#linq #reflection #lambda #reflector
#linq #отражение #лямбда #отражатель
Вопрос:
Я использую Reflector для декомпиляции некоторых двоичных файлов. У меня проблема с лямбда-выражениями и методом, который не компилируется. лямбда-выражение кажется мне очень сложным, и я понятия не имею, как преобразовать его обратно в компилируемый код 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) amp;amp; (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:
Вы пробовали ILSpy? У него даже есть некоторые параметры для управления, хотите ли вы создать синтаксис LINQ «function» или 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
«функции».
Если вы действительно хотите использовать то, что вам дал отражатель, это «исправленная» версия:
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) amp;amp; (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) amp;amp; (func.SubFunctionId != subFunctionId)
select func).Select(func => (func.Volume * func.RialAmount)).Sum();
}
Приложение: проверено, ILSpy создает случайный мусор, похожий, но отличный от Reflector
Комментарии:
1. @mani_007
into func
создаетIEnumerable<FunctionEnctity>
.where
Вероятно, это неправильно, потому что оно пытается сравнитьIEnumerable
сsectionEntity.SectionId
. Попробуйте изменить его наinto func from func2 in func where fun2.SectionId == sectionEntity.SectionId ...
, но помните, что теперь у вас естьfunc2
это элементfunc