2012-04-16 16 views
7

jest jakiś sposób, aby ustawić argumenty typu Func<> dynamicznie, więc nie muszę używać niekończących if instrukcji?Dynamicznie ustawiać Func <> typy

Coś jak:

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

Zamiast:

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

UPDATE:

Oto fragment z mojego kodu:

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 jest ciąg - nazwa nieruchomości ins ide "StavkaDokumenta" klasa. pd.Expression jest wyrażeniem łańcuchowym, które musi być zgodne z typem Polje. stavka jest instancją StavkaDokumenta.

+4

Jeśli używasz nieskończonych ifs, być może jest coś w twoim obecnym podejściu, które można poprawić? Przynajmniej to rozważyłbym. – Botz3000

+3

Czy możesz podać przykład nieskończonego łańcucha, który próbujesz rozwiązać? – GregC

+3

Jeśli używasz nieskończonego 'xxx is SomeType', prawdopodobnie coś jest nie tak z twoim projektem. –

Odpowiedz

9

Teraz, gdy pokazał, co naprawdę chcesz, odpowiedź jest znacznie prostsza: Jak jesteś widocznie zainteresowany tylko w zwracanej wartości tego wyrażenia, można zmienić swój kod do tego:

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

Old odpowiedź:

można użyć rodzajowych i niejawna konwersja do Func<T> do osiągnięcia tego:

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

Nazwać z grupą metody tak:

var foo = GetFunc(SomeMethod); 

ta zakłada, że ​​SomeMethod wygląda następująco:

decimal SomeMethod() 
{ 
    // ... 
} 

foo będzie od rodzaju Func<decimal>. Jeśli typem zwrotu SomeMethod będzie string, typem foo będzie Func<string>.


Co się dzieje w tym kodzie jest następujący:

Parametr, który jest przekazywany do GetFunc jest tak zwana „grupa metoda”, a nie zmienna typu Func<T>. Jednak istnieje niejawna konwersja z grupy metoda zmiennej Func<T>:

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

To niejawna konwersja jest dokładnie to, co się dzieje tutaj: Przed GetFunc jest nawet nazywana grupa metoda SomeMethod przekształca się zmienną typ Func<T>. Typ betonu użyty dla T jest dodatkowo wywnioskowany przez kompilator na podstawie typu zwrotu metody SomeMethod().
Naszym celem było utworzenie instancji Func<T> w oparciu o naszą grupę metod. A ponieważ dzieje się to już podczas konwersji parametru przed wywołaniem metody, po prostu zwracamy tę utworzoną instancję z metody.

+0

Przykro mi, ale nie śledzę. Twoja metoda 'GetFunc ' skutecznie nie robi nic. Zwraca parametr jako ten sam, który zaczął. – Yuck

+0

@Yuck: Magia dzieje się w samym wywołaniu, ponieważ istnieje niejawna konwersja z grupy metod ('SomeMethod') do zmiennej typu' Func '. –

+0

Spróbuję teraz Daniel, ale myślę, że to załatwi sprawę. Utknąłem i zaczynało się układać z ifs ... –

Powiązane problemy