![](/img/trans.png)
[英]Create instance of class with generic type and call method of same generic type from string name of object at runtime
[英]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.