戻り値だけでメソッドをオーバーロードすることはできません (ジェネリックかどうかに関係なく)。Bar
さらに、オブジェクトは と の両方IAlpha
を実装できるため、 への呼び出しを解決することは不可能でありIBeta
、オーバーロードを使用してこれを行うことはできません。
public class AlphaBeta : IAlpha, IBeta
{
string x {set;}
string y {set;}
}
// too ambiguous
AlphaBeta parkingLot = myFoo.Bar<AlphaBeta>();
メソッドは戻り値の型によってのみ異なるため、以下も機能しません。
class Gar
{
public string Foo()
{
return "";
}
public int Foo()
{
return 0;
}
}
残念ながら、最善の解決策は、一般的ではない解決策を使用することです。ここでは、コマンド パターンが役に立ちます。
public class Foo
{
private readonly static Dictionary<Type, Command> factories =
new Dictionary<Type, Command>();
static Foo()
{
factories.Add(typeof(IAlpha), new AlphaCreationCommand());
factories.Add(typeof(IBeta), new BetaCreationCommand());
}
public T Bar<T>()
{
if (factories.ContainsKey(typeof(T)))
{
return (T) factories[typeof(T)].Execute();
}
throw new TypeNotSupportedException(typeof(T));
}
}
// use it like this
IAlpha alphaInstance = myFoo.Bar<IAlpha>();
IBeta betaInstance = myFoo.Bar<IBeta>();
Bar を実装するもう 1 つの方法は、明示的に型を宣言せずに呼び出すことができるようにする (角かっこで) ことです。ただし、100% 管理された出力パラメーターは通常、悪い設計の悪臭を放つため、これは避けたいと思います。
public void Bar<T>(out T returnValue)
{
if (factories.ContainsKey(typeof(T)))
{
returnValue = (T) factories[typeof(T)].Execute();
return;
}
throw new TypeNotSupportedException(typeof(T));
}
// call it like this
// T is inferred from the parameter type
IAlpha alphaInstance;
IBeta betaInstance;
myFoo.Bar(out alphaInstance);
myFoo.Bar(out betaInstance);
Command
、AlphaCreationCommand
、BetaCreationCommand
、およびを除外しTypeNotSupportedException
ました。それらの実装はかなり自明です。
別の方法として、コマンドの代わりに Func を使用することもできますが、これによりFoo
、コード ベースが大きくなるにつれて手に負えなくなる可能性のあるすべてのインスタンス化コードを実装する必要があります。