2009-06-22 5 views

答えて

19

変換演算子は汎用ではありません。スペックセクション10.10からは、ここで変換オペレータ宣言子の形式です:

conversion-operator-declarator: 
    implicit operator type ( type identifier ) 
    explicit operator type ( type identifier )

は、たとえば、と方法-ヘッダをこの比較:

方法、ヘッダ属性 optメソッド修飾子 opt部分オプトリターン型 メンバー名型パラメータリストオプト(正式なパラメータリスト OPT型パラメータ制約-条項 opt

(このフォーマットについてはごめん。演算子形式には型パラメータリストまたは型パラメータの制約は含まれないことに注意してください。

+2

ユーザー定義の汎用コンバージョンをサポートしていても、このコンバージョンは依然として違法です。組み込みの変換を置き換える変換を定義することは不正です。これはTとUが同じ型であればそうするでしょう。アイデンティティ変換を置き換えます。 –

+1

キャストはコンパイラによって決定されるため、TとUが同じ型の場合、ユーザー定義キャストは使用されず、リーガルになります。 –

2

はあなたのコードでは、行に沸く:あなたが基底クラスを割り当てようreturn new Foo<U>((U)a.Item)

を継承されたクラスです。これは不可能です。

のは、T(ベース・クラス)を言ってみましょうが、タイプStreamであり、Uは、タイプMemoryStream(継承されたクラス)のものであり、あなたはタイプMemoryStreamの変数にStreamを割り当てることができません。

+0

リファレンスはストリームとしてオブジェクトをマスクしますが、実際にはMemoryStreamである場合、それを確実にメモリストリームにキャストすることができます。これは正当な方法です。問題は、演算子のオーバーロードでジェネリック制約を実際に指定することができないということです。 – LaserJesus

+0

...コードを取って、演算子のオーバーロードではなくメソッドとして表現するとコンパイルされます – LaserJesus

0

のだまされやすい人のようですそれはあなたが反変変換をしたいように見えるが、struct S変換はあなたに何も買わないので、@Gidonが指摘しているように、単にnew Foo<U>((U)a.Item)と言うことができます。、一般的なインタフェースで分散があるところで

var foo = new Foo<object>(new object { }); 
IFoo<String> bar = foo; 
bar.Item="123"; 
var b = Object.ReferenceEquals(foo, bar); // true 

を:好き

public interface IFoo<in T> { 
    T Item { 
     set; 
    } 
} 

public class Foo<T>:IFoo<T> { 
    public Foo(T item) { 
     this.Item=item; 
    } 

    public T Item { 
     get; set; 
    } 

    // public static explicit operator Foo<U>(U a) { 
    // return new Foo<U>((U)a.Item); 
    // } 
} 

とそれを使用する:あなたがクラスであることをFooを変更すると考えた場合

、その後、我々はいくつかの違いを作ることができます.netfx 4.0からのみ利用可能です。

関連する問題