Javaとおんなじ考えで使うとはまるC#のジェネリクス
クローズ構築型はオープン構築型にアサインできない
public class A<T> { }
public class B : A<string> { }
[TestMethod] public void Test() { Assert.IsFalse(typeof(A<>).IsAssignableFrom(typeof(B))); // Trueになると思いがちだけどFalse }
ついついやってしまいます。
本当にやりたいことはこう。
[TestMethod] public void Test() { Assert.IsTrue(HasGenericTypeDefinition(typeof(B), typeof(A<>))); }
private bool HasGenericTypeDefinition(Type target, Type typeDefinition) { for (var t = target; t != null; t = t.BaseType) { if (t.IsGenericType && t.GetGenericTypeDefinition() == typeDefinition) { return true; } } return false; }
A
ジェネリッククラスのstaticな値は異なるクローズ構築型で共有されない
public class C<T> { public static int Hoge { get; set; } }
[TestMethod] public void Test2() { C<int>.Hoge = 2; C<string>.Hoge = 3; Assert.AreEqual(2, C<int>.Hoge); // C<int>.Hogeが3になると思いがちだけど2 }
staticなフィールドで値をキャッシュするときなどに気をつけたいですね。
共有したいならジェネリックじゃないクラスにstaticをおいてそれを継承すると解決。その場合は、C
public class C { public static int Hoge { get; set; } }
public class C<T> : C { }