8

我的问题有点类似于这个:如何将动作转换为具有相同签名的已定义委托?

为什么具有相同签名的委托之间没有隐式转换。例如,代码:

class Program
{
    private delegate void Foo1(int x);
    private delegate void Foo2(int x);


    static void Main(string[] args)
    {
        Foo1 foo1 = Console.WriteLine;
        Foo2 foo2 = Console.WriteLine;

        Call(foo1);

        Call2(foo2);
    }

    static void Call(Action<int> action)
    {
        action(10);
    }

    static void Call2(Foo1 action)
    {
        action(10);
    }
}

它不能编译,因为there isn't implicit convertion from Action<int> to Foo1. 但通常它是一样的。所以这意味着这些名称是别名,而不是实际名称。所以我认为把它当作别名来考虑是个好主意。所以在这种情况下,我们有 a 的 3 个别名delegate, that get one int value and returns nothing。并且这些代表可以完全互换。但我们没有。所以问题是:为什么?通过签名它是同一件事,并且没有任何实现,因此具有相同签名的委托是一个并且具有许多别名的相同......

是 C# 缺陷还是有原因?至于我,我什么都看不到。

4

1 回答 1

3

这两个委托之间没有隐式转换,原因与这两种类型之间没有隐式转换相同:

public sealed class Foo1
{
    public string Value { get; set; }
}

public sealed class Foo2
{
    public string Value { get; set; }
}

仅仅因为两个类具有相同的字段并不意味着您应该能够将一个类视为另一个类。相同的逻辑适用于委托(请注意,委托也是类型)。

有应用于创建该类型的语义含义。如果有人创建了 aFoo1他们希望它是 a Foo1,而不是Foo2. 如果他们不遗余力地使用预期 a 的Foo1地方Foo2,这是一个很大的危险信号,即使类型看起来相似,这两种类型之间也存在语义差异。如果程序员知道编译器不知道的东西,他们可以使用某种显式转换来表明他们知道自己在做什么。

(上一段是故意写成同样适用于你的代表,以及我上面提供的课程。)

于 2013-08-22T21:03:43.893 回答