这是我以前从未注意到的,但最近遇到了.当我遇到这种情况时,我很惊讶编译器认为是正确的,以及它迫使我做什么.我认为通过示例最容易描述.
假设我们有一个带有单个方法的泛型基类.
abstract class GenericBase<T>
{
public abstract T SomeMethod<T>(T value);
}
Run Code Online (Sandbox Code Playgroud)
这里没什么好疯狂的.现在,让我们扩展它,提供一个具体的实现int:
class IntImplementation : GenericBase<int> // T is now, and forever shall be, int
{
public override int SomeMethod(int value)
{
return ++value;
}
}
Run Code Online (Sandbox Code Playgroud)
看起来很简单吧?或者,所以我想......事实上,你不能这样做.编译器会抛出消息
'IntImplementation'不实现继承的抽象成员'GenericBase.SomeMethod(T)'
但是...... T现在是一个int!为什么我不能在我的覆盖中替换它?事实证明唯一可接受的覆盖是
public override T SomeMethod<T>(T value)
Run Code Online (Sandbox Code Playgroud)
这意味着我的方法现在必须
public override T SomeMethod<T>(T value)
{
return ++((int)value);
}
Run Code Online (Sandbox Code Playgroud)
哇,这根本不是通用的.事实上,我不妨从基类中抛弃泛型,并与良好的ol'一起去object!
心神.吹.我一直在为这可能背后的原因感到疑惑,但我很茫然.有人有什么想法吗?
Eri*_*ert 23
将T在通用方法毫无关系与T包含类,你应该得到一个警告信息,告诉你也正在于此.请阅读编译器警告; 他们在那里为你的利益.
如果你打算SomeMethod成为通用的那么你应该写:
abstract class GenericBase<T>
{
public abstract U SomeMethod<U>(U value);
}
Run Code Online (Sandbox Code Playgroud)
现在显然GenericBase<int>根本没有影响SomeMethod<U>.
或者,如果你的意图SomeMethod根本没有被泛化,那么不要将它泛化:
abstract class GenericBase<T>
{
public abstract T SomeMethod(T value);
}
Run Code Online (Sandbox Code Playgroud)
现在你可以SomeMethod按照你的描述进行覆盖.