我有一个基类,其方法可以被覆盖。如果我从这个基类继承一个类,我怎么能让该方法返回继承的类型?
像:
public class ClassA : BaseClass
{
public override ClassA TestMethod(...)
{
// ...
}
}
我是否需要手动为基类提供类型?或者我可以自动提供该类型吗?
答案 0 :(得分:8)
您可以使用通用类型来执行此操作。
public class BaseClass<T> where T : BaseClass<T> {
public abstract T TestMethod(...);
}
public class ClassA : BaseClass<ClassA>
{
public override ClassA TestMethod(...)
{
// ...
}
}
你为什么需要它?可能会导致更好的答案......
答案 1 :(得分:7)
您想要的功能有一个名字;这是返回类型协方差。
C#不支持的原因如下:
Why C# doesn't allow inheritance of return type when implementing an Interface
其他答案都表明您使用C#版本的奇怪重复出现的模板模式来解决您的问题。我的观点是,这种模式比它解决的问题更多。有关详细信息,请参阅我关于该主题的文章:
http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx
解决此问题的更好方法是使用此模式:
abstract class Animal
{
protected abstract Animal ProtectedGetMother();
public Animal GetMother()
{
return this.ProtectedGetMother();
}
}
class Cat : Animal
{
protected override Animal ProtectedGetMother()
{
do the work particular to cats here
make sure you return a Cat
}
public new Cat GetMother()
{
return (Cat)this.ProtectedGetMother();
}
}
问题是您无法使用不同的返回类型覆盖虚拟方法。所以不要。使用不同的返回类型创建一个全新的方法,并使使虚拟方法成为类层次结构的实现细节。
这种技术比Cat : Animal<Cat>
“一只猫是猫的动物”胡说八道容易理解大约十亿倍。
答案 2 :(得分:2)
您可以通用方式执行此操作:
public abstract class Base
{
public abstract T AbstractTestMethod<T>() where T : Base;
public virtual T VirtualTestMethod<T>() where T : Base, new()
{
return new T();
}
}
public class ClassA : Base
{
public override ClassA AbstractTestMethod<ClassA>()
{
return new ClassA();
}
public override ClassA VirtualTestMethod<ClassA>()
{
return new ClassA();
}
}
使用虚方法的行为不如使用抽象方法那么严格。使用抽象方式可以强制开发人员自己实现该方法。使用虚拟方式,您可以告诉他们类似“满足我的约束并随意使用默认行为”。