C# 使用泛型类型时,如何从继承类而不是基类调用方法?
我有一个实现DependsOn()的基类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()
{
返回新列表();
}
}
我扩展了这个基类
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;
}