我有这个:
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 个类型参数”)。
我该怎么做?
一种方法是只采取
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)