This project is read-only.
2
Vote

Codegen for closures in member initializers

description

Currently, code like this:
using System;

class C {
    Action a = () => Console.WriteLine();
    
    public C() { }
    public C(int x) { }
    public C(byte x) { }
    public C(sbyte x) { }
    public C(ushort x) { }
    public C(ulong x) { }
}
Compiles into:
internal class C
{
    private Action a;
    [CompilerGenerated]
    private static Action CS$<>9__CachedAnonymousMethodDelegate1;
    [CompilerGenerated]
    private static Action CS$<>9__CachedAnonymousMethodDelegate3;
    [CompilerGenerated]
    private static Action CS$<>9__CachedAnonymousMethodDelegate5;
    [CompilerGenerated]
    private static Action CS$<>9__CachedAnonymousMethodDelegate7;
    [CompilerGenerated]
    private static Action CS$<>9__CachedAnonymousMethodDelegate9;
    [CompilerGenerated]
    private static Action CS$<>9__CachedAnonymousMethodDelegate11;
    public C()
    {
        Action arg_1C_1;
        if (arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate1 == null)
        {
            arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate1 = new Action(null.<.ctor>b__0);
        }
        this.a = arg_1C_1;
        base(); // This is not valid C#, but it represents the IL correctly.

    }
    public C(int x)
    {
        Action arg_1C_1;
        if (arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate3 == null)
        {
            arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate3 = new Action(null.<.ctor>b__2);
        }
        this.a = arg_1C_1;
        base(); // This is not valid C#, but it represents the IL correctly.

    }
    public C(byte x)
    {
        Action arg_1C_1;
        if (arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate5 == null)
        {
            arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate5 = new Action(null.<.ctor>b__4);
        }
        this.a = arg_1C_1;
        base(); // This is not valid C#, but it represents the IL correctly.

    }
    public C(sbyte x)
    {
        Action arg_1C_1;
        if (arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate7 == null)
        {
            arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate7 = new Action(null.<.ctor>b__6);
        }
        this.a = arg_1C_1;
        base(); // This is not valid C#, but it represents the IL correctly.

    }
    public C(ushort x)
    {
        Action arg_1C_1;
        if (arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate9 == null)
        {
            arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate9 = new Action(null.<.ctor>b__8);
        }
        this.a = arg_1C_1;
        base(); // This is not valid C#, but it represents the IL correctly.

    }
    public C(ulong x)
    {
        Action arg_1C_1;
        if (arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate11 == null)
        {
            arg_1C_1 = C.CS$<>9__CachedAnonymousMethodDelegate11 = new Action(null.<.ctor>b__10);
        }
        this.a = arg_1C_1;
        base(); // This is not valid C#, but it represents the IL correctly.

    }
    [CompilerGenerated]
    private static void ctor>b__0(object obj)
    {
        Console.WriteLine();
    }
    [CompilerGenerated]
    private static void ctor>b__2(object obj)
    {
        Console.WriteLine();
    }
    [CompilerGenerated]
    private static void ctor>b__4(object obj)
    {
        Console.WriteLine();
    }
    [CompilerGenerated]
    private static void ctor>b__6(object obj)
    {
        Console.WriteLine();
    }
    [CompilerGenerated]
    private static void ctor>b__8(object obj)
    {
        Console.WriteLine();
    }
    [CompilerGenerated]
    private static void ctor>b__10(object obj)
    {
        Console.WriteLine();
    }
}
Can you solve this redundancy? For example, have some kind of identity for every closure in user code and preserve it while transforming member initializers into constructor's code...

comments