委托给实例方法不能有 null 'this'。转换代表时

问题描述 投票:0回答:2

我正在尝试从通用委托转换为命名委托。

结果符合以下精神(无效的 C#):

Action<CustomClass> act = ???;
CustomDelegate d = act;

我已经尝试过了

CustomDelegate d = act.Invoke;
CustomDelegate d = new CustomDelegate( act );
CustomDelegate d = new CustomDelegate( x => act(x) );
CustomDelegate d = new CustomDelegate( act.Invoke );

所有这些都在运行时失败,给出

ArgumentException
并出现错误

委托给实例方法不能有 null 'this'。

堆栈顶部不是我的代码是:

在 System.MulticastDelegate.ThrowNullThisInDelegateToInstance()

在 System.MulticastDelegate.CtorClosed(对象目标,IntPtr methodPtr)

如何转换委托以免出现异常?

c# .net-3.5 delegates
2个回答
4
投票

我最终通过尝试 @DiegoMijelshon 针对选角代表问题的解决方案找到了答案。通过该解决方案,我得到了

NullReferenceException
而不是
ArgumentException
。因此我发现问题是因为我的 Action<> 为空(它是一个参数)。因此,如下所示的空检查解决了我的问题。

CustomDelegate d = adt == null ? null : act.Invoke;
// Though, I actually went with @DiegoMijelshon solution to avoid extra indirection.

然后我用 Reflector 进行了查看(我应该早点做),发现它确实是对参数进行空检查,导致

ThrowNullThisInDelegateToInstance
被调用。


0
投票

我在不同的环境中也遇到了同样的异常。

考虑以下代码:

public class Program
{
    public static void Main()
    {
        Demo.CallAction1(null); //instance is null!
    }
    
    public class Demo
    {
        public void DemoAction1() {}
        public void DemoAction2() {}
        
        public static void Execute(Action a) { a();}
        
        public static void CallAction1(Demo d)  { Execute(d.DemoAction1); }
    }
}

您将收到此错误:

Run-time exception (line 18): Delegate to an instance method cannot have null 'this'.

Stack Trace:

[System.ArgumentException: Delegate to an instance method cannot have null 'this'.]
   at System.MulticastDelegate.CtorClosed(Object target, IntPtr methodPtr)
   at Program.Demo.CallAction1(Demo d) :line 18
   at Program.Main() :line 8

参见:https://dotnetfiddle.net/lELV2s

© www.soinside.com 2019 - 2024. All rights reserved.