为什么不能在简单的赋值中使用两个相同形状的委托类型?

时间:2014-01-16 10:55:21

标签: .net casting delegates

我知道如何为彼此分配两个相同形状的委托类型(使用分配者委托的ctor)。但是我想知道为什么一个代表不能在没有任何额外努力的情况下分配给另一个代理。(我的意思是del1 = del2)。它背后有什么.net逻辑? 请考虑以下代码:

delegate void T1(int a, int b);
delegate void T2(int a, int b);
...
T1 t1 = (x,y) => x = 1;
T2 t2 = T2(t1); //Issues Error!


delegate void T1<in T>(T obj);
delegate void T2<in T>(T obj);
...
T1<int> t1 = (x) => x = 1;
T2<int> t2 = t1;//Issues Error!

2 个答案:

答案 0 :(得分:0)

如果委托类型相同,则可以分配它们。这是小提琴 - http://dotnetfiddle.net/18Il3h

using System;

public class Program
{
    public void Main()
    {
        Action action = Handler1;
        Action action2 = Handler2;

        action = action2;
        action();
    }

    public void Handler1()
    {
        Console.WriteLine("handler1");
    }

    public void Handler2()
    {
        Console.WriteLine("handler2");
    }

}

它编译并正常工作。将显示“handler2”。

<强> UPDATE1

您仍然可以根据T1创建T2类型。您不能直接从T1转换为T2,因为它们是不同的类型,即使具有相同的签名,但您仍然可以基于T1创建T2的实例。这是工作小提琴 - http://dotnetfiddle.net/P0mvR6

using System;

public class Program
{
    delegate void T1(int a, int b);
    delegate void T2(int a, int b);

    public void Main()
    {
        int counter = 0;

        T1 t1 = (x,y) => {
            Console.WriteLine(counter++);
        };
        T2 t2 = new T2(t1); // here you need to create T2, and not to cast it from T1

        t1(1,1); // parameters are not used
        t2(1,1); // parameters are not used
    }
}

答案 1 :(得分:0)

您收到的错误(至少我这样做)并不是在这种情况下不能进行类型转换,而是T2在此上下文中不可用。这是因为T2是一种类型,你不能像函数一样调用类型。要将一种类型转换为另一种类型,您必须将其转换为:

T2 t2 = (T2) t1;

但是这会因错误而失败,无法进行转换。这是为什么?因为两种类型仍然不同。即使两种类型的定义相同,它们仍然是不同且不兼容的类型,因此您不能将其中一种分配给另一种。

然而,代表们有点特别。您可以将兼容的函数转换为类型化的委托。这实际上发生在很多情况下,最重要的是在添加事件处理程序时,但通常隐藏着语法糖。例如,obj.SomeEvent += HandleSomeEvent实际上是obj.SomeEvent += new SomeEventHandler(HandleSomeEvent);这就是你需要的线索:创建新的委托实例时,可以将兼容的函数传递给构造函数,并创建一个具有该函数的新委托:

T1 t1 = (x, y) => x = 1;
T2 t2 = new T2(t1);