2010-08-24 4 views
1

Учитывая любую из приведенных ниже переменных, как я могу их «проверить», чтобы получить значение параметра, переданное в? т.е. 12345.Внутри дерева лямбда/выражения

System.Func<DateTime> f1 =() => DateTime.Now.AddDays(12345); 

System.Linq.Expressions.Expression<System.Func<DateTime>> 
         f2 =() => DateTime.Now.AddDays(12345); 

Edit:

два ответы ниже Микаэля и Кирка как ответить на мой вопрос Orignal. Тем не менее, я сделал это немного сложнее, чтобы иметь дело с «реальной жизнью». В идеале я ищу для «общего» решения, которое будет работать с чем-то Alongs линии ниже:

var days = 123; 
var hours = 456; 
System.Func<DateTime> f1 =() => DateTime.Now.AddDays(days).AddHours(hours); 
Expression<System.Func<DateTime>> f2 =() => DateTime.Now.AddDays(days).AddHours(hours); 

То, что я на самом деле после того, как способ генерации UNIKEY «ключ» дали lamda выражение. Моя идея - использовать имя метода и пары имя/значение параметра, но я приветствую другие предложения! Благодарю.

+0

'f1' действительно содержит информацию, но только путем проверки сгенерированного ИЛ от компилятора C#. 'f2', если он выполняется, компилируется во время выполнения, а компилятор C# просто создает дерево выражений, которое вы можете проверить с помощью типа и подтипов выражения. – Richard

ответ

2

Если вы имеете в виду значение 12345, эти данные можно получить только в f2. Для f2:

MethodCallExpression call = (MethodCallExpression)f2.Body; 
ConstantExpression arg = (ConstantExpression)call.Arguments[0]; 
Console.WriteLine(arg.Value); 
1

Единственный способ, которым я могу видеть, чтобы получить его от f1 является:

int days = (f1() - DateTime.Now).Days; 

который я сомневаюсь, что вы хотите.

Получение значения из f2, однако, возможно, и не так сложно, если тело функции так же четко определено, как и ваш пример. Он начнет что-то вроде ((f2 as LambdaExpression).Body as MethodCallExpression)....

Я мог бы занять много времени, чтобы выяснить, какой именно процесс, но, вероятно, было бы проще, если вы просто проверите f2 в отладчике.

3

В дополнение к ответу Кирк Волл, в, если вы хотите иметь 12345 в качестве объекта, вы можете использовать следующее:

public void Run() 
    { 
     System.Linq.Expressions.Expression<System.Func<DateTime>> f2 =() => DateTime.Now.AddDays(12345); 

     MethodCallExpression call = (MethodCallExpression)f2.Body; 
     ConstantExpression arg = (ConstantExpression)call.Arguments[0]; 

     var value = GetValue(arg); 
     Debug.WriteLine(value); 
    } 

    private object GetValue(ConstantExpression expression) 
    { 
     Expression conversion = Expression.Convert(expression, typeof(object)); 
     var getterLambda = Expression.Lambda<Func<object>>(conversion); 

     var getter = getterLambda.Compile(); 

     return getter(); 
    } 
Смежные вопросы