[英]Inheritance on a constrained generic type parameter
我知道不可能從泛型類型參數繼承,但是在為抽象類型的派生實現通用代理時會很方便的:-)
有人知道為什么這不可能嗎?
示例C#:
abstract class Foo
{
public virtual void Bar()
{
// nop
}
}
class FooProxy<TFoo> : TFoo
where TFoo : Foo
{
public override void Bar()
{
// do some stuff before
base.Bar();
// do some stuff after
}
}
編輯:更多代碼來說明如何使用此示例。 考慮以下Foo的派生詞:
class FooX : Foo
{
public string X { get; set; }
public override void Bar()
{
Console.WriteLine("Doing Bar X");
}
}
class FooY : Foo
{
public string Y { get; set; }
public override void Bar()
{
Console.WriteLine("Doing Bar Y");
}
}
和調用代碼:
FooProxy<FooX> fooXProxy = new FooProxy<FooX>();
fooXProxy.X = "test X";
fooXProxy.Bar();
FooProxy<FooY> fooYProxy = new FooProxy<FooY>();
fooYProxy.Y = "test Y";
fooYProxy.Bar();
使用FooX和FooY時,將重用Bar()方法的FooProxy重寫中的代碼。
編輯:根據Pete OHanlon的答案進行了修改:使Bar()方法成為虛擬的。
因為你不能。 泛型不是模板。 您不應該像C ++模板那樣考慮它們,並且期望它們具有相同的行為。 它們是根本不同的概念。
C#規范明確禁止將類型參數用作基類:
C#3.0語言規范:類型參數(第4.5節)
類型參數不能直接用於聲明基類(第10.2.4節)或接口(第13.1.3節)。
我了解您想要做什么及其用途。 這是C ++模板的傳統用例。 具體來說,如果可以使用C#泛型來實現,那么Moq
庫之類的東西就可以從中受益。 問題是,C ++模板是編譯時的“查找和替換”結構,而C#泛型是運行時的東西。
為了證明這一事實,對於本課程:
class Test<T> where T : class {
// whatever contents it might have...
}
僅單個IL將在編譯時被發射,並在運行時間,JIT編譯器將生成所有引用類型的類型參數的單個本地代碼。 這根本不像C ++模板,后者將為每個T
分別發出本機代碼(這是經過優化的,但從概念上講,它們是完全獨立的代碼段)。
您不能從泛型類型參數繼承,因為類型在編譯時是未知的,因此編譯器無法弄清楚超類是什么。 我意識到,乍一看,編譯器可以弄清楚<T>是什么,這似乎表明它應該能夠弄清楚T是什么,但是兩者是不同的。
另外,您在Bar中遇到邏輯問題。 您不能調用base.Bar,因為這是抽象類型。 為了糾正此問題,您必須將Foo中的實現更改為
public virtual void Bar() {}
因為Foo是抽象類型。
如果您在類中實現了Foo,然后在模板中使用了Foo,則可以這樣做。
您也可以使用界面來執行您認為要執行的操作。
編輯:
仔細考慮一下您的代碼,這沒有任何意義。 您將需要創建GENERIC類型的基類,然后從該基類派生出來以實現您想要的工作。 這也將使地獄更加有意義...
abstract class Foo<T>
{
public virtual void Bar();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.