Получить имя и тип свойства, используя выражение лямбда
Я пытаюсь написать функцию, которая вытащит имя свойства и тип, используя синтаксис, как показано ниже:
private class SomeClass
{
Public string Col1;
}
PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>();
propertyMapper.MapProperty(x => x.Col1)
Есть ли способ передать свойство через функцию без каких-либо серьезных изменений в этом синтаксисе?
Я хотел бы получить имя свойства и тип свойства.
Итак, в приведенном ниже примере я хотел бы получить
Name = "Col1"
и Type = "System.String"
Может ли кто-нибудь помочь?
Ответы
Ответ 1
Здесь достаточно примера использования Expressions, чтобы получить имя свойства или поля, чтобы вы начали:
public static MemberInfo GetMemberInfo<T, U>(Expression<Func<T, U>> expression)
{
var member = expression.Body as MemberExpression;
if (member != null)
return member.Member;
throw new ArgumentException("Expression is not a member access", "expression");
}
Код вызова будет выглядеть так:
public class Program
{
public string Name
{
get { return "My Program"; }
}
static void Main()
{
MemberInfo member = ReflectionUtility.GetMemberInfo((Program p) => p.Name);
Console.WriteLine(member.Name);
}
}
Слово предостережения, однако: простая формулировка (Program p) => p.Name
фактически включает в себя довольно много работы (и может принимать измеримые количества времени). Рассмотрите кэширование результата, а не часто вызывайте метод.
Ответ 2
Я нашел это очень полезным.
public class PropertyMapper<T>
{
public virtual PropertyInfo PropertyInfo<U>(Expression<Func<T, U>> expression)
{
var member = expression.Body as MemberExpression;
if (member != null && member.Member is PropertyInfo)
return member.Member as PropertyInfo;
throw new ArgumentException("Expression is not a Property", "expression");
}
public virtual string PropertyName<U>(Expression<Func<T, U>> expression)
{
return PropertyInfo<U>(expression).Name;
}
public virtual Type PropertyType<U>(Expression<Func<T, U>> expression)
{
return PropertyInfo<U>(expression).PropertyType;
}
}
Я сделал этот маленький класс, чтобы выполнить первоначальный запрос.
Если вам нужно имя свойства, вы можете использовать его следующим образом:
PropertyMapper<SomeClass> propertyMapper = new PropertyMapper<SomeClass>();
string name = propertyMapper.PropertyName(x => x.Col1);
Ответ 3
Это легко сделать в С# 6. Чтобы получить имя свойства, используйте имя оператора.
nameof(User.UserId)
и получить тип свойства use typeof.
typeof(User.UserId)
Ответ 4
Я просто подумал, что я поставил бы это здесь, чтобы опираться на предыдущий подход.
public static class Helpers
{
public static string PropertyName<T>(Expression<Func<T>> expression)
{
var member = expression.Body as MemberExpression;
if (member != null && member.Member is PropertyInfo)
return member.Member.Name;
throw new ArgumentException("Expression is not a Property", "expression");
}
}
Затем вы можете вызвать его следующим образом:
Helpers.PropertyName(() => TestModel.TestProperty);
Я также должен указать, что с VS 2015 и С# 6.0 вы можете просто использовать nameof.
https://msdn.microsoft.com/en-us/library/dn986596.aspx