通用方法问题/错误?

Luc*_*zzi 5 c# generics

有人能解释一下这个问题吗?

让这个工作的唯一方法是使用CorrectName中的虚拟,然后在Derived中覆盖,而不是new关键字,但是,为什么会发生这种情况?

为什么如果我通过泛型投射它给我Base值,如果我直接投射它给我Derived值?((输出如下))

谢谢你们,正如我所说的,我已经得到了"解决方案",但我想理解

    class Base
    {
        public string Name { get; set; }
        public string CorrectName { get { return Name; } }
    }
    class Derived : Base
    {
        public new string CorrectName { get { return "NEW" + Name; } }
    }
    static void Main(string[] args)
    {
        List<Derived> container = new List<Derived>();

        var d = new Derived() { Name = "NameDerived2" };

        container.Add(d);

        Search<Derived>(container);
        Console.ReadLine();
    }

    static void Search<T>(List<T> list) where T : Base
    {
        foreach (var el in list)
        {
            Console.WriteLine("No Cast -->" + el.CorrectName);
            Console.WriteLine("Generic Cast -->" + (el as T).CorrectName);
            Console.WriteLine("Direct Cast -->" + (el as Derived).CorrectName);
        }
    }
Run Code Online (Sandbox Code Playgroud)

OUTPUT:

No Cast -->NameDerived2

Generic Cast -->NameDerived2

Direct Cast -->NEWNameDerived2
Run Code Online (Sandbox Code Playgroud)

真相表:

el is Derived == true
el.GetType().Equals(typeof(Derived)) == true
el.GetType().Equals(typeof(T)) == true
el.GetType().Equals(typeof(Base)) == false
typeof(T).Equals(typeof(Base)) == false
typeof(T).Equals(typeof(Derived)) == true
Run Code Online (Sandbox Code Playgroud)

Tho*_*mar 4

如果没有virtual关键字,基类中的方法不会被覆盖,而是被新实现“隐藏”。您还可以通过使用new中的关键字来强制执行此操作Derived。正如您在通用方法声明中所说,T传递给该方法的任何内容都必须是 type Base,因此 every 都T被强制转换为Base

现在发生的情况是,当你不使用 时virtual,你就会失去多态性,这意味着,即使对象实际上是类型Derived,但转换为Base,调用Base的实现CorrectName,而不是 - 正如你所期望的 - 中的新实现Derived

仅当您将对象显式转换为Derived.

这也在这里进行了讨论和描述:virtual keywords in c#

另一个可以帮助您了解虚拟方法和非虚拟方法之间区别的链接可能是: http: //en.wikipedia.org/wiki/Virtual_method_table

  • @ThorstenDittmar 然而“typeof(T)”和“el.GetType()”都说“Derived”。我认为更正确的说法是该方法根据约束来处理泛型类型,而不是动态地将行为更改为传入的类型。 (2认同)