使用奇怪的重复模板模式时返回类型

时间:2011-11-14 12:56:22

标签: c# generics inheritance crtp

我在我的C#项目中使用curiously recurring template pattern(CRTP),但我遇到了一些问题。代码从上面的链接中删除:

public abstract class Base<T> where T : Base<T>{
    public T FluentMethod() {
        return (T)(this); 
    }
}

public class Derived : Base<Derived> {
}

美丽!当我尝试做这样的事情时,问题出现了:

public class SomeClass
{
    Base<T> GetItem() { /* Definition */ };
}

SomeClass应该能够返回Base类的任何实现,但是当然T在这里没有意义,因为这是在另一个类中。使用Derived而不是T编译,但这不是我想要的,因为我应该能够返回其他类型的项目,只要它们派生自Base。此外,GetItem()可能会返回不同类型的对象,具体取决于SomeClass对象的状态,因此使SomeClass泛型也不是解决方案。

我在这里遗漏了一些明显的东西,或者在使用CRTP时不能这样做吗?

2 个答案:

答案 0 :(得分:3)

您必须将该方法声明为通用:

using System;
public abstract class Base<T> where T : Base<T> {
    public T FluentMethod() {
        return (T)(this);
    }
}

public class Derived : Base<Derived> {
}

public class SomeClass {
    Base<T> GetItem<T>() where T : Base<T> {
        throw new NotImplementedException();
    }
}

要使其成为属性,您必须将类本身声明为通用:

public class SomeClass<T> where T : Base<T> {
    Base<T> GetItem {
        get { throw new NotImplementedException(); }
    }
}

答案 1 :(得分:0)

不要将公共方法设为通用,否则类型声明达到另一个级别。为“Derived GetDerivedItem()”

创建不同类型的工厂类
public class SomeClass {
    private Base<T> GetItem<T>() { /*implementation */ }

    public Derived GetDerivedItem() {
        return GetItem<Derived>();
    }
}