简体   繁体   English

如果源对象被取消引用,Func 和 Action 委托会变为 null 吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM