На самом деле вы не можете сделать это, если только вы не используете C # 3.0, в этом случае вам нужно полагаться на LINQ (эм, деревья выражений).
Что вы делаете, так это то, что вы создаете фиктивный метод для лямбда-выражения, который позволяет компилятору генерировать дерево выражений (компилятор выполняет проверку типов). Затем вы копаетесь в этом дереве, чтобы получить член. Вот так:
static FieldInfo GetField<TType, TMemberType>(
Expression<Func<TType, TMemberType>> accessor)
{
var member = accessor.Body as MemberExpression;
if (member != null)
{
return member.Member as FieldInfo;
}
return null; // or throw exception...
}
Дан следующий класс:
class MyClass
{
public int a;
}
Вы можете получить метаданные следующим образом:
// get FieldInfo of member 'a' in class 'MyClass'
var f = GetField((MyClass c) => c.a);
Со ссылкой на это поле вы можете затем выкопать любой атрибут обычным способом. то есть отражение.
static TAttribute GetAttribute<TAttribute>(
this MemberInfo member ) where TAttribute: Attribute
{
return member.GetCustomAttributes( typeof( TAttribute ), false )
.Cast<TAttribute>().FirstOrDefault<TAttribute>();
}
Теперь вы можете выкопать атрибут в любом поле чем-то, что в целом проверено компилятором. Это также работает с рефакторингом, если вы переименуете 'a', Visual Studio поймает это.
var attr = GetField((MyClass c) => c.a).GetAttribute<DisplayNameAttribute>();
Console.WriteLine(attr.DisplayName);
Там нет ни одной литеральной строки в этом коде.