并传递一个对象的方法,另一个目的保持第一对象活着? [英] does passing a method of one object to another object keep the first object alive?

查看:97
本文介绍了并传递一个对象的方法,另一个目的保持第一对象活着?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有三个对象:A,B和C。
对象'一'和'c'寿命长,静态引用服务单身。
对象'B'是短暂的,即没有静态引用保持它活着。



现在假设对象'一'创建对象'B'的一个实例在它的方法,如:

  b b =新型b一()的范围; 

进一步假设B类看起来是这样的:

 大众b()
{
C.ActionList.Add(的someMethod);
}

无效的someMethod()
{

}

现在,多久对象'b'生活?我的假设是,它生活超出了所谓它的构造方法的范围;具体而言,只要它的方法仍然是在对象的'C'的ActionList。



这是否正确?如果没有,它就会被当作垃圾收集,什么'C'时发生运行在其的ActionList的所有方法



奖金的问题:如果在'B的方法没有命名,但匿名的,写在构造函数如下:

 大众b()
{
C.ActionList.Add(()=> {

});
}


解决方案

具体而言,只要它的方法仍然是在对象'C'的'的ActionList。




是的,这是正确的。委托实例方法创造了一个硬引用,以实例本身,并会保持它活着。你的第二个问题是不相关的。



请注意,这就是为什么事件订阅是.NET内存泄漏的常见原因 - 他们不技术上泄漏,但是事件订阅基于代表,并且具有这种相同的行为,所以事件订阅保持对所述实例的引用。




如果该方法在b没有命名,但匿名的,并且在构造函数?




这是相同的写在一个lambda。如果拉姆达使用有问题的实例的状态,它会被变成了一个实例方法对类型由编译器的引用到该实例,并保持一个参考。 (请注意,有可能为一些lambda表达式将变成静态方法,如果他们不依赖于任何关闭了值,实例等,在这种情况下,它不会持有的参考。)



在你的情况,内容的 ... 将决定这一点。如果你的表达无非是:()=> {Console.WriteLine(富); } ,它不会需要关闭在任何值的实例,有问题也不会使用实例,所以它没有被引用。如果你这样做()=> {Console.WriteLine(this.Foo); } ,但是,它会创建一个引用类型的方法,以这个,并保持类的实例还活着。


Suppose I have three objects: 'a', 'b' and 'c'. Object 'a' and 'c' are long-lived, statically referenced service singletons. Object 'b' is short-lived, i.e. no static references keep it alive.

Now suppose object 'a' creates an instance of object 'b' in the scope of one of its methods, e.g.

B b = new B();

Further suppose that the class B looks something like this:

public B ()
{
    C.ActionList.Add ( SomeMethod );
}

void SomeMethod ()
{
...
}

Now, how long does object 'b' live? My presumption is that it lives beyond the scope of the method that called its constructor; specifically, for as long as its method is still in the 'ActionList' of object 'c'.

Is that correct? If not, and it gets garbage collected, what happens when 'c' runs all the methods in its 'ActionList'?

Bonus question: What if the method on 'b' is not named, but anonymous and written in the constructor as follows:

public B ()
{
    C.ActionList.Add ( () => {
    ...
    } );
}

解决方案

specifically, for as long as its method is still in the 'ActionList' of object 'c'.

Yes, that is correct. A delegate to an instance method creates a "hard reference" to the instance itself, and will keep it alive. Your second question is not relevant.

Note that this is why event subscriptions are a common source of "memory leaks" in .NET - they don't technically leak, but event subscriptions are based on delegates, and have this same behavior, so an event subscription holds a reference to the instance.

What if the method on 'b' is not named, but anonymous and written in a lambda in the constructor?

This is the same. If the lambda uses state of the instance in question, it will get turned into an instance method on a type with a reference to that instance by the compiler, and hold a reference. (Note that it's possible for some lambda expressions to be turned into static methods, if they don't rely on any closed over values, the instance, etc, in which case it would not hold a reference.)

In your case, the contents of the ... would determine this. If your expression was nothing but: () => { Console.WriteLine("Foo"); }, it wouldn't need to close over any values in the instance, and wouldn't use the instance in question, so it would not hold a reference. If you do () => { Console.WriteLine(this.Foo); }, however, it would create a method on a type with a reference to this, and keep the class instance alive.

这篇关于并传递一个对象的方法,另一个目的保持第一对象活着?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆