最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In C#, is it possible to get the owner object's properties from an anonymous function that is assigned outside? - Stack

programmeradmin5浏览0评论

Let's assume we have a class defined as:

class A
{
    public int Param { get; set; }
    public Action DoSomething { get; set; }
}

The DoSomething action is assigned in another class, but it needs to have access to param:

class B
{
    public B()
    {
        var a = new A()
        {
            Param = 100,
            DoSomething = () => Debug.Print( xxx ) // xxx here needs to refer to Param
        };
    }
}

Clearly, this.Param won't work because this is lexically bond to class B. How can I make DoSomething to access its owner class's other properties?

Let's assume we have a class defined as:

class A
{
    public int Param { get; set; }
    public Action DoSomething { get; set; }
}

The DoSomething action is assigned in another class, but it needs to have access to param:

class B
{
    public B()
    {
        var a = new A()
        {
            Param = 100,
            DoSomething = () => Debug.Print( xxx ) // xxx here needs to refer to Param
        };
    }
}

Clearly, this.Param won't work because this is lexically bond to class B. How can I make DoSomething to access its owner class's other properties?

Share Improve this question edited Feb 27 at 15:08 dbc 117k26 gold badges263 silver badges387 bronze badges asked Feb 27 at 15:02 JakeJake 1212 silver badges8 bronze badges 5
  • you can't, as there's nothing that forces this kind of relation between the delegate and the property. But why do you want that? You can of course use the property wherever you execute the delegate, can't you? – MakePeaceGreatAgain Commented Feb 27 at 15:04
  • 1 Do C# Object Initialiser - Reference to the new instance (answer: not possible) or Can properties inside an object initializer reference each other? (answer: no) answer your question also? – dbc Commented Feb 27 at 15:06
  • Bear in mind that there's nothing in general stopping the same Action from being referenced from multiple properties in multiple objects. There's no clear concept of "the" owner within the system. – Damien_The_Unbeliever Commented Feb 27 at 15:10
  • @MakePeaceGreatAgain, in JavaScript, this is dynamically bond at run time, so I'm curious on whether C# has similar language feature. – Jake Commented Feb 27 at 15:13
  • E.g. if you have a variable a of type A that you have assigned Param and DoSomething to, nothing stops me from writing var otherA = new A { Param = a.Param==0 ? 99 : 0, DoSomething = a.DoSomething };. There are now two "the owner"s of that DoSomething Action and they have different opinions on what Param is equal to. – Damien_The_Unbeliever Commented Feb 27 at 15:13
Add a comment  | 

3 Answers 3

Reset to default 3

This is specifically a limitation of object initializers. But you can do it outside of the initializer context:

class B
{
    public B()
    {
        var a = new A();
        a.Param = 100;
        a.DoSomething = () => Debug.Print(a.Param);
    }
}

Of course, now you have a closure, which is an additional object behind the scenes. Additionally, this requires DoSomething to be public, which means this can be changed later, while the object initializer would allow a property with an init option.

A simple solution is to take a parameter representing Param

class A
{
    public int Param { get; set; }
    public Action<int> DoSomething { private get; set; }
    void RunDoSomething() => DoSomething(Param);
}
...
var a = new A()
{
    Param = 100,
    DoSomething = param => Debug.Print( param ) 
};

Or you could use an Action<A> to essentially get an this reference.

You can use a.Param rather than using this.Param.

class B
{
    public B()
    {
        var a = new A()
        {
            Param = 100,
            DoSomething = () => Debug.Print(a.Param)
        };
    }
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论