Вы не можете перегружать метод только возвращаемым значением (общим или нет). Кроме того, было бы невозможно разрешить вызовы к 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, который позволяет вам вызывать его без явного объявления типа (в ваших угловых скобках), является использование параметра out. Однако я бы этого избегал, так как из-за 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
, который может выйти из-под контроля по мере роста вашей кодовой базы.