Вы можете сделать это:
void Main()
{
Console.WriteLine(MyHtml.DescriptionFor2<Test>((t) => t.StringMember));
Console.WriteLine(MyHtml.DescriptionFor2<Test>((t) => t.BooleanMember));
Console.WriteLine(MyHtml.DescriptionFor2<Test>((t) => t.IntegerMember));
}
public class Test
{
[Description("This is a string member")]
public string StringMember { get; set; }
[Description("This is a boolean member")]
public bool BooleanMember { get; set; }
[Description("This is a integer member")]
public int IntegerMember { get; set; }
}
public static class MyHtml
{
public static string DescriptionFor2<T>(Expression<Func<T, dynamic>> expression)
{
var result = string.Empty;
var member = GetMemberExpression(expression)?.Member?.Name;
if (member != null)
{
var property = typeof(T).GetProperty(member);
if (property != null)
{
var attr = property
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.Cast<DescriptionAttribute>()
.FirstOrDefault();
result = attr?.Description ?? string.Empty;
}
}
return result;
}
private static MemberExpression GetMemberExpression<T>(Expression<Func<T, dynamic>> expression)
{
var member = expression.Body as MemberExpression;
var unary = expression.Body as UnaryExpression;
return member ?? (unary != null ? unary.Operand as MemberExpression : null);
}
}
public class DescriptionAttribute : Attribute
{
public string Description { get; set; }
public DescriptionAttribute(string description)
{
Description = description;
}
}
Это включает получение тела выражения в качестве члена и использование его имени для разрешения свойства объекта.Тип данных dynamic
используется для избавления от параметра второго типа, однако вы также можете определить его явно для лучшего обнаружения ошибок во время компиляции:
public static string DescriptionFor2<T, U>(Expression<Func<T, U>> expression)
и вызова его:
MyHtml.DescriptionFor2<Test, string>((t) => t.StringMember);
MyHtml.DescriptionFor2<Test, bool>((t) => t.BooleanMember);
MyHtml.DescriptionFor2<Test, int>((t) => t.IntegerMember);
РЕДАКТИРОВАТЬ: отредактированный ответ, поскольку первоначальное решение не работало для типов значений, см. Выражение для членов типа приводит к различным выражениям (MemberExpression, UnaryExpression)