2012-04-16 41 views
7

có cách nào để đặt Func<> đối số kiểu động không, vì vậy tôi không phải sử dụng câu hỏi if vô tận?Tự động đặt Func <> loại

Cái gì như:

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

Thay vì:

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

UPDATE:

Dưới đây là một đoạn trích từ mã của tôi:

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 là chuỗi - tên của một thuộc tính ide "StavkaDokumenta" lớp. pd.Expression là biểu thức chuỗi phải đánh giá loại Polje. stavka là một thể hiện của StavkaDokumenta.

+4

Nếu bạn đang sử dụng ifs vô tận, có thể có điều gì đó về cách tiếp cận hiện tại của bạn có thể được cải thiện? Tôi ít nhất cũng sẽ xem xét nó. – Botz3000

+3

Bạn có thể cung cấp ví dụ về chuỗi vô tận mà bạn đang cố gắng giải quyết không? – GregC

+3

Nếu bạn đang sử dụng vô tận 'xxx là SomeType', có thể có điều gì đó sai với thiết kế của bạn. –

Trả lời

9

Bây giờ bạn thấy những gì bạn thực sự muốn, câu trả lời là đơn giản hơn nhiều: Như bạn dường như chỉ quan tâm đến giá trị trả về của biểu thức đó, bạn có thể thay đổi mã của bạn như thế này:

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

Cũ câu trả lời:

Bạn có thể sử dụng Generics và chuyển đổi ngầm để Func<T> để đạt được điều này:

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

Gọi đó là với một nhóm phương pháp như vậy:

var foo = GetFunc(SomeMethod); 

này giả định rằng SomeMethod trông như thế này:

decimal SomeMethod() 
{ 
    // ... 
} 

foo sẽ loại Func<decimal>. Nếu loại trả lại là SomeMethod sẽ là string, loại foo sẽ là Func<string>.


gì sẽ xảy ra trong mã này như sau:

Tham số được truyền cho GetFunc là một cái gọi là "phương pháp nhóm" và không phải là một biến kiểu Func<T>. Tuy nhiên, có tồn tại một chuyển đổi ngầm từ một nhóm phương pháp để một biến Func<T>:

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

Đó chuyển đổi ngầm được chính xác những gì đang xảy ra ở đây: Trước khi GetFunc thậm chí được gọi, nhóm phương pháp SomeMethod được chuyển đổi các một biến nhập Func<T>. Loại bê tông được sử dụng cho T được phỏng đoán bổ sung bởi trình biên dịch dựa trên kiểu trả về của phương thức SomeMethod().
Mục tiêu của chúng tôi là tạo một phiên bản Func<T> dựa trên nhóm phương pháp của chúng tôi. Và bởi vì điều đó đã xảy ra trong việc chuyển đổi tham số trước khi phương thức được gọi, chúng ta chỉ đơn giản trả về cá thể đã tạo ra từ phương thức đó.

+0

Tôi xin lỗi, nhưng tôi không làm theo. Phương thức của bạn 'GetFunc ' có hiệu quả không làm gì cả. Nó trả về tham số giống như kiểu nó đã bắt đầu. – Yuck

+0

@Yuck: Phép thuật đang xảy ra trong chính cuộc gọi vì có tồn tại một chuyển đổi ngầm từ một nhóm phương thức ('SomeMethod') thành một biến kiểu' Func '. –

+0

Tôi sẽ thử nó ngay bây giờ Daniel, nhưng tôi nghĩ rằng sẽ làm các trick. Tôi đã bị mắc kẹt và đã bắt đầu giải quyết với ifs ... –

Các vấn đề liên quan