访问func委托中的闭包变量c#

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了访问func委托中的闭包变量c#相关的知识,希望对你有一定的参考价值。

public Func<string, string> getdel()
{
    int i = 1;
    int j = 1;
    return s => s.ToUpper() + (i++);
}

public Func<string, string> aa = getdel()
aa("Test");

在delegate的Target属性中返回Closure变量的值。如何访问闭包变量值?如下所示:

((appropriatecast)(aa.Target)).i

当在委托中遇到断点时,我可以看到i的值但是在代码中这个appropriatecast是编译器生成的<> c__DisplayClass2_0(从IL反汇编程序验证)。

答案

您不能简单地将闭包强制转换为具体类型,因为事先不知道名称,并且(非常有意)是在C#中无效的名称。

您可以尝试使用dynamic访问其字段:

dynamic target = aa.Target;
int value = target.i;

或反思:

var closureType = aa.Target.GetType();
var field = closureType.GetField("i");
var value = (int)field.GetValue(aa.Target);

但是,我强烈反对依赖于此,因为无法保证编译器决定生成闭包并命名变量的方式。不同的编译器版本或对lambda的看似无关的修改可能会产生非常不同的结果,导致此代码中断。

如果您可以控制生成委托的代码,我建议您使用可公开访问的字段/属性来定义自己的类,而不是使用lambda并尝试使用编译器生成的闭包。

public class Foo
{
    public int i;    
    public string Bar(string s) => s.ToUpper() + (i++);
}
var foo = new Foo();
Func<string, string> aa = foo.Bar;

以上是关于访问func委托中的闭包变量c#的主要内容,如果未能解决你的问题,请参考以下文章

JS---闭包

在直接调用委托的情况下如何减轻“访问修改的闭包”

对闭包的误区

python中的闭包

Python嵌套函数和闭包

关于 C# 闭包