-1

考虑类

class FirstClass 
{
    //Some fields, ctors and methods
    ...
    public event Action Test
    {
        add
        {
            var method = value.Method;
            var parameters = method.GetParameters (); //Count == 1
            // (1)
            //I don't know anything about value so I think I can pass null as argument list because it's Action, not Action<T>
            //And we get Reflection.TargetParameterCountException here.
            method.Invoke (value.Target, null); 
            //Instead of calling Invoke as done above, we should call it like that:
            // (2)
            method.Invoke (value.Target, new object[] { null });
            //But since it's Action, we should be able to call it with (1) not with (2)
        }
        remove
        {
            ...
        }
    }
}

还有一个班级

class SecondClass
{
    public void TestMethod (Action action = null)
    {
        ...
    }
    public void OtherMethod ()
    {
        var a = new FirstClass ();
        a.Test += TestMethod;
    }
}

恕我直言:在类型系统级别不应允许将具有默认参数的方法添加到没有参数的委托。为什么允许?

PS您不仅可以在 add { } 访问器中执行此操作,还可以在任何其他地方执行此操作,上面的代码只是示例。

4

1 回答 1

0

这不应该编译。

委托动作有一个零参数的标志,并且没有返回值:

public delegate void Action();

因此,只能为它分配零参数而不是返回值的方法。您的第二堂课SecondClass.TestMethod确实有一个类型的参数Action(我猜是为了让这一切变得混乱;))。因此该方法将与另一个 Action 委托兼容(其中 T = Action):

public delegate void Action<T>();

如果您甚至尝试设法调用 FirstClass.Test.Add,并且您尝试进行两次 Invoke 调用,那么第一个应该会失败。

为什么?该方法是一个MethodInfoSecondClass.TestMethod此方法至少需要一个参数。此参数必须在提供给调用方法的对象数组内。但是,在您的第一次通话中,您没有对象数组;您的对象数组设置为空。并且设置为 null 的对象数组不能容纳任何东西,甚至不能容纳 0 个元素,更不用说 1 个具有 null 的元素了。

第二个 Invoke 确实有一个带有一个元素的对象数组,具有空值。

于 2013-05-02T16:10:49.160 回答