Сгенерированный лямбда-выражением с помощью рефлектора, как вернуть реальный Linq Query? - PullRequest
2 голосов
/ 15 октября 2011

Я использую Reflector для декомпиляции некоторых двоичных файлов. У меня проблема с лямбда-выражениями и methodof , который не компилируется. лямбда-выражение мне кажется очень сложным, и я не знаю, как преобразовать его обратно в компилируемый код LINQ. вот код:

public double? LoadSumRialAmount(long functionId, long? subFunctionId)
{
        ParameterExpression expression;
        if (!subFunctionId.HasValue)
        {
            return (from func in base.MetaData.SubFunction
                where func.FunctionId == functionId
                select func).Select<SubFunctionEntity, double?>(System.Linq.Expressions.Expression.Lambda<Func<SubFunctionEntity, double?>>(System.Linq.Expressions.Expression.Multiply(System.Linq.Expressions.Expression.Property(expression = System.Linq.Expressions.Expression.Parameter(typeof(SubFunctionEntity), "func"), (MethodInfo) methodof(SubFunctionEntity.get_Volume)), System.Linq.Expressions.Expression.Property(expression, (MethodInfo) methodof(SubFunctionEntity.get_RialAmount))), new ParameterExpression[] { expression })).Sum();
        }
        return (from func in base.MetaData.SubFunction
            where (func.FunctionId == functionId) && (func.SubFunctionId != subFunctionId)
            select func).Select<SubFunctionEntity, double?>(System.Linq.Expressions.Expression.Lambda<Func<SubFunctionEntity, double?>>(System.Linq.Expressions.Expression.Multiply(System.Linq.Expressions.Expression.Property(expression = System.Linq.Expressions.Expression.Parameter(typeof(SubFunctionEntity), "func"), (MethodInfo) methodof(SubFunctionEntity.get_Volume)), System.Linq.Expressions.Expression.Property(expression, (MethodInfo) methodof(SubFunctionEntity.get_RialAmount))), new ParameterExpression[] { expression })).Sum();
}

p.s другая ошибка: класс SubFunctionEntity имеет свойство «Volume», и я не понимаю, почему этот код вызывает какое-то статическое свойство, например: SubFunctionEntity.get_Volume

1 Ответ

3 голосов
/ 15 октября 2011

Вы пробовали ILSpy ?У него даже есть несколько параметров для управления, если вы хотите создать синтаксис «функции» LINQ или from... where синтаксис (View->Options->Decompiler->Decompile query expression и Decompile anonymous methods/lambdas)

Для вашего другого вопроса: SubFunctionEntity.get_Volume является получателемСвойство Volume класса SubFunctionEntity.

(MethodInfo) methodof(SubFunctionEntity.get_Volume) такое же, как typeof(SubFunctionEntity).GetProperty("Volume").GetGetMethod(), только выполняется во время компиляции, а не во время выполнения.Проблема в том, что C # не имеет methodof «функции».

Если вы действительно хотите использовать то, что дал вам Reflector, это «исправленная» версия:

public double? LoadSumRialAmount(long functionId, long? subFunctionId)
{
    ParameterExpression expression;
    if (!subFunctionId.HasValue)
    {
        return (from func in base.MetaData.SubFunction
                where func.FunctionId == functionId
                select func).Select<SubFunctionEntity, double?>(Expression.Lambda<Func<SubFunctionEntity, double?>>(Expression.Multiply(Expression.Property(expression = Expression.Parameter(typeof(SubFunctionEntity), "func"), typeof(SubFunctionEntity).GetProperty("Volume").GetGetMethod()), Expression.Property(expression, typeof(SubFunctionEntity).GetProperty("RialAmount").GetGetMethod())), new ParameterExpression[] { expression })).Sum();
    }
    return (from func in base.MetaData.SubFunction
            where (func.FunctionId == functionId) && (func.SubFunctionId != subFunctionId)
            select func).Select<SubFunctionEntity, double?>(Expression.Lambda<Func<SubFunctionEntity, double?>>(Expression.Multiply(Expression.Property(expression = Expression.Parameter(typeof(SubFunctionEntity), "func"), typeof(SubFunctionEntity).GetProperty("Volume").GetGetMethod()), Expression.Property(expression, typeof(SubFunctionEntity).GetProperty("RialAmount").GetGetMethod())), new ParameterExpression[] { expression })).Sum();
}

Обратите внимание, что вам нужно будет использовать:

using System.Linq;
using System.Linq.Expressions;

Ах ... самое сложное выражение: func => (func.Volume * func.RialAmount), чтобы вы могли написать метод как:

public double? LoadSumRialAmount(long functionId, long? subFunctionId)
{
    if (!subFunctionId.HasValue)
    {
        return (from func in base.MetaData.SubFunction
                where func.FunctionId == functionId
                select func).Select(func => (func.Volume * func.RialAmount)).Sum();
    }
    return (from func in base.MetaData.SubFunction
            where (func.FunctionId == functionId) && (func.SubFunctionId != subFunctionId)
            select func).Select(func => (func.Volume * func.RialAmount)).Sum();
}

Приложение: проверено, ILSpy производит случайный мусор, похожий, но отличный от Reflector

...