C# 使用泛型类型时,如何从继承类而不是基类调用方法?

C# 使用泛型类型时,如何从继承类而不是基类调用方法?,c#,inheritance,generic-type-argument,C#,Inheritance,Generic Type Argument,我有一个实现DependsOn()的基类 公共类实体 { 受保护实体(){} 公共虚拟列表DependsOn() { 返回新列表(); } } 我扩展了这个基类 public class Waveform : Entity { public virtual new List<Type> DependsOn() { return new List<Type> {typeof(Scenario)}; } } 公共类波形:实体 { 公

我有一个实现DependsOn()的基类

公共类实体
{
受保护实体(){}
公共虚拟列表DependsOn()
{
返回新列表();
}
}
我扩展了这个基类

public class Waveform : Entity
{
    public virtual new List<Type> DependsOn()
    {
        return new List<Type> {typeof(Scenario)};
    }
}
公共类波形:实体
{
公共虚拟新列表DependsOn()
{
返回新列表{typeof(Scenario)};
}
}
我希望下面的代码返回“new List{typeof(Scenario)}”,而不是返回一个空列表(它从基类而不是继承的类调用DependsOn方法。我也用调试器验证了这一点)

公共虚拟列表FindParents(T possibleChild),其中T:Entity
{
List dependsOnTypes=possibleChild.DependsOn();
}
公共无效删除实体(T实体),其中T:实体
{
列表父项=FindParents(实体);
}
波形=新波形();
删除实体(波形);

使用
覆盖
而不是
虚拟新建

virtual new
创建一个新插槽,并定义一个新函数,该函数本身就是
virtual
,但不与其基类共享vtable插槽

public class Waveform : Entity
{
    public virtual new List<Type> DependsOn()
    {
        return new List<Type> {typeof(Scenario)};
    }
}

每次在函数上使用
new
关键字时,都应将其视为与基类中具有相同名称的函数无关
new
允许您完全更改函数的签名,例如。

您没有真正扩展基类,而是创建了一个同名的新方法。使用
覆盖
关键字,如下所示:

public class Waveform : Entity
{
    public override List<Type> DependsOn()
    {
        return new List<Type> {typeof(Scenario)};
    }
}
公共类波形:实体
{
公共覆盖列表DependsOn()
{
返回新列表{typeof(Scenario)};
}
}

为什么在这种情况下需要重写而不是新的,是从运行时包含子类的基类对象调用该方法。实际传递的元素的类型为Entity type,在运行时用波形填充,但在运行时,Entity对象不知道任何重写,因为子类实现隐藏基类实现

在原始格式中,调用您想要的正确方法的唯一方法是使用波形对象,而不是实体,然后它将调用正确的版本,如下所示:

 class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Waveform waveform = new Waveform();
            p.DeleteEntity<Waveform>(waveform);
        }

        public void DeleteEntity<T>(T entity) where T : Waveform
        {
            List<Entity> parents = FindParents<T>(entity);
        }

        public virtual List<Entity> FindParents<T>(T possibleChild) where T : Waveform
        {
            List<Entity> dependsOnTypes = possibleChild.DependsOn();
            return dependsOnTypes;
        }        
    }

    public class Entity
    {
        protected Entity() { }

        public virtual List<Entity> DependsOn()
        {
            return new List<Entity>();
        }
    }

    public class Waveform : Entity
    {
        public virtual new List<Entity> DependsOn()
        {
            return new List<Entity> { new Scenario() };           
        }
    }

    public class Scenario: Entity
    {
        int x;
        float y;
    }
类程序
{
静态void Main(字符串[]参数)
{
程序p=新程序();
波形=新波形();
p、 删除实体(波形);
}
公共void DeleteEntity(T实体),其中T:波形
{
列表父项=FindParents(实体);
}
公共虚拟列表FindParents(T possibleChild),其中T:Waveform
{
List dependsOnTypes=possibleChild.DependsOn();
返回dependsOnTypes;
}        
}
公共类实体
{
受保护实体(){}
公共虚拟列表DependsOn()
{
返回新列表();
}
}
公共类波形:实体
{
公共虚拟新列表DependsOn()
{
返回新列表{new Scenario()};
}
}
公共类场景:实体
{
int x;
浮动y;
}

出于某种原因,它没有真正单击,直到您说“认为它与基类中具有相同名称的函数无关”。
 class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Waveform waveform = new Waveform();
            p.DeleteEntity<Waveform>(waveform);
        }

        public void DeleteEntity<T>(T entity) where T : Waveform
        {
            List<Entity> parents = FindParents<T>(entity);
        }

        public virtual List<Entity> FindParents<T>(T possibleChild) where T : Waveform
        {
            List<Entity> dependsOnTypes = possibleChild.DependsOn();
            return dependsOnTypes;
        }        
    }

    public class Entity
    {
        protected Entity() { }

        public virtual List<Entity> DependsOn()
        {
            return new List<Entity>();
        }
    }

    public class Waveform : Entity
    {
        public virtual new List<Entity> DependsOn()
        {
            return new List<Entity> { new Scenario() };           
        }
    }

    public class Scenario: Entity
    {
        int x;
        float y;
    }