オーバーロードされたジェネリクスなメソッドが使いにくい

そういうルールだといわれるとそれまでなんですが、ジェネリクスなメソッドがオーバーロードされている場合、呼び出すメソッドを決定するルールが不便にかんじます。

たとえば次のような3つのクラスがあるとします。ポイントは、BはAのサブクラスだけどCはちがうということです。

private class A
{
}

private class B : A
{
}

private class C
{
}

オーバーロードされた2つのメソッドを用意します。

private A Hoge(A a)
{
	Console.WriteLine("private A Hoge(A a)");
	return a;
}

private T Hoge<T>(T t)
{
	Console.WriteLine("private T Hoge<T>(T t)");
	return t;
}

そしてこれらを呼び出します。さぁ、コンソールの出力結果はどうなるでしょう。

[TestMethod]
public void TestGenerics()
{
	Hoge(new A());
	Hoge(new B());
	Hoge(new C());
}

こうなりました。

private A Hoge(A a)
private T Hoge<T>(T t)
private T Hoge<T>(T t)

自分としては「Hoge(new B())」のコードは「private A Hoge(A a)」を呼んでほしいのですが、「private T Hoge(T t)」を呼び出します。このルールは特定の型(ここではA)のサブタイプを同じメソッド(ここでは「private A Hoge(A a)」)で扱いたいときに不便です。

ちなみにJavaジェネリクスだと上記と似たようなコードでは、自分の期待通りの動きになります(BはAと同じメソッドで扱われる)。