簡體   English   中英

C# - 使用泛型類型參數創建 class 的實例而不指定這些類型

[英]C# - Create an instance of a class with generic type parameters without specifying these types

我有以下代碼:

public static class Typing
{
    public static void Run()
    {
        var type = typeof(GenericSuperType<,>);

        type = type.MakeGenericType(typeof(int), typeof(int));
        dynamic instance = Activator.CreateInstance(type);
        var types = instance.Register();
        
        foreach(var i in types)
            Console.WriteLine(i);
    }
}

public class GenericSuperType<C, R>
{
    public IEnumerable<Type> Register()
    {
        yield return typeof(MiddlewareOne<C, R>);
        yield return typeof(MiddlewareTwo<C, R>);
    }
}

public interface IGenericMiddleware<C, R>
{
    R Execute(C command);
}

public class MiddlewareOne<C, R> : IGenericMiddleware<C, R>
{
    public R Execute(C command)
    {
        return default;
    }
}

public class MiddlewareTwo<C, R> : IGenericMiddleware<C, R>
{
    public R Execute(C command)
    {
        return default;
    }
}

我想要實現的是創建一個GenericSuperType<,> class 的實例,以便調用基本上會返回一些其他泛型類型的Register()方法。 這樣做的唯一目的是獲取Register()方法返回的類型(這些類型可能與示例中的類型不同,並且將由用戶在方法重載中提供)。 但是,為了做到這一點,我需要在這里為GenericSuperrType<,>提供一些類型(就像我對int所做的那樣),但隨后問題就出現了——這些類型可以對它們有通用約束,比方說:

public class GenericSuperType<C, R> where C : ISomeType
{
    public IEnumerable<Type> Register()
    {
        yield return typeof(MiddlewareOne<C, R>);
        yield return typeof(MiddlewareTwo<C, R>);
    }
}

在這種情況下,創建任何類型的實例都會失敗。
到目前為止,我嘗試的是檢查CR的通用約束並采取相應的行動,類似於這些行(一個簡單的例子):

    public static void Run()
    {
        var type = typeof(GenericSuperType<,>);

        var defparams = type.GetGenericArguments();
        IList<Type> typeConstraints = new List<Type>();
        foreach (var i in defparams)
        {
            typeConstraints.Add(i.GetGenericParameterConstraints().FirstOrDefault());
        }

        for (int i = 0; i < typeConstraints.Count; i++)
        {
            if (typeConstraints[i] == null)
                typeConstraints[i] = typeof(String);
        }

        type = type.MakeGenericType(typeof(int), typeof(int));
        dynamic instance = Activator.CreateInstance(type);
        var types = instance.Register();
        
        foreach(var i in types)
            Console.WriteLine(i);
    }

這可以正常工作,但我必須涵蓋所有可能的通用約束。
我想到的另一件事是:通過反射實際刪除GenericSuperType<,>泛型類型約束(如果實際上可能,我認為應該這樣做,但我不擅長 c# 反射),然后只提供一些虛擬類型從Register()方法中獲取類型。 或者也許只是將類型/類/文件的內容復制到另一個沒有泛型類型約束並調用它們? 我正在尋找解決方案(我知道這聽起來很復雜,但我也知道反射是一個強大的工具,可以讓這成為可能)。

預先感謝您的所有幫助!

你的目標到底是什么? 最終,我會說你應該創建一個界面:

public interface IRegster
{
    IEnumerable<Type> Register();
}

然后讓你所有的 class 具體實現這個。 然后您不必擔心任何泛型類型或創建虛擬實例或類似的東西。 您只需通過接口獲取類型。

但是,您並沒有真正說明這些泛型類型類稍后將如何最終實例化(真正的實現),所以我不知道任何人都可以在這里給您完美的建議。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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