您不能仅通过返回值(通用或非通用)重载方法。此外,不可能解决对 的调用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
随着代码库的增长,这些代码可能会失控。