有几个帖子已经关于这样的事情栈溢出,但不完全一样 - 所以道歉提前如果这是一些已经回答了

为什么这个不行:

public class MyBase { }

public class MyUtils
{
    public bool Foo<T> (T myObject) { return true; }
    public bool Foo (MyBase myBaseObject) { return false; }

    public void Go<T> (IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            // this test fails
            Assert.IsFalse (Foo (item));
        }
    }
}

如果我请上述围棋(),并通过在MyBase对象的负荷,每次调用富将调用通用的Foo(),它返回真。

new MyUtils ().Go (new MyBase[] { new MyBase (), new MyBase () });      

为什么它不叫专业MyBase的版本呢?如果我调用foo(新MyBase())直接,它正确地推断进行的呼叫。这是因为在C#3,还是我只是被愚蠢和不正确地这样做呢?

缺乏协方差收藏

谢谢!

艾萨克

有帮助吗?

解决方案

它不调用“专门”之一,因为编译器的动产当程序(在此情况下,是Go功能)是调用该方法的编译的时,它的运行。

当编译器编译Go功能,它具有唯一的信息是,有式T的一些对象。它没有,你可能会在某个时间点与类型MyBase的对象提供任何的想法。它具有唯一的选择是选择Foo<T>过载,因此它烘烤是,在以已编译的程序。

如果你想要一个应用程序来选择在运行时过载,并通过观察,同时应用程序运行的对象选择最佳的过载,这就是所谓的“动态调度”,且仅由动态语言如Ruby使用, Python和PHP等

C#3是完全静态的,并且不支持这一点。你必须在你的代码来检查的类型,如果你想它的工作这样写if语句。 另一方面,C#4,具有一定的动态支持。如果你正在写在C#4这个代码,你可以声明如下“转到”功能:

 public void Go<T> (IEnumerable<dynamic> items)

然后,将使用动态调度在运行时选择哪个过载被调用,并且将调用专业采取MyBase过载

其他提示

据C#规范(7.4.3.2),非通用方法比普通的一个更好的,所以它应选择。

不过,我觉得一般一个在你的情况下回升,因为它是一个通用的调用上下文(以下简称“foreach”循环)。

中调用
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top