2016-10-12 4 views
0

Ich möchte Func Typ mit angegebenen generischen Typargumente, so ähnlich wie, aber nur mit einer AussageWie man Art von Funktion mit spezifizierten allgemeinen Typen schafft?

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 
// .... 
} 

Natürlich schaffen, ich auxuliary Array erstellen:

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

Aber diese Lösung scheint zu hässlich für mich

Hinweis: Array von Typen kann lang sein (bis zu 15) und ich möchte elegante Lösung finden. Leider erstelle ich solche Art von Metadaten, in einer anderen Sprache geschrieben

Antwort

3

Es gibt statische Methoden in der Expression-Klasse für Func und Aktion, die exaclty tun, was Sie benötigen

Expression.GetFuncType(Type[] types) 

Expression.GetActionType(Type[] types) 

Weitere Informationen hier:

GetFuncType

GetActionType

+0

die glänzende Antwort ist! – LmTinyToon

+1

Dann ziehe ich alle meine Kommentare oben über hässlichen Code zurück, der benötigt wird :) Stellt sich heraus, es ist nur eine Frage von wer diesen hässlichen oder gewundenen Code schreiben muss - https://referencesource.microsoft.com/#System.Core/Microsoft /Scripting/Compiler/DelegateHelpers.Generated.cs,227 –

+0

@Charpie, Gibt es ein Analogon einer solchen Methode für Tupel-Typ? – LmTinyToon

1

Erinnern Sie sich, dass generische Typen haben Namen der Form T`N, wobei N ist die Anzahl der generischen Parameter. So alle Func Delegierten haben einen systematischen Namen, die uns auf einfache Weise die Art zu erhalten:

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

Keine Versprechungen, wie effizient das ist, aber wenn man solche Typen zur Laufzeit ist die Konstruktion, das ist wahrscheinlich nicht das primäre Anliegen sowieso.


die Existenz Expression.GetFuncType In Anbetracht dieser Antwort natürlich schlechter ist, aber ich verlasse es für pädagogische Zwecke bis (irgendeiner Art). Dies funktioniert nicht mehr als 9 Argumente, da System.Func Delegaten von mehr als 9 Argumenten in System.Core, nicht mscorlib, leben und daher einen assemblierungsqualifizierten Namen erfordern. Die Lösung ist einfach (werfen Sie einen Scheck ein und fügen Sie unter Vorbehalt System.Core zu dem Namen hinzu), aber in Anbetracht der Existenz von GetFuncType unnötig.

Verwandte Themen