Javaの世界から来て、ジェネリックスとC#を使ったプログラミングはしばしば頭痛の種です。このように:
interface ISomeObject { }
class SomeObjectA : ISomeObject { }
class SomeObjectB : ISomeObject { }
interface ISomething<T> where T : ISomeObject
{
T GetObject();
}
class SomethingA : ISomething<SomeObjectA>
{
public SomeObjectA GetObject() { return new SomeObjectA(); }
}
class SomethingB : ISomething<SomeObjectB>
{
public SomeObjectB GetObject() { return new SomeObjectB(); }
}
class SomeContainer
{
private ISomething<ISomeObject> Something;
public void SetSomething<T>(ISomething<T> s) where T : ISomeObject
{
Something = (ISomething<ISomeObject>)s;
}
}
class TestContainerSomething
{
static public void Test()
{
SomeContainer Container = new SomeContainer();
Container.SetSomething<SomeObjectA>(new SomethingA());
}
}
その結果、InvalidCastException
atになりSomething = (ISomething<ISomeObject>)s;
ます。Javaでは、これは機能し、ジェネリックワイルドカードを使用することもできます(他のすべてが失敗した場合)<?>
。これはC#では不可能です。
これは問題を説明するためにまとめた単なる例ですが、この例外をどのように排除できますか?唯一の主な制約は、ジェネリッククラスになるSomeContainer
ことはできないということです
**注**:これについては多くの質問がありますが、(私が見つけた)それらのどれも非ジェネリッククラス内のジェネリッククラスメンバーに対応していません。
**更新**
メソッド内に、SetSomething
次の行を追加しました。
Console.WriteLine(s.GetType().IsSubclassOf(typeof(ISomething<SomeObjectA>)));
Console.WriteLine(s.GetType().ToString() + " : " + s.GetType().BaseType.ToString());
foreach (var i in s.GetType().GetInterfaces())
{
Console.WriteLine(i.ToString());
}
驚いたことに、これは
False
SomeThingA : System.Object
ISomething`1[SomeObjectA]
これが、この例外が発生する理由ですか?