どのように使用しているかではなく、2 つの宣言しか与えていないことを考えると、言うのは難しいです。IdT は別の型パラメータですか? (それがTId
である場合、それはそうであることが示唆されます-しかし、EntityT
慣習に反して、別の型パラメーターに使用しているという事実は、おそらくIdT
同様であることを示唆しています...)
IdT
さて、あなたの場合が実際にあると仮定Guid
すると、コンパイラはどのように機能するのFoo
でしょうか? から派生した他のタイプが存在する可能性がありますEntityObject<Guid>
。
要するに、確実に何かを伝えるのに十分な情報を提供していませんが、基本的にコンパイラに対して不当な要求をしているように思えます。
編集:さて、通常の命名規則を使用して、あなたが持っているものについての私の推測は次のとおりです:
public interface IRepository
{
TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>
}
public abstract class EntityObject<TId>
{
public IdT id { get; set; }
}
public class Foo : EntityObject<Guid> {}
あなたがしたい:
IRepository repository = GetRepositoryFromSomewhere();
Foo foo = repository.Get<Foo>(someGuid);
現在、あなたがしなければならないのは:
Foo foo = repository.Get<Foo, Guid>(someGuid);
はい、コンパイラは必要以上に少し難しくしています。言語をより単純にし、型推論のルールを理解しやすくするために、6 文字を追加しました。
基本的に、型推論はすべてか無かの問題です -すべての型パラメータが推論されるか、どれも推論されないかのどちらかです。これにより、どれが指定されていてどれが指定されていないかを判断する必要がないため、シンプルに保たれます。それは問題の一部であり、他の部分は、メソッドの型パラメーターに対してのみ制約を表現できることです。次のことはできません。
class Repository<TEntity>
{
TEntity Get<TId>(TId id) where TEntity : EntityObject<TId>
}
それは制約TEntity
であり、ではありませんTId
。繰り返しますが、この種のことは型推論をより簡単にします。
これで、潜在的に次のように書くことができます:
Foo foo = repository.Get(someGuid).For<Foo>();
適切なGet
メソッドと追加のインターフェースを使用します。私は個人的にはただ使用することを好むと思いGet<Foo, Guid>
ます。