在一些研究中,我使用我以前从未见过的泛型来尝试继承模式。
http://thwadi.blogspot.ca/2013/07/using-protobuff-net-with-inheritance.html
public abstract class BaseClass<TClass> where TClass : BaseClass<TClass>
{
//...
}
public class DerivedClass : BaseClass<DerivedClass>
{
//...
}
用法:
static void Main(string[] args)
{
DerivedClass derivedReference = new DerivedClass();
//this looks odd...
BaseClass<DerivedClass> baseReference = derivedReference;
//this doesn't work
//BaseClass baseClass = derivedReference;
}
我很惊讶这甚至有效,我必须自己测试一下。我仍然无法理解你为什么要这样做。
我唯一能想到的是阻止不同的派生类作为基类存储在集合中。这可能是原因,我想我只是对应用程序感到好奇。
答案 0 :(得分:4)
它被称为Curiously recurring template pattern,它通常用于允许类中的方法将派生类的类型用作传入或返回的参数。
例如,这是实现的Clone方法,因此只有每个层都需要在方法向下链时向方法添加它自己的属性。
public abstract class BaseClass<TClass> where TClass : BaseClass<TClass>, new()
{
public int Foo {get;set;}
public virtual TClass Clone()
{
var clone = new TClass();
clone.Foo = this.Foo;
return clone;
}
}
public class DerivedClass : BaseClass<DerivedClass>
{
public int Bar {get;set;}
public override DerivedClass Clone()
{
var clone = base.Clone();
clone.Bar = this.Bar;
return clone;
}
}
用法:
static void Main(string[] args)
{
DerivedClass derivedReference = new DerivedClass();
DerivedClass clone = derivedReference.Clone();
}
答案 1 :(得分:3)
作为使用示例,假设您要在基类型和派生类型上实现一些可链接的构建器方法,如下所示:
var d = new DerivedClass();
d.SetPropertyA("some value").SetPropertyB(1);
虽然SetPropertyA
属于基类,SetPropertyB
属于派生类。
通过实现如下所示的类,在链接方法时,在调用SetPropertyA
之后,因为返回值的类型为DerivedClass
,您可以调用SetPropertyB
:
public abstract class BaseClass<TClass> where TClass : BaseClass<TClass>
{
public string A {get ; set; }
public TClass SetPropertyA(string value)
{
this.A=value;
return this as TClass;
}
}
public class DerivedClass : BaseClass<DerivedClass>
{
public int B {get ; set; }
public DerivedClass SetPropertyB(int value)
{
this.B=value;
return this;
}
}
然后,如果你有一些其他的派生类,每个派生类都可以使用基础SetPropertyA
知道返回值是它自己的类型。