简体   繁体   中英

Access closure variables in func delegate 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");

Closure variable's value is returned in Target property of delegate.How can I access the closure variable value?something like this:

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

When hitting breakpoint at delegate ,I can see the value of i but in code this appropriatecast is a <> c__DisplayClass2_0 that is compiler generated(verified from IL Disassembler).

You cannot simply cast the closure to its concrete type since the name isn't known beforehand and (quite intentionally) is a name that is invalid in C#.

You could try to access its fields either with dynamic :

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

or with reflection:

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

However, I'd strongly advise against relying on this as there are no guarantees about the way the compiler decides to generate the closure and name the variables. Different compiler versions or seemingly unrelated modifications to the lambda could produce very different results, causing this code to break.

If you have control over the code that generates the delegate, I would recommend defining your own class with a publicly accessible field/property instead of using a lambda and trying to fiddle around with the compiler generated closure.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM