C# 这个==null怎么可能?

C# 这个==null怎么可能?,c#,.net,events,null,C#,.net,Events,Null,编辑:这不是重复,因为这是一个使用Delegate.CreateDelegate的实际示例,另一个是关于IL的理论讨论。除了“this”和“null”这两个词之外,彼此之间没有任何关系 相对于这个 我遇到过这样一种情况:对null实例调用事件处理程序。奇怪的请看图片: 我不明白发生了什么事。如何在空实例上调用实例方法???您可以使用重载创建这种情况,在重载中为调用目标提供null引用 class Foo { public void Method() { Con

编辑:这不是重复,因为这是一个使用Delegate.CreateDelegate的实际示例,另一个是关于IL的理论讨论。除了“this”和“null”这两个词之外,彼此之间没有任何关系

相对于这个

我遇到过这样一种情况:对null实例调用事件处理程序。奇怪的请看图片:


我不明白发生了什么事。如何在空实例上调用实例方法???

您可以使用重载创建这种情况,在重载中为调用目标提供
null
引用

class Foo
{
    public void Method() 
    {
        Console.WriteLine(this == null);
    }
}

Action<Foo> action = (Action<Foo>)Delegate.CreateDelegate(
    typeof(Action<Foo>), 
    null, 
    typeof(Foo).GetMethod("Method"));

action(null); //prints True
class-Foo
{
公开作废法()
{
Console.WriteLine(this==null);
}
}
Action Action=(Action)Delegate.CreateDelegate(
类型(动作),
无效的
typeof(Foo.GetMethod(“Method”);
动作(空)//打印正确

从该页上的MSDN备注中:

如果firstArgument是空引用,而method是实例方法, 结果取决于委托类型和类型的签名 方法:

•如果类型的签名明确包含隐藏的第一个 方法的参数,则该委托被称为表示打开的 实例方法。调用委托时,中的第一个参数 参数列表将传递给的隐藏实例参数 方法

•如果方法和类型的签名匹配(即所有参数 类型是兼容的),则称委托在 空引用。调用委托就像调用实例一样 方法,这对于 可以。


所以它被记录为一种已知的、可能是有意的行为。

因为它已经被垃圾收集了?您可能忘记在使用后取消注册事件处理程序。@Marcel:据我所知,如果事件处理程序已注册,则无法对其进行垃圾收集,因为存在对该对象的引用。@MichaelPerrenoud:没有dup,我已经检查过了。这是一个实际问题,而另一个只是关于理论IL的讨论。这里可能不是这样,但请注意,实际上是创建一个委托来调用一个实例方法,其中
This
null
@ChrisSinclair:你完全正确。你能把你的答案贴出来吗?我会接受的。我正在使用代码创建一个泛型委托,目标被设置为null。上帝保佑你;)绝对好,这是我用别人的代码做的。。。奇怪,我认为这是允许的,这很奇怪。在这种情况下,
Delegate.CreateDelegate
会引发异常。我想不出有哪一个用例需要在没有实例的情况下调用实例方法……是否可以将“this”设置为其他对象?然后它将类似于JavaScript绑定/调用/应用方法。@DanielHilgarth,from
调用委托就像在null实例上调用实例方法,这不是一件特别有用的事情。
因此,我相信null只允许用于静态方法。是的,确实很可怕。我怀疑CLR并不一定关心是否有一个实例可用于执行一个方法。在这种情况下,重载还处理静态方法。我想除了检查目标是否为空之外,它还可以检查
MethodInfo.IsStatic
属性,但我想微软开发人员觉得这不值得(或者有其他影响)?