使用lambdaexpression式获取属性名称和types
我正在尝试编写一个函数,使用如下所示的语法来提取属性的名称和types:
private class SomeClass { Public string Col1; } PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>(); propertyMapper.MapProperty(x => x.Col1)
有什么办法可以将这个属性传递给函数,而不会对这个语法做任何重大的修改?
我想获得属性名称和属性types。
所以在下面的例子中,我想要检索
Name = "Col1"
和Type = "System.String"
谁能帮忙?
这里有足够的例子使用expression式来获取一个属性或字段的名称,让你开始:
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
的简单(Program p) => p.Name
实际上涉及了相当多的工作(并且可能花费大量的时间)。 考虑caching结果,而不是频繁地调用方法。
我发现这非常有用。
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; } }
我让这个小class遵循原来的要求。 如果你需要财产的名字,你可以这样使用它:
PropertyMapper<SomeClass> propertyMapper = new PropertyMapper<SomeClass>(); string name = propertyMapper.PropertyName(x => x.Col1);
我只是认为我会把这个build立在以前的方法上。
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和C#6.0你可以简单地使用nameof。
这可以很容易地在C#6中完成。要获取属性名称的操作符名称。
nameof(User.UserId)
并得到属性使用typeof运算符。
typeof(User.UserId)