[英]When using generic types, how can I call an method from an inherited class instead of a base class?
我有一個實現DependsOn()的基類
public class Entity
{
protected Entity() { }
public virtual List<Type> DependsOn()
{
return new List<Type>();
}
}
我已經擴展了這個基類。
public class Waveform : Entity
{
public virtual new List<Type> DependsOn()
{
return new List<Type> {typeof(Scenario)};
}
}
我希望以下代碼返回“新列表{typeof(Scenario)}”,而不是返回一個空列表(它從基類而不是繼承的類調用DependsOn方法。我也通過調試器進行了驗證)
public virtual List<Entity> FindParents<T>(T possibleChild) where T : Entity
{
List<Type> dependsOnTypes = possibleChild.DependsOn();
}
public void DeleteEntity<T>(T entity) where T : Entity
{
List<Entity> parents = FindParents<T>(entity);
}
Waveform waveform = new Waveform();
DeleteEntity<Waveform>(waveform);
使用override
而不是virtual new
。
virtual new
創建一個新插槽,並定義一個新的函數,該函數本身是virtual
但不與其基類共享vtable插槽。
每次在函數上使用new
關鍵字時,都應認為它與基類中具有相同名稱的函數無關。 new
允許您例如完全更改函數的簽名。
您尚未真正擴展基類,而是創建了一個具有相同名稱的新方法。 使用override
關鍵字,如下所示:
public class Waveform : Entity
{
public override List<Type> DependsOn()
{
return new List<Type> {typeof(Scenario)};
}
}
在這種情況下,為什么需要覆蓋而不是新方法,是在運行時從包含子類的基類對象調用該方法的。 實際傳遞的元素是實體類型,在運行時會被波形填充,但是在運行時,實體對象不知道任何替代,因為子類實現隱藏了基類實現。
在原始格式下,調用所需的正確方法的唯一方法是使用Waveform對象(而不是實體),然后將調用正確的版本,如下所示:
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.