C# 具有附加泛型类型的奇怪重复出现的模板模式

C# 具有附加泛型类型的奇怪重复出现的模板模式,c#,generics,crtp,C#,Generics,Crtp,假设我想要一个泛型的Box类,它可以包含一些内容,所以它是一个BoxBox有一个Transform方法,该方法返回一个Box: 现在,我从Box继承的每个类都应该引用它自己,否则所有的地狱都会崩溃: public class FooBox<T> : Box<FooBox, T> 未能使用编译类型“B”不能用作泛型类型或方法“Test.Box”中的类型参数“B”。没有从“B”到“Test.Box”的隐式引用转换。(CS0311)。这是有道理的,因为返回类型现在是Box,B

假设我想要一个泛型的
Box
类,它可以包含一些内容,所以它是一个
Box
Box
有一个
Transform
方法,该方法返回一个
Box

现在,我从
Box
继承的每个类都应该引用它自己,否则所有的地狱都会崩溃:

public class FooBox<T> : Box<FooBox, T>
未能使用
编译类型“B”不能用作泛型类型或方法“Test.Box”中的类型参数“B”。没有从“B”到“Test.Box”的隐式引用转换。(CS0311)
。这是有道理的,因为返回类型现在是
Box
,B是
Box
,而不是
Box

简单的解决方案不起作用:

public abstract Box<B, U> Transform<U>(Func<T, U> transform) where B : Box<B, U>;
公共抽象框变换(Func变换),其中B:Box;
无法使用
“Test.Box.Transform()”未定义类型参数“B”(CS0699)
进行编译


有没有办法解决这个问题,或者我真的把自己逼到了墙角?

我认为直接修复的问题是重用
B
类型参数。尝试其他操作,并将其作为类型参数包含:

public abstract Box<B2, U> Transform<B2,U>(Func<T, U> transform) where B2 : Box<B2, U>;

你能把它做成一个
并通过工厂方法传递实现特定的信息吗?@miliesmith删除CRTP当然可以,但这会导致无法控制像
框合并(Box-other,Func-Merge)这样的方法
实际接受兼容的
Box
es。不是100%需要
B2
而不是
B
,但是您肯定需要它作为编译的
Transform
的类型参数(如果我将B2添加到方法的泛型参数中),但是现在我不能保证B2和B实际上是同一个派生类,这是我的目标。我实际上想确保B2和B是同一个类,U和T是完全独立的类型。比如说,
InfiniteSequence
是一个派生类,我想从转换中得到一个无限序列,而不是一个抽象框。我想你想说的是,虽然B和B2不是同一类型,但它们应该是同一个实例,但两者之间没有任何继承关系,对吗?我想你不会明白的。考虑克隆Box并在此过程中强制转换T->U。不,我正在尝试设置通用约束,允许我使用以下签名覆盖
FooBox:Box
中的方法
FooBox Transform(Func Transform)
,而不是
BarBox Transform(Func Transform)
的任何其他子项。
public abstract Box<B, U> Transform<U>(Func<T, U> transform);
public abstract Box<B, U> Transform<U>(Func<T, U> transform) where B : Box<B, U>;
public abstract Box<B2, U> Transform<B2,U>(Func<T, U> transform) where B2 : Box<B2, U>;
public abstract Box<B2, U> Transform<B2,U>(Func<T, U> transform) 
    where B2 : Box<B2, U>
    where U : T