[英]Is this bad practice? Overloading methods for generic interface and returning different types
[英]Generic interface overloading for methods?
有沒有一種好的,通用的方法可以執行以下操作,而無需求助於第二種方法或進行大量強制轉換-我想使API盡可能輕便,在我看來,OO明智:
class Foo
{
public T Bar<T>() where T: IAlpha
{
/* blahblahblah */
}
public T Bar<T>() where T: IBeta
{
/* blahblahblah */
}
}
interface IAlpha
{
string x {set;}
}
interface IBeta
{
string y {set;}
}
謝謝
您不能僅通過返回值(泛型或非泛型)重載方法。 另外,將不可能解析對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而無需顯式聲明類型(在尖括號中)的方式調用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代替Commands,但是這迫使您在Foo
實現所有實例化代碼,隨着代碼庫的增加,這些實例化代碼可能會失控。
這個怎么樣?
class Foo
{
public void Bar<T>(Action<T> @return) where T: IAlpha
{
@return(new AlphaImpl());
}
public void Bar<T>(Action<T> @return) where T: IBeta
{
@return(new BetaImpl());
}
}
interface IAlpha
{
string x {set;}
}
interface IBeta
{
string y {set;}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.