2012-04-16 20 views
7

¿Hay alguna forma de establecer argumentos de tipo Func<> dinámicamente, por lo que no tengo que usar infinidad de sentencias if?Func <> tipos dinámicamente

Algo así como:

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

En lugar de:

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

ACTUALIZACIÓN:

He aquí un fragmento de mi código:

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 es una cadena - nombre de una propiedad ins ide "StavkaDokumenta" clase. pd.Expression es una expresión de cadena que debe evaluar al tipo de Polje. stavka es una instancia de StavkaDokumenta.

+4

Si está utilizando infinitos if, tal vez hay algo acerca de su enfoque actual que podría mejorarse? Al menos lo consideraría. – Botz3000

+3

¿Podría darnos un ejemplo de cadena infinita si está intentando resolverlo? – GregC

+3

Si está utilizando infinito 'xxx es SomeType', probablemente haya algo mal con su diseño. –

Respuesta

9

Ahora que mostró lo que realmente quiere, la respuesta es mucho más simple: Como es aparentemente sólo está interesado en el valor de retorno de esa expresión, se puede cambiar el código para esto:

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); 
} 

vieja respuesta:

puede utilizar los genéricos y la conversión implícita a Func<T> para lograrlo:

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

llama con un grupo método de este modo:

var foo = GetFunc(SomeMethod); 

Esto supone que SomeMethod se parece a esto:

decimal SomeMethod() 
{ 
    // ... 
} 

foo será de tipo Func<decimal>. Si el tipo de devolución de SomeMethod fuera string, el tipo de foo sería Func<string>.


Lo que sucede en este código es la siguiente:

El parámetro que se pasa a GetFunc es el llamado "grupo de método" y no una variable de tipo Func<T>. Sin embargo, existe una conversión implícita de un grupo método a una variable de Func<T>:

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

que la conversión implícita es exactamente lo que está sucediendo aquí: Antes GetFunc incluso se llama, el grupo método SomeMethod se convierte en la variable de tipo Func<T>. El tipo concreto utilizado para T es inferido adicionalmente por el compilador basado en el tipo de retorno del método SomeMethod().
Nuestro objetivo fue crear una instancia de Func<T> basada en nuestro grupo de métodos. Y como eso ya ocurre en la conversión del parámetro antes de que el método sea llamado, simplemente devolvemos esa instancia creada del método.

+0

Lo siento, pero no sigo. Su método 'GetFunc ' no está haciendo nada. Devuelve el parámetro como el mismo tipo que comenzó. – Yuck

+0

@Yuck: La magia está sucediendo en la propia llamada porque existe una conversión implícita de un grupo de métodos ('SomeMethod') a una variable de tipo' Func '. –

+0

Lo intentaré ahora, Daniel, pero creo que hará el truco. Estaba atascado y estaba empezando a conformarme con ifs ... –

Cuestiones relacionadas