从linq表达式中检索信息时是否使用了reflection?

我有以下扩展方法:

public static string ToPropertyName(this Expression<Func> propertyExpression) { if (propertyExpression == null) return null; string propName; MemberExpression propRef = (propertyExpression.Body as MemberExpression); UnaryExpression propVal = null; // -- handle ref types if (propRef != null) propName = propRef.Member.Name; else { // -- handle value types propVal = propertyExpression.Body as UnaryExpression; if (propVal == null) throw new ArgumentException("The property parameter does not point to a property", "property"); propName = ((MemberExpression)propVal.Operand).Member.Name; } return propName; } 

我在传递属性名而不是字符串时使用linq表达式来提供强类型,我使用此函数以字符串forms检索属性的名称。 这种方法是否使用reflection?

我问的理由是这个方法在我们的代码中使用了很多,我希望它足够快。

据我所知,reflection并不涉及某种动态类型内省在幕后发生的意义。 但是, System.Reflection中的Type (如TypePropertyInfoSystem.Linq.Expressions命名空间中的类型一起使用。 它们仅被编译器用于描述作为抽象语法树(AST)传递给您的方法的任何Func 。 由于从Func到表达式树的转换是由编译器完成的,而不是在运行时,因此只描述了lambda的静态方面。

请记住,在运行时从lambda构建此表达式树(复杂对象图)可能需要比简单地传递属性名称字符串(单个对象)更长的时间,因为需要实例化更多对象(数量取决于复杂性) lambda传递给你的方法),但同样,没有涉及someObject.GetType()动态类型检查。

例:

这篇MSDN文章显示了以下lambda表达式:

 Expression> lambda1 = num => num < 5; 

由编译器转换为这样的东西:

 ParameterExpression numParam = Expression.Parameter(typeof(int), "num"); ConstantExpression five = Expression.Constant(5, typeof(int)); BinaryExpression numLessThanFive = Expression.LessThan(numParam, five); Expression> lambda1 = Expression.Lambda>( numLessThanFive, new ParameterExpression[] { numParam }); 

除此之外,没有别的事情发生。 这是对象图,然后可以传递给您的方法。

由于您的方法命名是ToPropertyName ,我想您正在尝试获取类的某个特定属性的类型名称。 您是否对Expression>方法进行了基准测试? 创建表达式的成本非常大,因为您的方法是静态的,我看到您也没有缓存成员表达式。 换句话说,即使表达方法不使用reflection,成本也可能很高。 看到这个问题: 如何将C#属性名称作为带reflection的字符串? 你有另一种方法:

 public static string GetName(this T item) where T : class { if (item == null) return string.Empty; return typeof(T).GetProperties()[0].Name; } 

您可以使用它来获取属性或变量的名称,如下所示:

 new { property }.GetName(); 

要进一步加快速度,您需要缓存成员信息。 如果你拥有的绝对是Func那么你的方法适合。 另请参见: 基于lambda表达式的reflection与正常reflection

相关问题:将所有属性名称和相应的值放入字典中