2012-04-16 8 views
7

Gibt es eine Möglichkeit, Func<> Typ Argumente dynamisch zu setzen, so dass ich nicht unendlich if Anweisungen verwenden müssen?Dynamisch gesetzt Func <> Typen

Etwas wie:

Type t = Type.GetType("System.Decimal"); 
Func<t> foo = new Func<t>(some_function); 

Statt:

Func<Decimal> foo = new Func<Decimal>(some_function); 

UPDATE:

Hier ein Ausschnitt aus meinem Code ist:

Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType; 
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka"); 
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression); 
Expression final = Expression.Convert(expr, t); 
if (t == typeof(decimal)) 
{ 
    var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal>>(final, pe); 
    o = lambda.Compile().Invoke(stavka); 
} 
if (t == typeof(decimal?)) 
{ 
    var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal?>>(final, pe); 
    o = lambda.Compile().Invoke(stavka); 
} 
else if (t == typeof(int)) 
{ 
    var lambda = Expression.Lambda<Func<StavkaDokumenta, int>>(final, pe); 
    o = lambda.Compile().Invoke(stavka); 
} 
else if (t == typeof(int?)) 
{ 
    var lambda = Expression.Lambda<Func<StavkaDokumenta, int?>>(final, pe); 
    o = lambda.Compile().Invoke(stavka); 
} 
else if (t == typeof(string)) 
{ 
    var lambda = Expression.Lambda<Func<string>>(final, null); 
    o = lambda.Compile().Invoke(); 
} 

pd.Polje ist string - Name einer Eigenschaft ins Ide "StavkaDokumenta" -Klasse. pd.Expression ist ein String-Ausdruck, der den Typ von Polje auswerten muss. stavka ist eine Instanz von StavkaDokumenta.

+4

Wenn Sie endlose ifs verwenden, gibt es vielleicht etwas an Ihrem derzeitigen Ansatz, das verbessert werden könnte? Ich würde es mir zumindest überlegen. – Botz3000

+3

Können Sie ein Beispiel für eine endlose if-Kette angeben, die Sie zu lösen versuchen? – GregC

+3

Wenn Sie endless 'xxx ist SomeType' verwenden, ist wahrscheinlich etwas mit Ihrem Design nicht in Ordnung. –

Antwort

9

Nun, da Sie zeigte, was Sie wirklich wollen, ist die Antwort viel einfacher: Wie Sie offenbar nur daran interessiert, den Rückgabewert dieses Ausdrucks sind, können Sie Ihren Code dies ändern:

Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType; 
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka"); 
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression); 
Expression final = Expression.Convert(expr, t); 

if (t == typeof(string)) 
{ 
    var lambda = Expression.Lambda<Func<string>>(final, null); 
    o = lambda.Compile().Invoke(); 
} 
else 
{ 
    var lambda = Expression.Lambda(final, pe); 
    o = lambda.Compile().DynamicInvoke(stavka); 
} 

Alte Antwort:

Sie Generika und implizite Konvertierung in Func<T> dies erreichen können:

Func<T> GetFunc<T>(Func<T> func) 
{ 
    return func; 
} 

Nennen Sie es mit einer Methodengruppe wie folgt:

var foo = GetFunc(SomeMethod); 

Dies setzt voraus, dass SomeMethod wie folgt aussieht:

decimal SomeMethod() 
{ 
    // ... 
} 

fooFunc<decimal> vom Typ sein. Wenn der Rückgabetyp SomeMethod ein string wäre, wäre der Typ fooFunc<string>.


Was in diesem Code geschieht, ist die folgende:

Der Parameter, auf GetFunc ist eine so genannte „Methodengruppe“ und nicht eine Variable vom Typ Func<T> geben wird. Allerdings gibt es eine implizite Konvertierung von einer Methodengruppe auf eine Variable Func<T>:

Func<decimal> func = SomeMethod; // an implicit conversion happens here 

Die implizite Konvertierung ist genau das, was hier geschieht: Vor GetFunc wird auch genannt, die Methodengruppe SomeMethod umgewandelt wird, die eine Variable Geben Sie Func<T> ein. Der für T verwendete konkrete Typ wird zusätzlich vom Compiler basierend auf dem Rückgabetyp der Methode SomeMethod() abgeleitet.
Unser Ziel war es, basierend auf unserer Methodengruppe eine Instanz von Func<T> zu erstellen. Und da dies bereits bei der Konvertierung des Parameters vor dem Aufruf der Methode geschieht, geben wir diese erzeugte Instanz einfach aus der Methode zurück.

+0

Es tut mir leid, aber ich folge nicht. Ihre Methode 'GetFunc ' macht effektiv nichts. Es gibt den Parameter als den gleichen Typ zurück, den er begonnen hat. – Yuck

+0

@Yuck: Die Magie passiert im Aufruf selbst, weil es eine implizite Konvertierung von einer Methodengruppe ('SomeMethod') in eine Variable vom Typ' Func 'gibt. –

+0

Ich werde es jetzt versuchen Daniel, aber ich denke, das wird den Trick machen. Ich steckte fest und fing an, mich mit ifs zu begnügen ... –