2011-11-29 14 views
25

ReSharperのは、だから私は少しを調査し、this articleを読み終わった(ウィキペディア記事を見つけ)といくつかのより多くのGoogleの<TFrom、out TTo>はどういう意味ですか?

interface IModelMapper<in TFrom, out TTo> 

interface IModelMapper<TFrom, TTo> 
{ 
    TTo Map(TFrom input); 
} 

から変更することが示唆されました。

これは私のアプリケーションには何を意味するのかまだ分かりませんので、私はその提案を受け入れたくないと誘惑されます。この変更が導入するメリットは何ですか?私はその提案を無視して検討していませんか?

さらに明示的に、なぜ私はそれを受け入れるべきですか?

答えて

48

ボトムライン: ReSharperのは、あなたのタイプを調査し、TFromがcontravariantly使用することができることを発見し、covariantly TToました。リファクタリングを受け入れることで、以下に説明するように、これらの型を柔軟に使用することができます。それが貴重なものであれば、それを受け入れてください。

ただし、このリファクタを受け入れるとは今後これらのタイプをどのように使用するかを制限することになります。TToをパラメータとするメソッドを記述した場合、共存型を読み込むことができないため、コンパイラエラーが発生します。TFromの場合は、この型を返すメソッドを持つことはできません。このタイプのパラメータはoutです。


TFromが反変であることを伝えるだ

、そのTToは共変です。これらのだった機能は、最近added to C#

タイプ共分散はcontravarianceが少ない特定のタイプが渡されることを意味しているより特定のタイプは、渡され得ることを意味する。

IEnumerable<T>は、タイプの良い例です。共分散。あなたがリード/ライトされたコレクションのためにこれを行うさせた(仮に)場合について考えてみましょう

IEnumerable<object> objects = new List<string>(); 

IEnumerable<T>内の項目のみを読んでいるので、あなたはより具体的な何かにそれを設定すること:

List<object> objects = new List<string>(); 
objects.Add(new Car()); 
//runtime exception 

がタイプ共変であるために、一般的なパラメータは、厳密には読み取り専用方法で使用する必要があります。それはタイプからに書き出しただけでなければなりません。(したがってキーワード)に決して読み込まないでください。そのため、IEnumerable<T>の例が機能しますが、List<T>の例は機能しません。ところで、配列をサポートしています(Javaはそう思うので)、この同じ種類の実行時エラーは配列では可能です。

逆反りは逆を意味します。コントラバティブタイプをサポートするには、汎用パラメータをに、にのみ、に書き込む必要があります。

Action<object> objAction = (o => Console.WriteLine(o.ToString())); 
Action<string> strAction = objAction; 
strAction("Hello"); 

strActionは、文字列パラメータを取るように宣言されていますが、オブジェクト型に置き換えた場合、それは正常に動作します:。これは

Action<T>がタイプcontravainceの一例であるあなたが少なく、特定のタイプを代用することができます。文字列が渡されますが、デリゲートが動作するように設定されている場合は、それをオブジェクトとして扱うことを選択すると、そうなります。大丈夫です。

Func<T>Action<T>の逆の場合です。ここTだけので、それは共変だ、返されます。

Func<string> strDelegate = () => "Hello"; 
Func<object> myObjFunc = strDelegate; 
object O = myObjFunc(); 

myObjectFuncは、オブジェクトを返すようにコーディングされています。それを文字列を返すものに設定した場合、再び、害はありません。この選択は、あなたのアプリケーションに影響を与える可能性がある方法の例として、

+0

ありがとう、本当に役に立ちます。 – mhttk

+0

@mhttk - 素晴らしい。喜んで助けてください –

+0

おそらく私が読んだco/contravarianceの最もよい説明 - ありがとう! –

2

は、あなたがIModelMapper<Customer, Address[]>IModelMapper<Supplier, Address[]>を実装して、別の1 SupplierAddressMapperを実装タイプCustomerAddressMapperを持っていると仮定します。 CustomerSupplierの型は基本クラスCompanyを共有していますが、アドレスロジックは異なるため、これを処理するために別の型が必要です。

ここで、IMapper<Company, Address[]>を受け取るメソッドがあるとします。インターフェイスの反復性の前に、CustomerAddressMapperまたはSupplierAddressMapperのインスタンスをこのメソッドに渡すことはできません。ここで、タイプパラメータTFromin修飾子を使用すると、これを行うことができます。

さらに、TToパラメータの共分散のためにIMapper<Customer, object>を必要とするメソッドにCustomerAddressMapperを渡すこともできます。

関連する問題