2つの宣言を与えただけで、使用方法はわかりません。 IdTは別の型パラメータですか? IdT
があると仮定すると、今
を - (ただし、規則に反して別の型パラメータのEntityT
を、使用しているという事実は、...多分IdT
も同様であることを示唆している、それはTId
だったら、それはそれは示唆しています)あなたのケースでは実際に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>
}
をそれがTId
、TEntity
はない制約だからです。ここでも、このようなことは型推論を簡単にします。
今、あなたは潜在的に書くことができます:
Foo foo = repository.Get(someGuid).For<Foo>();
適切なGet
方法と、余分なインターフェースで。私は個人的にちょうどGet<Foo, Guid>
を使用することを好むだろうと思う。
ジョン、詳細を追加しないことをお詫び申し上げます。これは本当に正当な疑問ではなく、カフの暴言から離れていました。しかし、imhoコンパイラはコンパイル時にfooオブジェクトからIdTを決定できるはずです。 ほとんどの場合、ジェネリックのための私の前提ですが、コンパイラがこれをどのように読むことができるかの解釈が間違っていますが、コンパイル時までジェネリック型が決まっていないと仮定しました。テンプレートオブジェクト。それが、参照されるオブジェクトのタイプを決定することがさらに一歩前進しないと仮定します。 – Raspar
Generics!= Templates。あなたはおそらく、そのようなことを「推論する」C++コンパイラを手に入れることができますが、ジェネリックがランタイムである限り、より明示的な一般的な定義なしには起こりません。 – user7116
IdTは 'Get'の型パラメータではありません。これは型パラメータが' EntityT'だけです。あなたはIRepositoryの宣言をしていないか、あなたのために働いていないものを与えていません。あなたがしようとしていることを示して、あなたが望むものの代わりに何が起こったのかを伝える*完全な例を挙げてください。 –