C# 奇数遗传模式

C# 奇数遗传模式,c#,generics,inheritance,C#,Generics,Inheritance,在一些研究中,我遇到了一个使用我以前从未见过的泛型的继承模式 公共抽象类基类,其中TClass:BaseClass { //... } 公共类派生类:基类 { //... } 用法: static void Main(string[] args) { DerivedClass derivedReference = new DerivedClass(); //this looks odd... BaseClass<DerivedClass> baseRef

在一些研究中,我遇到了一个使用我以前从未见过的泛型的继承模式

公共抽象类基类,其中TClass:BaseClass
{
//...
}
公共类派生类:基类
{
//...
}
用法:

static void Main(string[] args)
{
    DerivedClass derivedReference = new DerivedClass();

    //this looks odd...
    BaseClass<DerivedClass> baseReference = derivedReference;

    //this doesn't work
    //BaseClass baseClass = derivedReference;

}
static void Main(string[] args)
{
    DerivedClass derivedReference = new DerivedClass();

    DerivedClass clone = derivedReference.Clone();    
}
static void Main(字符串[]args)
{
DerivedClass derivedReference=新的DerivedClass();
//这看起来很奇怪。。。
基类baseReference=derivedReference;
//这不管用
//基类基类=派生引用;
}
我很惊讶这居然奏效,我不得不自己测试。我还是不明白你为什么要这么做

我唯一能想到的就是防止不同的派生类作为它们的基类一起存储在一个集合中。这可能就是原因,我想我只是对应用程序好奇。

它被称为It,它通常用于允许类中的方法将派生类的类型用作传入或返回的参数

例如,这是一个克隆方法,因此只有每一层需要在方法链中添加自己的属性

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;
    }
}

作为使用示例,假设您希望在基类型和派生类型上实现一些可链接的生成器方法,如下所示:

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;
    }
}
公共抽象类基类,其中TClass:BaseClass
{
公共字符串A{get;set;}
公共TClass SetPropertyA(字符串值)
{
这个.A=值;
将其作为TClass返回;
}
}
公共类派生类:基类
{
公共int B{get;set;}
公共派生类SetPropertyB(int值)
{
这个.B=值;
归还这个;
}
}

如果你有其他的派生类,它们中的每一个都可以使用基类
SetPropertyA
,因为返回值属于它自己的类型。

一个很好的使用示例是当您希望在基类和派生类中有可链接的方法调用时。要使上一个示例起作用,您需要第三个非泛型类
公共抽象类基类{}
然后泛型类将需要更改为
公共抽象类BaseClass:BaseClass,其中TClass:BaseClass
。有一个编辑提示ColonInternal是一个打字错误。@BillWoodger只是好奇为什么它作为编辑无效?(我以前从未尝试过)@LukeCummings我们还不知道它是否有效。我投票反对。我的看法是,如果海报在网站上仍然“活跃”,请留下评论。如果它们早已消失,请尝试编辑,但要注意更改实际代码可能很棘手。让你的编辑评论真的很好。@lukecommings这完全是主观的。我投票赞成这一编辑,因为它显然是一个打字错误,与作者的答案没有任何冲突。比尔说得很好,但在这种情况下(这么小的变化),我认为自己编辑是可以的。@lukecommings你的编辑很好,我批准了。我最初有两个方法,Clone()和CloneInternal(),但后来决定简化示例,但忘记重命名其中一个调用。
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;
    }
}