:CLRは、それがどの表現の変更を加える必要がないことを保証することができたときに基本的には、分散が適用さ値型に共分散を使用する方法は?あなたは、値型のための共分散を使用することはできません
:
Func<string> refTypeFunc =() => "foo"; Func<int> valueTypeFunc =() => 123; Func<object> a = refTypeFunc; // works Func<object> b = valueTypeFunc; // doesn't work
This answer by Jon Skeetは理由を説明します値に。参照はすべて同じように見えるので、
IEnumerable<string>
をIEnumerable<object>
として使用することができます。ネイティブコード自体は、インフラストラクチャが確実に有効であることを保証している限り、値を使って何をやっているのかを知る必要はありません。
IEnumerable<int>
をIEnumerable<object>
として処理する値型の場合、シーケンスを使用するコードはボクシング変換を実行するかどうかを判断する必要があります。
少なくともFunc
のためにあなたがこれを行うことができます。
Func<object> c =() => valueTypeFunc();
しかし、出て、このような簡単な方法は、ほとんどの場合に使用することはできません。私はICovariant<T>
を持っている場合今、私はICovariant<object>
にキャストすることはできません、と私はそれのうち簡単な方法を見ていない
interface ICovariant<out T>
{
Func<T> InnerFunc { get; }
}
:私のように定義されたインタフェースを持っていると言います。私が知っているT
はobject
であることができます - すべてできます。この場合、私は何ができますか?簡単な回避策がない場合は、他に最善の方法はありますか?
デザインは基本的に破っているobject' 'への一般的な値をキャストするためにあなたを必要とする理由たぶん自問してみてください第一にジェネリック医薬品の全目的。 – juharr
@juharrジェネリックの使用時には、実装と使用の両方がはるかにクリーンです。 'T'を返すメソッドがあります - ' object'を返すことは、呼び出しコードに醜いダウンキャスティングをたくさん追加します。 'T'を' object'として使うことは多相に非常に役立ちます。例えば、多くのオブジェクトインスタンスをリストに追加することです。 –
表現の変更がないようにしたい場合は、 'where T:class'をそこに貼り付けてください。 –