由于我不是编程语言的专家,我很清楚这可能是一个愚蠢的问题,但是尽我所能告诉C#通过将匿名方法和闭包转换为匿名嵌套类的实例方法来处理它们[1]。 ,实例化此类,然后将委托指向这些实例方法。
看来该匿名类只能实例化一次(或者我对此是否错?),那么为什么不将匿名类设为静态呢?
[1]实际上,似乎有一个用于闭包的类和一个用于不捕获任何变量的匿名方法的类,我不完全了解这两个类的基本原理。
我很清楚这可能是一个愚蠢的问题
不是。
C#通过使匿名方法和闭包成为匿名嵌套类的实例方法,实例化此类,然后将委托指向这些实例方法,来处理匿名方法和闭包。
C#有时会这样做。
看来该匿名类只能实例化一次(或者我对此是否错?),那么为什么不将匿名类设为静态呢?
在合法的情况下,C#会帮助您更好。它根本不构成闭包类。它使匿名函数成为当前类的静态函数。
是的,你错了。如果仅分配一次委托就可以解决问题,C#确实可以解决。
(严格地说,这并不是完全正确的;在某些模糊的情况下,未实现此优化。但在大多数情况下,是没有实现的。)
实际上,似乎有一个用于闭包的类和一个用于不捕获任何变量的匿名方法的类,我不完全了解这两个类的基本原理。
您已经将手指放在您没有充分理解的事物上。
让我们看一些例子:
class C1
{
Func<int, int, int> M()
{
return (x, y) => x + y;
}
}
这可以生成为
class C1
{
static Func<int, int, int> theFunction;
static int Anonymous(int x, int y) { return x + y; }
Func<int, int, int> M()
{
if (C1.theFunction == null) C1.theFunction = C1.Anonymous;
return C1.theFunction;
}
}
不需要新的课程。
现在考虑:
class C2
{
static int counter = 0;
int x = counter++;
Func<int, int> M()
{
return y => this.x + y;
}
}
您知道为什么不能使用静态函数生成它吗?静态函数将需要访问this.x,但是静态函数中的this在哪里?没有一个。
因此,这必须是一个实例函数:
class C2
{
static int counter = 0;
int x = counter++;
int Anonymous(int y) { return this.x + y; }
Func<int, int> M()
{
return this.Anonymous;
}
}
同样,我们不能再将委托缓存在一个静态字段中。你明白为什么吗?
练习:可以将委托缓存在实例字段中吗?如果否,那么是什么阻止了这种行为合法化?如果是,那么反对实现这种“优化”的一些理由是什么?
现在考虑:
class C3
{
static int counter = 0;
int x = counter++;
Func<int> M(int y)
{
return () => x + y;
}
}
不能将其作为C3的实例函数生成。你明白为什么吗?我们需要能够说:
var a = new C3();
var b = a.M(123);
var c = b(); // 123 + 0
var d = new C3();
var e = d.M(456);
var f = e(); // 456 + 1
var g = a.M(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<int> M(int y)
{
var locals = new Locals();
locals.__this = this;
locals.__y = y;
return locals.Anonymous;
}
}
练习:现在假设我们有C4<T>
一个通用方法M<U>
,其中lambda在类型T和U的变量上关闭。描述现在必须发生的代码生成。
练习:现在假设我们有M返回一个代表的元组,一个是()=>x + y
,另一个是(int newY)=>{ y = newY; }
。描述两个委托的代码生成。
练习:现在假设M(int y)
返回类型Func<int, Func<int, int>>
,我们返回a => b => this.x + y + z + a + b
。描述代码。
练习:假设同时关闭了一个lambdathis
和一个local进行了base
非虚拟调用。base
出于安全考虑,从类型内部的代码而不是直接在虚拟方法的类型层次结构中进行调用是非法的。描述在这种情况下如何生成可验证的代码。
练习:将它们放在一起。您如何使用多个getter和setter lambda来对所有嵌套lambda进行编码生成,而所有locals都由在base
调用类和方法范围内的泛型类型进行参数化?因为那是我们实际上必须解决的问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句