What is the lifetime of a delegate created by a lambda in C#?(由 C# 中的 lambda 创建的委托的生命周期是多少?)
问题描述
Lambda 很好,因为它们提供 简洁性和局部性 和 另一种封装形式.不必编写仅在一次可以使用 lambda 时使用的函数.
Lambdas are nice, as they offer brevity and locality and an extra form of encapsulation. Instead of having to write functions which are only used once you can use a lambda.
虽然想知道它们是如何工作的,但我直觉地认为它们可能只创建一次.这启发了我创建一个解决方案,允许 限制通过使用 lambda 作为创建它的范围的标识符,将类成员的范围超出私有到一个特定范围.
While wondering how they worked, I intuitively figured they are probably only created once. This inspired me to create a solution which allows to restrict the scope of a class member beyond private to one particular scope by using the lambda as an identifier of the scope it was created in.
这个实现工作,虽然可能有点矫枉过正(仍在研究它),证明我的假设是正确的.
This implementation works, although perhaps overkill (still researching it), proving my assumption to be correct.
一个较小的例子:
class SomeClass
{
public void Bleh()
{
Action action = () => {};
}
public void CallBleh()
{
Bleh(); // `action` == {Method = {Void <SomeClass>b__0()}}
Bleh(); // `action` still == {Method = {Void <SomeClass>b__0()}}
}
}
lambda 会返回一个新实例,还是保证始终相同?
Would the lambda ever return a new instance, or is it guaranteed to always be the same?
推荐答案
根据您在这里的问题和您对 Jon 的回答的评论,我认为您混淆了很多事情.为了确保清楚:
Based on your question here and your comment to Jon's answer I think you are confusing multiple things. To make sure it is clear:
- 为给定 lambda 支持委托的方法始终相同.
- 允许在词法上出现两次的相同"lambda 的委托支持方法是相同的,但实际上不是em> 在我们的实现中也是如此.
- 为给定 lambda 创建的 delegate 实例 可能始终相同,也可能不同,这取决于编译器缓存它的智能程度.
- The method that backs the delegate for a given lambda is always the same.
- The method that backs the delegate for "the same" lambda that appears lexically twice is permitted to be the same, but in practice is not the same in our implementation.
- The delegate instance that is created for a given lambda might or might not always be the same, depending on how smart the compiler is about caching it.
所以如果你有类似的东西:
So if you have something like:
for(i = 0; i < 10; ++i)
M( ()=>{} )
那么每次调用 M 时,你都会得到委托的相同的实例,因为编译器很聪明并且会生成
then every time M is called, you get the same instance of the delegate because the compiler is smart and generates
static void MyAction() {}
static Action DelegateCache = null;
...
for(i = 0; i < 10; ++i)
{
if (C.DelegateCache == null) C.DelegateCache = new Action ( C.MyAction )
M(C.DelegateCache);
}
如果你有
for(i = 0; i < 10; ++i)
M( ()=>{this.Bar();} )
然后编译器生成
void MyAction() { this.Bar(); }
...
for(i = 0; i < 10; ++i)
{
M(new Action(this.MyAction));
}
您每次都会使用相同的方法获得一个新的委托.
You get a new delegate every time, with the same method.
编译器被允许生成(但实际上此时并没有)
The compiler is permitted to (but in fact does not at this time) generate
void MyAction() { this.Bar(); }
Action DelegateCache = null;
...
for(i = 0; i < 10; ++i)
{
if (this.DelegateCache == null) this.DelegateCache = new Action ( this.MyAction )
M(this.DelegateCache);
}
在这种情况下,如果可能,您将始终获得相同的委托实例,并且每个委托都将由相同的方法支持.
In that case you would always get the same delegate instance if possible, and every delegate would be backed by the same method.
如果你有
Action a1 = ()=>{};
Action a2 = ()=>{};
然后在实践中编译器将其生成为
Then in practice the compiler generates this as
static void MyAction1() {}
static void MyAction2() {}
static Action ActionCache1 = null;
static Action ActionCache2 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
if (ActionCache2 == null) ActionCache2 = new Action(MyAction2);
Action a2 = ActionCache2;
但是编译器被允许检测到两个 lambda 是相同的并生成
However the compiler is permitted to detect that the two lambdas are identical and generate
static void MyAction1() {}
static Action ActionCache1 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
Action a2 = ActionCache1;
现在清楚了吗?
这篇关于由 C# 中的 lambda 创建的委托的生命周期是多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:由 C# 中的 lambda 创建的委托的生命周期是多少?
基础教程推荐
- SSE 浮点算术是否可重现? 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- MS Visual Studio .NET 的替代品 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- c# Math.Sqrt 实现 2022-01-01