通过反射获取DescriptionAttribute

问题描述 投票:0回答:1

我有这个:

public class Demo
{
  [Description("Hello World!")]
  public int SomeProp { get; set; }
}

我想要描述。所以我写了这个:

public string? GetDescription<TType, TProperty>(Expression<Func<TType, TProperty>> expression)
  where TType : class
{
  var memberName  = ((MemberExpression)expression.Body).Member.Name;
  var description = typeof(TType).GetMember(memberName).First()
                    .GetCustomAttribute<DescriptionAttribute>()
                    ?.Description;
  return description;
}

可以这样使用:

var description = GetDescription<Demo, string>(x => x.SomeProp);

但我想要的是这个:

var description = GetDescription<Demo>(x => x.SomeProp);   // no TProperty

我希望类型推断能够推断

TProperty
并简化调用点,但没有它我就无法编译(“使用泛型方法需要 2 个类型参数”)。

我该怎么做?

c# .net linq generics reflection
1个回答
0
投票

一种方法是只采取

Func<TType, object>
。当属性类型不是
object
时,根表达式节点将是
Convert
表达式,因此您只需检查即可。

public static string? GetDescription<TType>(Expression<Func<TType, object>> expression)
  where TType : class
{
    var body = expression.Body;
    string memberName;
    if (body is MemberExpression exp1) {
        memberName = exp1.Member.Name;
    } else if (body is UnaryExpression unary && 
               unary.NodeType == ExpressionType.Convert &&
               unary.Operand is MemberExpression exp2) {
        memberName = exp2.Member.Name;
    } else {
        throw new NotSupportedException();
    }
    var description = typeof(TType).GetMember(memberName).First()
                    .GetCustomAttribute<DescriptionAttribute>()
                    ?.Description;
    return description;
}

或者,您可以更改使用站点并显式写入 lambda 的参数类型,而不是显式写入

GetDescription
的类型参数。

GetDescription((Demo x) => x.SomeProp)
© www.soinside.com 2019 - 2024. All rights reserved.