2012-07-16 2 views
1

에서 나는 다른 방법으로 호출 할 필요가 기능 식 트리Expression<Func<TClass, TProperty>>가 나중에 코드에서 입력 한 다음 객체의 전역 변수에 할당되는 상황을 결국했습니다 표현식. 전역 개체 유형을 변경할 수 없습니다. 그것은 객관적이어야합니다.캐스트 기능 식 트리 객체

개체를 Expression<Func<TClass, TProperty>>으로 캐스팅하지 않으면 전역 개체로 두 번째 메서드를 호출 할 때 코드가 컴파일되지 않습니다. 문제는 무엇입니까? TProperty은 두 번째 메서드가 호출되는 시점에 있습니다.

나는 (VS2010로 작성된 C# 콘솔 앱) 요점을 설명하기 위해 간단한 데모 앱을 만들었습니다. 실제 응용 프로그램은 이와 같이 보이지 않습니다.

using System; 
using System.Linq.Expressions; 

namespace FuncExpressionTree 
{ 
    public class ViewModel 
    { 
     public string StringProperty { get; set; } 
     public int IntProperty { get; set; } 
    } 

    public class Helper<T> 
     where T : ViewModel 
    { 
     private object _global; 

     public void Execute() 
     { 
      AssignToGlobal((T vm) => vm.StringProperty); 

      ProcessGlobal(); 

      AssignToGlobal((T vm) => vm.IntProperty); 

      ProcessGlobal(); 
     } 

     public void AssignToGlobal<TClass, TProperty>(Expression<Func<TClass, TProperty>> expression) 
     { 
      _global = expression; 
     } 

     public void ProcessGlobal() 
     { 
      // invalid cast exception thrown when IntProperty is assigned to _global 
      AssignToGlobal((Expression<Func<T, string>>)_global); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      (new Helper<ViewModel>()).Execute(); 
     } 
    } 
} 

Execute() 방법에 초점을 맞추면.

  1. 처음으로 전역에는 string 속성에 대한 표현식이 할당됩니다.
  2. Expression<Func<T, string>>으로 전송 중이기 때문에 ProcessGlobal이 실행되고 작동합니다.
  3. 다음 글로벌에는 int 속성에 대한 표현식이 할당됩니다.
  4. ProcessGlobal이 다시 실행되지만이 시점에서 잘못된 캐스트 예외가 발생합니다. 대신 Expression<Func<T, int>>을 캐스팅하도록 변경했지만 문자열 속성이 작동하지 않으면 작동합니다. 또한 Expression<Func<T, object>>은 잘못된 캐스트 예외를 발생시킵니다.

나는 임 뭔가 빠진 것 같은 느낌과 동적 (위의 예에서 ProcessGlobal 내에서 예를 들어 AssignToGlobal)이 두 번째 방법을 호출 할 System.Linq.Expressions 네임 스페이스와 함께 뭔가를 할 수 있어야한다는.

일반적인 방법으로 어떻게 작동합니까?

답변

1
public void ProcessGlobal() 
    { 
     var globalType = _global.GetType(); // globalType = Expression<Func<TClass, TProperty>> 
     var functionType = globalType.GetGenericArguments()[0]; // functionType = Func<TClass, TProperty> 
     var functionGenericArguments = functionType.GetGenericArguments(); // v = [TClass, TProperty] 
     var method = this.GetType().GetMethod("AssignToGlobal").MakeGenericMethod(functionGenericArguments); //functionGenericArguments = AssignToGlobal<TClass, TProperty> 
     method.Invoke(this, new[] { this._global }); // Call AssignToGlobal<TClass, TProperty>)(this._global); 
    } 
+0

감사합니다. TClass 인스턴스와 전역이라는 두 가지 인수를 사용하여 호출하도록 조정할 필요가 있지만 감사합니다. –

+0

문제가 발견되면 msg me "작동하지 않는 코드"라고 알려 드리겠습니다. – user1494736