インターフェース型の変数への代入と 3 項演算子を組み合わせるとコンパイルエラーになる
クラス A と、クラス B が IDisposable
を実装しているとします。
そのときに、3 項演算子を用いて、以下のように書くことはできないようです。
class A : IDisposable { ... } class B : IDisposable { ... } // コンパイルエラーになる: There is no implicit conversion between 'A' and 'B' IDisposable c = true ? new A() : new B();
IDisposable
でキャストすれば問題なくコンパイルできます。
// OK IDisposable c = true ? (IDisposable)new A() : (IDisposable)new B();
あるいは、いったん IDisposable
型の変数に格納しておいてから、3 項演算子を使う方法もあります。
IDisposable a = new A(); IDisposable b = new B(); var c = true ? a : b; // OK
背景
あるオブジェクトの配列があり、それをいくつかの異なる方法でソートする必要がでてきました。
そのため、それぞれの比較方法に応じた IComparer
を実装するクラスを用意して、
それを Sort
メソッドに渡してソート方法を切り替えようと考えました。
Sort
メソッドに IComparer
を渡すときに 3 項演算子を使おうとしたのですが、
コンパイルエラーになりましたので、かわりに IComparer
を返すメソッドを作成するようにしました。
おおよそ以下のようなコードを書きました。
using System; using System.Collections.Generic; class Foo {} // Foo をある方法 A で比較 class ComparerA : IComparer<Foo> { public int Compare(Foo x, Foo y) { throw new NotImplementedException(); } } // Foo をある方法 B で比較 class ComparerB : IComparer<Foo> { public int Compare(Foo x, Foo y) { throw new NotImplementedException(); } } class Program { static void Main() { var foos = new[] { new Foo() }; Array.Sort(foos, new ComparerA()); // 方法 A でソート Array.Sort(foos, new ComparerB()); // 方法 B でソート // フラグでソート方法を切り替える。 // 本当はこう書きたかったがコンパイルエラー: // There is no implicit conversion between 'ComparerA' and 'ComparerB' // Array.Sort(foos, true ? new ComparerA() : new ComparerB()); // 3 項演算子が使えないので、IComarer を返すメソッドを用意した Array.Sort(foos, CreateComparer(true)); } static IComparer<Foo> CreateComparer(bool flag) { if (flag) return new ComparerA(); return new ComparerB(); } }