質問
私は、これは公共の暴言の詳細ですが、なぜ私は私のIDの型を推論するためにC#を得ることができないと仮定?
public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>
とIDとしてGUIDを持つ定義EntityObject次のように
public Foo : EntityObject<Guid>
次のように定義された抽象EntityObjectクラスから継承
public abstract class EntityObject<IdT>
{
public IdT id { get; set; }
}
次のようにgetメソッドの使い方は以下のようになります:
IRepository repository = new Repository();
var hydratedFoo = repository.Get<Foo>(someGuidId);
の更なる明確化を提供するために、編集した。の
解決
それはあなたが唯一の2つの宣言を与えてくれたことを考えると、ありませんどのようにあなたがそれらを使用していると言うのは難しいです。 IDTは、どこか別の型パラメータですか?
- (それはそれがあることをお勧めTId
あった場合の規則に反していますが、別の型パラメータのEntityT
を使用しているという事実、...多分IdT
も同様であることを示唆しています)
さて、実際にあなたのケースでIdT
をGuid
されると仮定すると、どのようにあなたが意味することをコンパイラのワークアウトはFoo
必要がありますか? EntityObject<Guid>
から派生する他のタイプがある可能性があります。
要するに、あなたは私達に確かに何かを伝えるために十分な情報を与えられていないが、あなたは基本的にコンパイラに不当な要求を作っているように思えます。
EDIT:さて、ここでは通常の命名規則を使用して、あなたが持っているもので、私の推測です:
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>
を使用することを好むと思う。
他のヒント
宣言
public EntityT Get<EntityT>(IdT id) where EntityT : EntityObject<IdT>
IDTは、具体的なタイプであることを要求しています。あなたにもIDTをパラメータ化したい場合は、あなたが使用する必要があると思います。
public EntityT Get<EntityT, IdT>(IdT id) where EntityT : EntityObject<IdT>
しかし、それはあなたがしたいと思うものを、おそらくではありません。
このです。私はすべての場所で2を散布することなく、一般的なキーの種類を持っている私のエンティティを取得する方法を見つけ出すことができませんでした。今、私は(私はとにかくどこにでも持っているものである)整数キーに落ち着いてきましたが、それは間違っていると感じます。
あなたのメソッドのシグネチャは、このように見えた場合:
public TEntity Get<TEntity, TId>(TId id) where TEntity : EntityObject<TId>
コンパイラが...で動作するように何かを持っているでしょう。
あなたは、その後のようなものを取得する呼び出します
EDIT(私が間違っていた):<ストライキ>製品P =取得します(ID); ストライキ>
Product p = Get<Product, Guid>(id);
彼のポストアップトップとJonの釘付けこの答えは、私は黙ってよ、私の穴に戻ってクロールます。