簡體   English   中英

泛型派生類型的泛型方法返回對象

[英]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, Cpublic 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM