ラムダ式を介して渡されるときにプロパティ名を取得するより良い方法はありますか? これが私が現在持っているものです。
例えば。
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;
}
ベストアンサー1
最近、型安全な OnPropertyChanged メソッドを作成するために、非常によく似たことを行いました。
式の PropertyInfo オブジェクトを返すメソッドを次に示します。式がプロパティでない場合は例外がスローされます。
public static PropertyInfo GetPropertyInfo<TSource, TProperty>(
TSource source,
Expression<Func<TSource, TProperty>> propertyLambda)
{
if (propertyLambda.Body is not MemberExpression member)
{
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a method, not a property.",
propertyLambda.ToString()));
}
if (member.Member is not PropertyInfo propInfo)
{
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a field, not a property.",
propertyLambda.ToString()));
}
Type type = typeof(TSource);
if (propInfo.ReflectedType != null && type != propInfo.ReflectedType && !type.IsSubclassOf(propInfo.ReflectedType))
{
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a property that is not from type {1}.",
propertyLambda.ToString(),
type));
}
return propInfo;
}
パラメータsource
は、コンパイラがメソッド呼び出し時に型推論を行えるようにするために使用されます。次のようにすることができます。
var propertyInfo = GetPropertyInfo(someUserObject, u => u.UserID);