你无法仅通过返回值(无论是通用的还是非通用的)来重载一个方法。此外,由于一个对象可以同时实现 IAlpha
和 IBeta
,因此无法解析对 Bar
的调用,因此不能使用重载。
public class AlphaBeta : IAlpha, IBeta
{
string x {set;}
string y {set;}
}
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));
}
}
IAlpha alphaInstance = myFoo.Bar<IAlpha>();
IBeta betaInstance = myFoo.Bar<IBeta>();
另一种实现Bar的方式是使用输出参数,这样可以在不明确声明类型(在尖括号中)的情况下调用它。然而,我建议避免使用它,因为在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));
}
IAlpha alphaInstance;
IBeta betaInstance;
myFoo.Bar(out alphaInstance);
myFoo.Bar(out betaInstance);
我排除了Command
, AlphaCreationCommand
, BetaCreationCommand
, 和 TypeNotSupportedException
。它们的实现应该相当容易理解。
或者,你可以使用Func而不是Commands,但这会强制你在Foo
中实现所有的实例化代码,随着代码库的增长,这可能会变得不可控。