私が持っているとしましょう:
- 一般的な方法
Get<T>
- いくつかのインターフェース
IEntity
、IValue
- これらのインターフェースをそれぞれ実装するいくつかのクラス ex:
Entity
->IEntity
、Value
->IValue
など。
=>Get<T>
メソッドがインターフェイスをジェネリック型としてのみ許可する方法はありますか?
Get<IEntity>(42); //Allowed
Get<Entity>(42); //Compiler error
私の現在のソリューションは次のようになります。
Get<T>
Type 制約を持つジェネリック メソッドwhere T: IPersistable
(ほとんどの型がパラメーターとして渡されないようにするため)- インターフェイスは実装します
IPersistable
関数はアクティブに型をチェックします。
public T Get<T>(long id) where T : IPersistable
{
if (typeof (T) == typeof (IEntity))
return (T) EntityDao.Get(id);
if (typeof (T) == typeof (IValue))
return (T) ValueDao.Get(id);
//...
throw new TechnicalException("Type not supported");
}
=> 問題は次のとおりです。
- それはきれいではありません...チェックするタイプが非常に少ないので、私はそれで暮らすことができました
- 署名は、関数が実際に行うことと一致しません。それは
IPersistable
in を許可しますが、実際には <- は許可しません。それは本当に私を悩ませます:(
編集:クラスの過剰人口を避けるために、そのような制約を検討しています。
そのクラスには、ほぼすべてこのように機能する 8 つまたは 9 つのジェネリック メソッドがあります。直感的な方法は、@DanielHilgarthがタイプごとに1つのメソッドのみを持つことを提案したことです。メソッドは現在、4 または 5 種類でのみ呼び出すことができます。それでも、それはそのクラスに 32 ~ 40 個のメソッドがあることを意味します。
できればそれは避けたいです。
Edit2 :「実際の」クラスが呼び出されるのを防ぐ必要性は、共分散/反分散の問題から生じます。EntityDaoおよびValueDaoGet<T>
メソッドはオブジェクトを返します。でキャストできないため、メソッドでコレクションを呼び出すと、単一のオブジェクトを照会するとうまくいきません。IEntity
IValue
GetAll<T>
IEnumerable<IValue>
IEnumerable<Value>
リストのキャストに関する@JonSkeetsからのこの回答に気付きました。それは回避策かもしれません...