我正在尝试从通用委托转换为命名委托。
结果符合以下精神(无效的 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)
如何转换委托以免出现异常?
我最终通过尝试 @DiegoMijelshon 针对选角代表问题的解决方案找到了答案。通过该解决方案,我得到了
NullReferenceException
而不是 ArgumentException
。因此我发现问题是因为我的 Action<> 为空(它是一个参数)。因此,如下所示的空检查解决了我的问题。
CustomDelegate d = adt == null ? null : act.Invoke;
// Though, I actually went with @DiegoMijelshon solution to avoid extra indirection.
然后我用 Reflector 进行了查看(我应该早点做),发现它确实是对参数进行空检查,导致
ThrowNullThisInDelegateToInstance
被调用。
我在不同的环境中也遇到了同样的异常。
考虑以下代码:
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