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

问题描述 投票:0回答:1
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# .net .net-4.0 closures
1个回答
1
投票

您不能简单地将闭包强制转换为具体类型,因为事先不知道名称,并且(非常有意)是在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;
© www.soinside.com 2019 - 2024. All rights reserved.