我在我的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时不能这样做吗?
答案 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>();
}
}