なぜC#で、この暗黙の型変換が失敗するのか?
-
22-09-2019 - |
質問
背景:
レッツは、私は以下のクラスを持っていると仮定します
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' に変換できません。明示的なonversionは の
私はこれを理解していません。ここでの問題は何ですか?
解決
私は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、一般的に理解しやすい
。所属していません StackOverflow