Я искал высокий уровень SO, чтобы найти решение для моей проблемы.Преобразование типов деревьев выражений
Я нашел несколько ответов для того, когда речь идет о простых выражениях, как
var exp1 Expression<Func<T, bool>> x => x.Name == "MyName"
Но у меня возникают проблемы, когда выражения, как:
var exp1 Expression<Func<T, bool>> x => x.Category.Name == "Coupe"
Для неопытных, я могу преобразовать любое выражение из одного типа (T) в другое (TT), мне нужно сделать это и в других случаях более сложным ...
Любой, кто может помочь с некоторыми указателями? Вот что у меня до сих пор:
private class CustomVisitor<T> : ExpressionVisitor
{
private readonly ParameterExpression mParameter;
public CustomVisitor(ParameterExpression parameter)
{
mParameter = parameter;
}
//this method replaces original parameter with given in constructor
protected override Expression VisitParameter(ParameterExpression node)
{
return mParameter;
}
private int counter = 0;
/// <summary>
/// Visits the children of the <see cref="T:System.Linq.Expressions.MemberExpression" />.
/// </summary>
/// <param name="node">The expression to visit.</param>
/// <returns>
/// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression.
/// </returns>
/// <exception cref="System.NotImplementedException"></exception>
protected override Expression VisitMember(MemberExpression node)
{
counter++;
System.Diagnostics.Debug.WriteLine("{0} - {1}", node.ToString(), counter);
try
{
//only properties are allowed if you use fields then you need to extend
// this method to handle them
if (node.Member.MemberType != System.Reflection.MemberTypes.Property)
throw new NotImplementedException();
//name of a member referenced in original expression in your
//sample Id in mine Prop
var memberName = node.Member.Name;
//find property on type T (=PersonData) by name
var otherMember = typeof(T).GetProperty(memberName);
//visit left side of this expression p.Id this would be p
var inner = Visit(node.Expression);
return Expression.Property(inner, otherMember);
}
catch (Exception ex)
{
return null;
}
}
}
метод Полезность:
public static Expression<Func<TDestin, T>> ConvertTypesInExpression<TSource, TDestin, T>(Expression<Func<TSource, T>> source)
{
var param = Expression.Parameter(typeof(TDestin));
var body = new CustomVisitor<TDestin>(param).Visit(source.Body);
Expression<Func<TDestin, T>> lambda = Expression.Lambda<Func<TDestin, T>>(body, param);
return lambda;
}
И он используется так:
var changedFilter = ConvertTypesInExpression<ClientNotificationRuleDto, ClientNotificationRule, bool>(filterExpression);
Так что, если кто-нибудь может помочь с некоторыми Ideias или указатели, это было бы здорово!
Спасибо! Я проверю это. Об исключении, я знаю ... это не производственный код;) – Stargazer
Спасибо! Используя ваш код, мне удалось заставить его работать. В моем первоначальном коде не было части VisitLambda, и это имело значение. Благодаря! P.S.- Мне нужно изучить больше этого дерева выражений. :) – Stargazer
Ну, это все хорошо и отлично, пока ... Мне нужно иметь дело с захваченными переменными, что-то вроде: x => x.Name = varContainingName Я изо всех сил стараюсь расширить это, чтобы справиться с этим ... – Stargazer