在使用 C# 泛型约束时,我对某些要求感到沮丧,我想知道是否有办法解决我的问题。如果没有,我想解释一下为什么事情没有按照我想要的方式工作。
这个例子展示了我目前基本上要做的事情:
public abstract class EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }
public abstract class LogicBase<TEntity, TID>
where TEntity : EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }
public abstract class ServiceBase<TLogic, TEntity, TID>
where TLogic : LogicBase<TEntity, TID>
where TEntity : EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }
// Concrete Examples
public class EgEntity : EntityBase<long> {}
public class EgLogic : LogicBase<EgEntity, long> {}
public class EgService : ServiceBase<EgLogic, EgEntity, long> {}
提案 A显示了我希望得到的东西(我看不出它不能以这种方式工作的原因):
public abstract class EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }
public abstract class LogicBase<TEntity>
where TEntity : EntityBase<?> // why not allow some kind of a "this could be whatever" syntax here ("?"), then infer the constraints on "?" based on the definition of EntityBase<>
{ }
public abstract class ServiceBase<TLogic>
where TLogic : LogicBase<?> // infer the constraints on "?" based on the definition of LogicBase<>
{ }
// Concrete Examples
public class EgEntity : EntityBase<long> {}
public class EgLogic : LogicBase<EgEntity> {}
public class EgService : ServiceBase<EgLogic> {}
提案 B展示了另一种可能的选择,尽管不如提案 A 有吸引力:
public abstract class EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }
public abstract class LogicBase<TEntity>
where TEntity : EntityBase<TID> // introduce TID here to keep it out of class signature
where TID : struct, IEquatable<TID>
{ }
public abstract class ServiceBase<TLogic>
where TLogic : LogicBase<TEntity> // introduce TEntity here
where TEntity : EntityBase<TID> // introduce TID here
where TID : struct, IEquatable<TID>
{ }
// Concrete Examples
public class EgEntity : EntityBase<long> {}
public class EgLogic : LogicBase<EgEntity> {}
public class EgService : ServiceBase<EgLogic> {}
这两个提案都将最小化我在创建派生类型时必须指定的类型参数的数量,并且提案 A 将消除对一堆冗余约束的需要。
那么 C# 不能/不应该为这些提案之一提供支持是否有原因?(或者我是否忽略了该语言的相关现有功能?)