[英]Do Func and Action delegates become null if the source object becomes dereferenced?
Define these variables in Class A:在 A 类中定义这些变量:
public int CubeAnInt32(int n)
{
return n * n * n;
}
And these variables in Class B: B类中的这些变量:
public void CubeAnInt32WithDelegate(int k, Func<int, int> delg)
{
return delg(k);
}
And an overall scope:和一个整体范围:
/// Note that this is outside the scope of SomeArbitraryCallback()
Func<int, int> cube = default;
public void SomeArbitraryCallback()
{
var refWithinScope = new ClassA();
cube = refWithinScope.CubeAnInt32;
return;
}
public void AnotherCallbackPerformedAfter()
{
var cubeDependent = new ClassB();
/// Does this throw a NullReferenceException because of 'cube'?
/// Has the delegate assigned to 'cube' been dereferenced?
var result = cubeDependent.CubeAnInt32WithDelegate(0, cube);
return result;
}
Will a delegate whose object has been "de-scoped" (ie cube) be dereferenced?对象已“取消范围”(即多维数据集)的委托是否会被取消引用? Or will this delegate reference the assigned object and prevent it from being GC'd?或者这个委托会引用分配的对象并阻止它被 GC 处理?
As per https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/ - "A delegate is a type that represents references to methods" (emphasis is mine).根据https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/ - “委托是一种代表方法引用的类型”(重点是我的)。
So as long as your delegate ( cube
) remains in scope, a reference is held and refWithinScope
(of type ClassA
) will not be collected.因此,只要您的委托( cube
)仍在范围内,就会保留一个引用,并且不会收集refWithinScope
(类型为ClassA
)。
Whether you want to have this sort of design is a different discussion: looks like a good candidate for introducing subtle, unintended bugs in future re-factors.你是否想要这种设计是一个不同的讨论:看起来很适合在未来的重构中引入微妙的、意想不到的错误。
A delegate - concerning referencing null
- is in no way different from any other type.委托 - 关于引用null
- 与任何其他类型没有任何不同。 So if the variable is null
and you try to invoke it, you surely get a NullReferenceException
.因此,如果变量为null
并且您尝试调用它,您肯定会得到NullReferenceException
。
public event EventHandler<EventArgs> MyEvent;
private void RaiseEvent()
{
MyEvent.Invoke(this, myEventArgs);
}
So of course you need to assign somethig to your delegate, otherwise it's just null
.所以当然你需要为你的代表分配一些东西,否则它只是null
。
The same applies to a property.这同样适用于财产。 Unless you don't assignt any value to it, it will allways have its default-value, which is null
for reference-types:除非您不为其分配任何值,否则它将始终具有其默认值,对于引用类型为null
:
public string MyString { get; set; }
private void DoSomething()
{
Console.WriteLine(MyString.Length); // crash here
}
Coming back to your code, Func<int, int> cube = default;
回到你的代码, Func<int, int> cube = default;
will just assign null
to cube
.只会将null
分配给cube
。 So when you call CubeAnInt32WithDelegate
before having assigned something to the delegate, eg by calling SomeArbitraryCallback
, you will get an NRE.因此,当您在将某些内容分配给委托之前调用CubeAnInt32WithDelegate
时,例如通过调用SomeArbitraryCallback
,您将获得 NRE。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.