1

我在我的 C# 项目中使用了奇怪的重复模板模式(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 时不能这样做?

4

2 回答 2

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(); }
    }
}
于 2011-11-14T13:03:55.960 回答
0

不要将公共方法作为泛型,否则类型声明会达到另一个层次。为不同类型创建一个工厂类,例如“Derived GetDerivedItem()”

public class SomeClass {
    private Base<T> GetItem<T>() { /*implementation */ }

    public Derived GetDerivedItem() {
        return GetItem<Derived>();
    }
}
于 2011-11-14T13:13:36.507 回答