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#がこれらの提案の1つをサポートできなかった/提供できなかった理由はありますか?(または、偶然に、言語の関連する既存の機能を見落としたことがありますか?)