为什么C#将匿名方法和闭包实现为实例方法,而不是静态方法?
因为我不是编程语言方面的专家,所以我很清楚这可能是一个愚蠢的问题,但我最好能告诉C#通过将它们变成匿名嵌套类的实例方法来处理匿名方法和闭包[1] ,实例化这个类,然后将委托指向那些实例方法。
看来这个匿名类只能被实例化一次(或者我错了吗?),那么为什么不让匿名类变为静态呢?
[1]实际上,看起来有一个闭包类和一个不捕获任何变量的匿名方法,我不完全理解其中的任何一个。
我很清楚这可能是一个愚蠢的问题
不是。
C#通过将匿名方法和闭包设置为匿名嵌套类的实例方法,实例化此类,然后将委托指向这些实例方法来处理匿名方法和闭包。
C# 有时会这样做 。
看来这个匿名类只能被实例化一次(或者我错了吗?),那么为什么不让匿名类变为静态呢?
如果这是合法的,C#会让你更好。 它根本不构成封闭类。 它使匿名函数成为当前类的静态函数。
是的,你错了。 在你只能分配一次委托的情况下,C# 确实可以逃脱它。
(严格来说,这并不完全正确;有一些模糊的情况没有实现这种优化。但是大多数情况下都是这样。)
实际上,看起来有一个闭包类和一个不捕获任何变量的匿名方法,我不完全理解其中的任何一个。
你已经把手指放在你没有充分理解的东西上。
我们来看一些例子:
class C1 { Func M() { return (x, y) => x + y; } }
这可以生成为
class C1 { static Func theFunction; static int Anonymous(int x, int y) { return x + y; } Func M() { if (C1.theFunction == null) C1.theFunction = C1.Anonymous; return C1.theFunction; } }
不需要新的课程。
现在考虑:
class C2 { static int counter = 0; int x = counter++; Func M() { return y => this.x + y; } }
你知道为什么用静态函数不能生成这个吗? 静态函数需要访问this.x但这在静态函数中的位置是什么? 没有一个。
所以这一个必须是一个实例函数:
class C2 { static int counter = 0; int x = counter++; int Anonymous(int y) { return this.x + y; } Func M() { return this.Anonymous; } }
此外,我们不能再将代理缓存在静态字段中; 你明白为什么吗?
练习 :委托可以缓存在实例字段中吗? 如果不是,那么是什么阻止了这种合法? 如果是,那么反对实施这种“优化”的一些论点是什么?
现在考虑:
class C3 { static int counter = 0; int x = counter++; Func M(int y) { return () => x + y; } }
这不能作为C3的实例函数生成; 你明白为什么吗? 我们需要能够说:
var a = new C3(); var b = aM(123); var c = b(); // 123 + 0 var d = new C3(); var e = dM(456); var f = e(); // 456 + 1 var g = aM(789); var h = g(); // 789 + 0
现在,代理人不仅需要知道this.x
的值,还需要知道传入的y
的值。必须将其存储在某处 ,因此我们将其存储在字段中。 但它不能是C3的一个领域,因为那么我们如何告诉b
使用123和g
来使用789作为y
的值? 它们具有相同的C3
实例,但y
两个不同的值。
class C3 { class Locals { public C3 __this; public int __y; public int Anonymous() { return this.__this.x + this.__y; } } Func M(int y) { var locals = new Locals(); locals.__this = this; locals.__y = y; return locals.Anonymous; } }
练习 :现在假设我们有C4
,其generics方法M
,其中lambda在T和U类型的变量上关闭。描述现在必须发生的codegen。
练习 :现在假设我们有M返回一个委托元组,一个是()=>x + y
而另一个是(int newY)=>{ y = newY; }
(int newY)=>{ y = newY; }
。 描述两位代表的codegen。
练习 :现在假设M(int y)
返回Func
,我们返回a => b => this.x + y + z + a + b
。 描述codegen。
练习 :假设lambda关闭了这两个并且本地执行base
非虚拟调用。 出于安全原因,从不直接在虚方法的类型层次结构中的类型内的代码进行base
调用是非法的。 描述在这种情况下如何生成可validation的代码。
练习 :把它们放在一起。 你如何为所有本地人使用getter和setter lambdas为多个嵌套lambda做codegen,由类和方法作用域的generics类型参数化,进行base
调用? 因为这是我们实际必须解决的问题 。
上述就是C#学习教程:为什么C#将匿名方法和闭包实现为实例方法,而不是静态方法?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/962706.html