1. ホーム
  2. c#

[解決済み] ラムダ式からプロパティ名を取得する

2022-03-17 14:12:27

質問

ラムダ式で渡されたときにプロパティ名を取得する良い方法はありますか? 以下は、私が現在持っているものです。

例えば

GetSortingInfo<User>(u => u.UserId);

プロパティが文字列の場合のみ、メンブレックスプレッションとしてキャストすることで動作しました。すべてのプロパティが文字列ではないため、オブジェクトを使用する必要がありましたが、それではそれらのための未解決の式が返されます。

public static RouteValueDictionary GetInfo<T>(this HtmlHelper html, 
    Expression<Func<T, object>> action) where T : class
{
    var expression = GetMemberInfo(action);
    string name = expression.Member.Name;

    return GetInfo(html, name);
}

private static MemberExpression GetMemberInfo(Expression method)
{
    LambdaExpression lambda = method as LambdaExpression;
    if (lambda == null)
        throw new ArgumentNullException("method");

    MemberExpression memberExpr = null;

    if (lambda.Body.NodeType == ExpressionType.Convert)
    {
        memberExpr = 
            ((UnaryExpression)lambda.Body).Operand as MemberExpression;
    }
    else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
    {
        memberExpr = lambda.Body as MemberExpression;
    }

    if (memberExpr == null)
        throw new ArgumentException("method");

    return memberExpr;
}

解決方法は?

もう一つの方法は、ソースとプロパティを強く型付けして、ラムダの入力を明示的に推論することです。これが正しい用語かどうかはわからないが、結果はこうだ。

public static RouteValueDictionary GetInfo<T,P>(this HtmlHelper html, Expression<Func<T, P>> action) where T : class
{
    var expression = (MemberExpression)action.Body;
    string name = expression.Member.Name;

    return GetInfo(html, name);
}

そして、このように呼び出します。

GetInfo((User u) => u.UserId);

で、出来上がりです。