43

説明

自分のタイプのプロパティを指す式があります。ただし、すべてのプロパティ タイプで機能するわけではありません。「意味がない」とは、異なる式タイプになることを意味します。私はそれが結果になると思っていました MemberExpressionが、そうではありません。

for intandGuidそれは a UnaryExpressionand for string in a になりMemberExpressionます。

私は少し混乱しています;)

サンプルコード

私のクラス

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

テストコード

Person p = new Person { Age = 16, Name = "John" };

Expression<Func<Person, object>> expression1 = x => x.Age;
// expression1.Body = UnaryExpression;

Expression<Func<Person, object>> expression2 = x => x.Name;
// expression2.Body = MemberExpression;

質問

2 つの式を比較して、それらが同じ型と同じプロパティを意味するかどうかを確認するにはどうすればよいですか?

更新、回答、および完全なサンプル

私を正しい軌道に乗せてくれたユーザーdasblinkenlightに感謝します。

その方法を提供してくれた

private static MemberExpression GetMemberExpression<T>(
    Expression<Func<T,object>> exp
) {
    var member = expr.Body as MemberExpression;
    var unary = expr.Body as UnaryExpression;
    return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}

メソッドの結果を比較し、同じGetMemberExpression かどうかを確認するために、次の拡張メソッドを作成しましGetMemberExpression().Member.Nameた。

private static bool IsSameMember<T>(this Expression<Func<T, object>> expr1, Expression<Func<T, object>> expr2)
{
    var result1 = GetMemberExpression(expr1);
    var result2 = GetMemberExpression(expr2);

    if (result1 == null || result2 == null)
       return false;

    return result1.Member.Name == result2.Member.Name;
}
4

2 に答える 2

81

これが発生する理由は、それAge型であるためです。値の型を返す式を強制的にFunc<Person,object>コンパイラに挿入するにはConvert(expr, typeof(object))、aを挿入する必要がありUnaryExpressionます。

ただしstring、s およびその他の参照型の場合は、ボックス化する必要がないため、「ストレートな」メンバー式が返されます。

MemberExpressionの内部にアクセスしたいUnaryExpression場合は、そのオペランドを取得できます。

private static MemberExpression GetMemberExpression<T>(
    Expression<Func<T,object>> exp
) {
    var member = exp.Body as MemberExpression;
    var unary = exp.Body as UnaryExpression;
    return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}
于 2012-10-19T13:38:15.683 に答える