Как преобразовать выражение <Func <T, DateTime >> в выражение <Func <T, object >> - PullRequest
55 голосов
/ 08 апреля 2009

Я искал, но не могу найти способ кастовать из типа

Expression<Func<T, DateTime>>

к типу:

Expression<Func<T, object>>

Так что я должен снова обратиться к ТАКИМ обширным знаниям;)

Ответы [ 4 ]

71 голосов
/ 08 апреля 2009

Вы не можете просто разыгрывать между ними, потому что это не одно и то же. Однако вы можете эффективно добавить преобразование в дерево выражений:

using System;
using System.Linq.Expressions;

class Test
{
    // This is the method you want, I think
    static Expression<Func<TInput,object>> AddBox<TInput, TOutput>
        (Expression<Func<TInput, TOutput>> expression)
    {
        // Add the boxing operation, but get a weakly typed expression
        Expression converted = Expression.Convert
             (expression.Body, typeof(object));
        // Use Expression.Lambda to get back to strong typing
        return Expression.Lambda<Func<TInput,object>>
             (converted, expression.Parameters);
    }

    // Just a simple demo
    static void Main()
    {
        Expression<Func<string, DateTime>> x = text => DateTime.Now;
        var y = AddBox(x);        
        object dt = y.Compile()("hi");
        Console.WriteLine(dt);
    }        
}
25 голосов
/ 14 декабря 2014

Ответы от Роб и Джон Скит имеют одну проблему.

Вы получаете что-то вроде x => Convert(x.PropertyName), но часто, например, для ASP.NET MVC вам нужно выражение вроде этого x => x.PropertyName

То есть Expression.Convert является "загрязняющим" выражением для некоторых случаев.

Решение:

public static class LambdaExpressionExtensions
{
    public static Expression<Func<TInput, object>> ToUntypedPropertyExpression<TInput, TOutput> (this Expression<Func<TInput, TOutput>> expression)
    {
        var memberName = ((MemberExpression)expression.Body).Member.Name;

        var param = Expression.Parameter(typeof(TInput));
        var field = Expression.Property(param, memberName);
        return Expression.Lambda<Func<TInput, object>>(field, param);
    }
}

Usage:

Expression<Func<T, DateTime>> expression = ...;
Expression<Func<T, object>> expr = expression.ToUntypedPropertyExpression();
10 голосов
/ 23 ноября 2010

Основываясь на коде от Jon (спасибо, кстати), вы можете сделать еще один шаг вперед для полной гибкости:

public static Expression<Func<TModel, TToProperty>> Cast<TModel, TFromProperty, TToProperty>(Expression<Func<TModel, TFromProperty>> expression)
{
    Expression converted = Expression.Convert(expression.Body, typeof(TToProperty));

    return Expression.Lambda<Func<TModel, TToProperty>>(converted, expression.Parameters);
}
0 голосов
/ 24 августа 2016

Просто определите out TResult как объект и скомпилируйте выражение, оно работает для всех типов данных;

Expression<Func<string, object>> dateExp = text => DateTime.Now;
object dt = dateExp.Compile()("hi");
Console.WriteLine(dt);

Образец скрипки здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...