lambda表达式是否使用反射?

时间:2012-11-20 15:03:20

标签: c# reflection lambda

为了确保我理解有人可以确认lambda表达式使用反射吗?

3 个答案:

答案 0 :(得分:4)

他们可以,但他们不是必须的。如果将它们编译为委托,则不需要进行反射:但是,如果将它们编译为ab表达式树,则表达式树绝对基于反射。表达式树的某些部分可以直接从元数据标记(ldtoken)组装 - 特别是方法(包括运算符和getter / setter,以及类型) - 但是其他一些部分不能。这包括属性(PropertyInfo无法通过令牌加载) - 因此编译的lambda的IL可以明确包含GetProperty等。

但是无论是加载(标记还是反射),表达树都是以反射(MemberInfo等)表示。这可能稍后编译,或者可能由提供商进行分析。

为了帮助提高性能,表达式编译器可以缓存部分或全部表达式树,并重新使用它。

答案 1 :(得分:1)

Lambda表达式由编译器转换为匿名函数或表达式树。由于反射只能在运行时执行,因此在考虑编译器在任何一种情况下对它们的作用时,它根本不会进入图像。

在运行时,lambda表达式可能会导致在非常特定的情况下使用反射:

对于匿名函数:如果你编写一个明确反映某事物的匿名函数,那么lambda将在调用时执行该反射。这当然就像你在“正确”的方法中反思一样。

对于表达式树(即某些TDelegate类型Expression<TDelegate>的值):在使用IQueryable时在运行时使用它们可能会导致{{3}使用反射}。例如,假设你这样做:

var user = new User { Id = 42 };
var posts = Queryable.Posts.Where(p => p.UserId == user.Id);

posts即将实现时,查询提供商会发现它必须找到UserId等于变量Id的{​​{1}}的帖子。由于该id在运行时具有特定的已知值,因此查询提供程序需要将其从user中删除。它可能决定这样做的一种方式是通过反思。

答案 2 :(得分:-1)

lambda表达式只是用于创建委托的编译器语法糖。这里没有使用反射。