表达式捕获闭包,当它应该引用类实例时
本文关键字:引用 实例 闭包 表达式 | 更新日期: 2023-09-27 18:12:17
我有一种情况,代码在两个不同的开发盒上编译时表现不同。我不知道为什么。我不知道什么关键词能最好地描述这个问题。
当Rabbit在一个box源上被调用时,它的值为
{() => Program.Names}
在另一个方框源的值为
{() => value(NPC.Program+<>c__DisplayClass1_0).Names}
无论在什么计算机上编译,Hole都具有该值。
{() => value(NPC.Program+<>c__DisplayClass1_0).closure}
我想弄清楚为什么一台机器有类的表达式,而另一台机器在调用Rabbit时有闭包的值。我还想知道有没有办法控制它。谢谢!
class Program
{
public static ObservableCollection<string> Names = new ObservableCollection<string>();
static void Main(string[] args)
{
string closure = "closure";
if(closure.Length > 0)
{
GoingDown(p => {
closure.ToString();
Names = new ObservableCollection<string>();
Rabbit(() => Names);
Hole(() => closure);
}, closure);
}
}
public static void Rabbit<SourceType>(Expression<Func<ObservableCollection<SourceType>>> source)
{
"Testing".ToString();
}
public static void Hole(Expression<Func<object>> source)
{
"Testing".ToString();
}
public static void GoingDown(Action<object> a, object target)
{
Action b = () =>
{
a(target);
};
b();
}
}
首先:正如注释所指出的,了解。net/c#/etc的哪些版本产生了哪些行为是有帮助的。
第二个问题:如果是正确的,那么哪个行为是正确的?说明书上没有说。它为编译器提供了广泛的自由度,可以根据需要将lambdas实现为委托和表达式树。
第三:哪个更好?显然,没有必要将静态字段名复制到闭包类中。我希望生成非闭包版本;我怀疑生成闭包的版本有bug。也许这个错误在不显示闭包语义的版本中已经被修复了。
第四:你能控制这种行为吗?显然是的,你有一台有不良行为的机器和一台没有,所以你可以简单地选择将有不良行为的机器沉入海底,而使用有理想行为的机器。
或者:没有要求你使用编译器的lambda语义实现。lambda是一种语法糖;如果你不喜欢编译器给你的表达式树,你可以自由地"手工"生成表达式树。