簡體   English   中英

在運行時創建未知通用類Type-object的實例?

[英]Create instance of an unknown generic class Type-object at runtime?

(我確定這已經回答了,我搜索了但找不到)

我需要在運行時創建幾種通用類型的實例。 也就是說,我有一個名為i的變量,該變量持有一個介於0-4之間的數字,並且我需要為Action<>Action<T1>Action<T1, T2>Action<T1, T2, T3>創建一個Type對象的實例。 Action<T1, T2, T3>Action<T1, T2, T3, T4>具體取決於數字(實際情況並非如此簡單,以至於它實際上在0-4之間,我只能使用switch語句)。

編輯:闡明我需要該類型的Type對象,而不是該類型的實例。

我能想到的最通用的方法是按名稱加載目標操作類型,其中反引號后面的數字(又稱accent accent )表示所需的通用參數的數量。

不幸的是,在與其他操作類型不同的程序集(mscorlib)中發現了Action<>因此在使用此方法時,需要對其進行不同的處理。

public static Type GetActionDelegateType(params Type[] typeArgs)
{
    var argCount = typeArgs.Length;
    if (argCount == 0) return typeof (Action);
    var defType = argCount == 1
        ? typeof (Action<>) //special case since it's found in mscorlib
        : Type.GetType(string.Format("System.Action`{0}, {1}",
            argCount,
            typeof (Action).Assembly.FullName));
    return defType.MakeGenericType(typeArgs);
}

您可以使用以下測試代碼查看上面的代碼:

for (var i = 0; i <= 4; i++)
{
    var typeArgs = Enumerable.Repeat(typeof (string), i).ToArray();
    Console.WriteLine(GetActionDelegateType(typeArgs));
}

我不確定我是否完全理解您要達到的目標。 我會嘗試猜測。

如果您知道所需的類型參數數量永遠不會超過四個,則可以制作一個數組

Type[] types = new Type[] { typeof(Action<>), typeof(Action<,>), typeof(Action<,,>) }; // omitted the rest

並提供功能

int CalculateNumberOfParameters(int i)
{     
    // I don't know what your i variable really means, but I suggest you have some method to determine a number of type parameters from it).
}

然后,您只需使用types [CalculateNumberOfParameters(i)]即可獲取您的操作類型。 請注意,我提供了一個非參數化泛型數組,因此您應該在它們上調用MakeGenericType()以創建實際的可實例化類型。 如果您事先知道通用參數(並且它們不依賴於i),則應在創建類型數組時指定它們。

如果您永遠無法確定所需的通用參數數量,則必須在運行時創建類型,因為.net僅使用0-4參數定義Action。 您仍然必須提供一種到標准類型的轉換(或適配器),因此創建的類型的實例實際上可以在應用程序的其他部分使用。 這是一條艱難的路,我只需要使用一次(用於linq表達式序列化),因此除非特別要求,否則我不會深入研究細節。

使用Activator.CreateInstance(string assembly, string classname)

“程序集”可以為空(在這種情況下,在當前程序集中搜索類類型)。 “類名”應表示類名,您可以從整數或任何信息中獲得該類名。

對於模板類,請使用classif字符串形式“ ClassName'T1”。

在類上(靜態)使用typeof(Action<...>) ,在實例上(動態)使用GetType()方法。

不太確定您要尋找的是什么,您從未提到從哪里獲得T1,T2,T3?

此代碼可能對您有幫助。

private static void CreateAppropriateAction(params Type[] argTypes)
        {
            var numberOfArgs = argTypes.Count();
            switch (numberOfArgs)
            {
                case 1:
                    var oneArgAction = typeof(Action<>).MakeGenericType(argTypes);
                    break;
                case 2:
                    var twoArgAction = typeof(Action<,>).MakeGenericType(argTypes);
                    break;
                case 3:
                    var threeArgAction = typeof(Action<,,>).MakeGenericType(argTypes);
                    break;
                default:
                //Do nothing or throw exception
                    break;
            }
        }              

然后,您可以將這種方法與像這樣的調用一起使用...

CreateAppropriateAction(typeof(string),typeof(int));

暫無
暫無

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

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