5

バックグラウンド:

次のクラスがあるとします。

class Wrapped<T> : IDisposable
{
    public Wrapped(T obj)  { /* ... */ }

    public static implicit operator Wrapped<T>(T obj)
    {
        return new Wrapped<T>(obj);
    }

    public void Dispose()  { /* ... */ }
}

ご覧のとおり、T→の暗黙的な型変換演算子を提供しますWrapped<T>。最終的には、このクラスを次のように使用できるようにしたいと考えています。

interface IX  { /* ... */ }

class X : IX  { /* ... */ }

...

IX plainIX = new X();

using (Wrapped<IX> wrappedIX = plainIX)
{
    /* ... */
} 

問題:

ただし、上記のusing句の型変換は失敗します。new X()を に直接割り当てることはできますがwrappedIX、型を割り当てることはできませんIX。コンパイラは次のエラーで文句を言います:

コンパイラ エラー CS0266: 型 'IX' を 'Wrapped<IX>' に暗黙的に変換することはできません。明示的な反転が存在します (キャストがありませんか?)

私はこれを理解していません。ここで何が問題なのですか?

4

1 に答える 1

6

インターフェースだからだと思いIXます。コンパイラーは、型の値が(封印されている場合でも)IX既に派生している可能性があると考えているため、変換を使用しません。Wrapped<IX>Wrapped<T>

詳細は非常に複雑で、C#3.0仕様のセクション6.4.3および6.4.4にあります。基本的にIXはインターフェースであるため、どのタイプにも「包含」されません。つまり、6.4.4の後のステップは失敗します。

Wrappedこのメソッドを使用して非ジェネリック型を作成することをお勧めします。

public static Wrapped<T> Of<T>(T item)
{
    return new Wrapped<T>(item);
}

次に、次のように書くことができます。

using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))

基本的に、変換はさまざまな理由で少し注意が必要です。単純な方法の方が一般的に理解しやすい、IMOです。

于 2010-03-26T19:27:42.967 に答える