7

簡単に言うと、なぜこのコードはコンパイルに失敗するのでしょうか?

public interface IWorld { }
public class Foo<T> where T : IWorld { }
public void Hello<T>(T t) where T : IWorld
{
    Foo<IWorld> bar1 = new Foo<T>(); //fails implicit cast
    Foo<IWorld> bar2 = (Foo<IWorld>)new Foo<T>(); //fails explicit cast
}

すべてが をT実装するためIWorld、 のすべてのインスタンスがFoo<T>一致する必要がありますFoo<IWorld>。なぜだめですか?これを回避する方法はありますか?これを達成するためにジェネリックに頼りたくありません。

4

4 に答える 4

1

さらに単純な反論 - ではなくFoo、これが だったと想像してみてくださいList

List<T>yourを に変換したので、 typeのオブジェクトのみを含むように制約されているリストに、他の実装オブジェクト ( typeなど) をList<IWorld>追加できるようになりました。それは有効ではないはずです。 IWorldT2T

オブジェクトに戻りFooます - タイプ のオブジェクトで呼び出されることを期待するメソッドが含まれている場合、実装する任意のTオブジェクトでそれらを呼び出すことができるようになりました- (追加のタイプ制約を想像してください) そのオブジェクトが適格なタイプではないのために。IWorldFooFoo


コメントの私のポイント: 値の型。List<T>繰り返しになりますが、これは、値の型の aList<T>には、ボックス化されていない値の型が含まれているという観点から話すと、より簡単になる可能性があります。これらの同じ値が必要な場合は、リストに追加する前にList<IWorld>各値をボックス化する必要があります。

于 2012-12-21T10:44:06.403 に答える
1

最初にオブジェクトにキャストできます

Foo<IWorld> bar2 = (Foo<IWorld>)(object)new Foo<T>();
于 2012-12-21T10:10:11.977 に答える
1
T : IWorld

は、T が IWorld を実装したことを意味し、IWorld のみを実装し、正確に IWorld であることを意味するわけではありません。また、他のインターフェースが実装されている場合もあります。

ただし、C# はそれ以降のバージョンでこのキャストをサポートしています。http://msdn.microsoft.com/en-us/library/dd799517.aspx (ジェネリックにおける共分散と反分散) を参照してください。

于 2012-12-21T10:08:03.763 に答える
0

以下の問題は何ですか

 Foo<IWorld> bar1 = new Foo<IWorld>(); 

何を達成しようとしていますか?

インスタンスを渡す必要がある場合は、IWorld安全に渡すことができますがT、コードではそうではありません。

編集(コメントに基づく)

キャストするには、要件に応じてCastまたはOfTypeFoo<Array of something>を使用できます(互換性のない一致をスローするか無視するか)。

.NET 4の場合、CoVariance機能により自動的に機能するはずです。

于 2012-12-21T10:13:10.367 に答える