C#交叉引用泛型类
本文关键字:泛型类 引用 | 更新日期: 2023-09-27 18:26:14
我希望两个泛型类能够相互引用。我似乎找不到任何要编译的东西。尝试过这个:
class Program
{
static void Main(string[] args)
{
}
public class ClassA<BT> where BT: ClassB<ClassA<BT>>
{
BT btvar;
}
public class ClassB<AT> where AT: ClassA<ClassB<AT>>
{
AT atvar;
}
}
这有一个实际的实现,但我想避免对自己的代码进行复杂的解释。我可以创建遵守规则的封闭类,但我似乎无法为这些封闭实例描述泛型类或接口。
据我所知,这是不可能的,这就是为什么:
您想要一个模板值为B类型的A。你想要B,模板值为a类型。
如果你创建了一个新的a实例,编译器必须检查T是否属于B类型。要检查它是否属于B,它必须检查B是否属于a类型,a是否属于B类,等等。
你最终创造了一个无尽的循环。
我最终完成这项工作的方式是将类添加为自己的类型参数之一。它不太漂亮,但很管用。
public abstract class Saver<TSaver, TData>
where TSaver : Saver<TSaver, TData>
where TData : ISaveable<TData, TSaver>
{ ... }
public interface ISaveable<TData, TSaver>
where TData : ISaveable<TData, TSaver>
where TSaver : Saver<TSaver, TData>
{ ... }
public class WorkspaceWindow : ScalingWindow, ISaveable<WorkspaceWindow, WorkspaceWindowSaver>
{ ... }
public class WorkspaceWindowSaver : Saver<WorkspaceWindowSaver, WorkspaceWindow>
{ ... }
这是可能的,下面是基于这个问题的答案。
public class ClassA<BT, AT> :
where BT : ClassB<AT, BT>
where AT : ClassA<BT, AT>
{
BT btvar;
}
public class ClassB<AT, BT> :
where BT : ClassB<AT, BT>
where AT : ClassA<BT, AT>
{
AT atvar;
}
您将无法直接使用这些类,您需要覆盖它们。
public ClassAImp : ClassA<ClassBImp, ClassAImp>
public ClassBImp : ClassB<ClassAImp, ClassBImp>
所以你不妨把ClassA和ClassB抽象化。
这将编译,但我希望看到您实例化ClassA或ClassB:
public class ClassA<TBt> where TBt : ClassB<TBt>
{
TBt _btvar;
}
public class ClassB<TAt> : ClassA<TAt> where TAt : ClassB<TAt>
{
TAt _atvar;
}
"你为什么要这样做?"对我来说是一个很好的问题。Generics的目的是允许你抽象一个类,允许它使用多种类型。如果约束将类型限制为具体类型,则只允许该类型及其子类。如果你不是为子类做这件事,就不要使用泛型。如果你是,那么使用一个接口怎么样?
public interface IClassA<ITB> { }
public interface IClassB<ITA> { }
public class ClassA<AT,BT> : IClassA<BT> where BT : IClassB<AT>
{
BT btvar;
}
public class ClassB<BT,AT> : IClassB<AT> where AT : IClassA<BT>
{
AT atvar;
}
public class ClassADerivedClosed : ClassA<ClassADerivedClosed, ClassBDerivedClosed> { }
public class ClassBDerivedClosed : ClassB<ClassBDerivedClosed, ClassADerivedClosed> { }