首页 > 解决方案 > 在 MemberExpression 中处理“转换为对象”

问题描述

我有一个看起来像这样的类:

public class MyClass
{
  public int Id { get; set; }
  public string Name { get; set; }
}

我需要这样做:

var memberExpressions = ConvertToMemberExpressions<MyClass>(o => o.Id, o => o.Name);

...

public static List<MemberExpression> ConvertToMemberExpressions<T>(params Expression<Func<T, object>>[] methodExpressions)
{
    var results = new List<MemberExpression>();
    foreach(var methodExpression in methodExpressions)
    {
        var memberExpression = methodExpression.Body as MemberExpression;
        results.Add(memberExpression);
    }
    return results;
}

问题是因为Func<T, object>(能够同时包含intstring作为参数)我的 methodExpression 看起来像这样:{o => Convert(o.Id, Object)},这不是我需要的。我需要到达o.Id

字符串不会发生这种情况:{o => o.Name},这里没有转换。

我曾经Func<T,object>能够利用 Intellisense 并获得 MyClass 的道具。我尝试过使用Func<T, dynamic>,但结果是一样的。

可以使用多个重载来解决它:

public static ConvertToMemberExpressions<TClass, T1>(Expression<Func<TClass,T1>>[] methodExpression1)
public static ConvertToMemberExpressions<TClass, T1, T2>(Expression<Func<TClass,T1>>[] methodExpression1, Expression<Func<TClass,T2>>[] methodExpression2)
...

...但如果可能的话,我想避免这种牺牲。


问题

o => o.Id是否可以从构建o => Convert(o.Id, Object)

标签: c#reflectionlinq-expressions

解决方案


只需检查您是否methodExpression.BodyUnaryExpressiona NodeTypeConvert

public static List<MemberExpression> ConvertToMemberExpressions<T>(params Expression<Func<T, object>>[] methodExpressions)
{
    var results = new List<MemberExpression>();
    foreach (var methodExpression in methodExpressions)
    {
        var expr = methodExpression.Body;
        if (expr is UnaryExpression unaryExpression && unaryExpression.NodeType == ExpressionType.Convert)
        {
            expr = unaryExpression.Operand;
        }

        if (expr is MemberExpression memberExpression)
        {
            results.Add(memberExpression);
        }
        else
        {
            throw new ArgumentException($"Unexpected expression type {expr.NodeType}");
        }
    }
    return results;
}

使用表达式时,调试器是您的朋友:

expr 上的 Watch 窗口的图像,显​​示了 NodeType 和 Operand 的类型和值


推荐阅读