[英]Generic method returning objects of generic derrived types
我在C#中的泛型方面有些掙扎。 考慮這段代碼:
public interface A {};
public interface B : A {};
public interface C : A {};
public interface IMyInterface<in T> where T : A {};
public class FirstImpl<T> : IMyInterface<T> where T : B {};
public class SecondImpl<T> : IMyInterface<T> where T : C {};
現在我需要一些工廠,該工廠采用一種類型並返回正確的實現:
public IMyInterface<T> Create<T>() where T : A
{
if(typeof(T) is B) {
return new FirstImpl<T>();
}
if(typeof(T) is C) {
return new SecondImpl<T>();
}
}
這在兩個層面上都不起作用。 第一個是返回類型。 第二個是我不能將“ T”傳遞到第一個或第二個實現中,因為它們需要更具體的類型。 任何想法如何解決這個問題?
每當您使用通用類型或方法編寫代碼,並且該代碼對通用類型參數進行某種測試時,您就做錯了。 (恕我直言,不用說,反射會更糟。)泛型類型的全部要點是編寫不依賴於泛型類型的代碼。
在您的示例中,更好的方法是這樣的:
static IMyInterface<T> CreateB<T>() where T : B
{
return new FirstImpl<T>();
}
static IMyInterface<T> CreateC<T>() where T : C
{
return new SecondImpl<T>();
}
即編寫不同的方法來處理每種情況。 如果基於約束的方法行得通,則調用者無論如何都要知道正在處理什么。 因此,僅使用不同的方法名稱就不會有問題,每種方法名稱都將在適當的情況下使用。
如果以上內容不能解決您的特定情況,請改進問題,使其包括一個良好的“ 最小,完整和可驗證”代碼示例 ,該示例不僅顯示您嘗試使用的泛型類型,還顯示它們將在其中使用的上下文。用過的。
如果您不介意反思,可以這樣做:
public static IMyInterface<T> Create<T>() where T : A
{
if (typeof(B).IsAssignableFrom(typeof(T)))
{
var type = typeof(FirstImpl<>);
var boundType = type.MakeGenericType(typeof(T));
return (IMyInterface<T>) Activator.CreateInstance(boundType);
}
else if(typeof(C).IsAssignableFrom(typeof(T)))
{
var type = typeof(SecondImpl<>);
var boundType = type.MakeGenericType(typeof(T));
return (IMyInterface<T>) Activator.CreateInstance(boundType);
}
throw new ArgumentException("unknown type " + typeof(T).Name);
}
您可以在.net小提琴中嘗試
最簡單的方法是僅使用Create<T>()
方法添加額外的約束,例如public IMyInterface<T> Create<T>() where T : A , B, C
如果想要保持設計完整public IMyInterface<T> Create<T>() where T : A , B, C
則public IMyInterface<T> Create<T>() where T : A , B, C
。 對於默認情況,您可能需要一個實現來使方法完整。
public IMyInterface<T> Create<T>() where T : A, B, C
{
if (typeof(T) is B)
{
return new FirstImpl<T>();
}
if (typeof(T) is C)
{
return new SecondImpl<T>();
}
return new DefaultImpl<T>;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.