2016-10-12 219 views
0

我想創建Func鍵類型與指定的泛型類型參數,類似的東西一樣,但只有一個發言如何創建具有指定泛型類型的func類型?

Type create_type(Type[] types) 
{ 
    return typeof(Func<>).MakeGenericType(types); // error if types.Length != 1 
    return typeof(Func<,>).MakeGenericType(types); // error if types.Length != 2 
    return typeof(Func<,,>).MakeGenericType(types); // error if types.Length != 3 
    return typeof(Func<,,,>).MakeGenericType(types); // error if types.Length != 4 
// .... 
} 

當然,我可以創造auxuliary數組:

var func_types = new Type[] { typeof(Func<>), typeof(Func<,>) , //...} 

但是這種解決方案對我來說似乎太難看了

注:類型數組可以很長(最多15個),我想找到優雅的解決方案。不幸的是,我使用另一種語言編寫的元數據創建了這樣的類型

回答

3

有在表達類Func鍵是做exaclty你需要

Expression.GetFuncType(Type[] types) 

Expression.GetActionType(Type[] types) 

這裏進一步信息靜態方法和措施:

GetFuncType

GetActionType

+0

這是輝煌的答案! – LmTinyToon

+1

然後,我收回上面關於需要醜陋代碼的所有評論:)原來,這只是誰將不得不編寫那些醜陋或令人費解的代碼的問題 - https://referencesource.microsoft.com/#System.Core/Microsoft /Scripting/Compiler/DelegateHelpers.Generated.cs,227 –

+0

@CSharpie,這種方法是否有一些類似於元組類型的方法? – LmTinyToon

1

回想一下,泛型類型的名稱形式爲T`N,其中N是泛型參數的數量。因此,所有Func代表有一個系統的名稱,使我們能夠很容易地獲得類型:

Type create_type(Type[] types) { 
    return Type.GetType($"System.Func`{types.Length}").MakeGenericType(types); 
} 

沒有承諾就如何高效這一點,但如果你在運行時構建這樣的類型,這可能並不是主要的問題無論如何。


鑑於Expression.GetFuncType存在,這個答案當然是劣質的,但我要離開它用於教育目的(的某種)。這會停止超過9個參數的工作,因爲System.Func多於9個參數的代表存在於System.Core中,而不是mscorlib,因此需要裝配限定的名稱。修復很簡單(輸入支票並有條件地添加System.Core作爲名稱),但是由於存在GetFuncType而不必要。