2010-02-04 26 views
49

Tôi đang cố gắng tạo ra một hệ thống tập lệnh đơn giản sẽ được sử dụng để in nhãn. Tôi đã làm điều này trong quá khứ với sự phản chiếu mà không có vấn đề gì, nhưng bây giờ tôi đang cố gắng làm điều đó với các hàm Lambda để tôi có thể cache các hàm để tái sử dụng.Biểu thức loại 'System.Int32' không thể được sử dụng cho kiểu trả về 'System.Object'

Code tôi có cho đến nay là như sau ...

public static string GetValue<T>(T source, string propertyPath) { 

    try { 

     Func<T, Object> func; 

     Type type = typeof(T); 
     ParameterExpression parameterExpression = Expression.Parameter(type, @"source"); 
     Expression expression = parameterExpression; 
     foreach (string property in propertyPath.Split('.')) { 
      PropertyInfo propertyInfo = type.GetProperty(property); 
      expression = Expression.Property(expression, propertyInfo); 
      type = propertyInfo.PropertyType; 
     } 

     func = Expression.Lambda<Func<T, Object>>(expression, parameterExpression).Compile(); 

     object value = func.Invoke(source); 
     if (value == null) 
      return string.Empty; 
     return value.ToString(); 

    } 
    catch { 

     return propertyPath; 

    } 

} 

Điều này dường như làm việc trong một số trường hợp, nhưng trong những người khác nó không thành công. Vấn đề có vẻ là trong cố gắng của tôi để trả về các giá trị như các đối tượng - không phụ thuộc vào các kiểu dữ liệu thực tế. Tôi đang cố gắng để làm điều này bởi vì tôi không biết tại thời gian biên dịch những gì các loại dữ liệu sẽ được nhưng về lâu dài, tôi chỉ cần một chuỗi.

Tôi nhận được ngoại lệ được hiển thị trong tiêu đề của thông báo này bất cứ khi nào tôi cố gắng truy cập thuộc tính loại Int32 - nhưng tôi cũng nhận được nó cho các loại Nullable và các loại khác. Trường hợp ngoại lệ được ném khi tôi cố gắng biên dịch biểu thức thành hàm.

Ai có thể đề xuất cách tôi có thể thực hiện điều này một cách khác nhau trong khi vẫn duy trì chức năng Lambda để tôi có thể lưu bộ nhớ cache cho người truy cập?

Trả lời

94

Bạn đã thử sử dụng Expression.Convert? Điều đó sẽ thêm chuyển đổi boxing/nâng/etc.

Expression conversion = Expression.Convert(expression, typeof(object)); 
func = Expression.Lambda<Func<T, Object>>(conversion, parameterExpression).Compile(); 
+1

Bạn đã vô cùng chặt chẽ với câu trả lời này, chỉ có nó là "khái niệm" mà cần thiết để được chuyển đổi và không "parameterExpression" (biểu hiện = Expression.Convert (biểu hiện, typeof (Object)); ) ngay trước khi biên dịch. Cảm ơn. –

+1

Rất tiếc - cảm ơn, đã sửa. –

+0

Làm việc rực rỡ! – Schotime

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