LoginSignup
2
2

More than 5 years have passed since last update.

C#でコンパイラが生成した要素はCompilerGeneratedAttributeがつく

Posted at

C#の匿名型やプロパティ、イテレーターなんかの言語機能は、コンパイラが内部的にフィールド、プロパティ、メソッド、クラスもろもろを生成します。

そのコンパイラが生成したフィールド、プロパティ、メソッド、クラスには、CompilerGeneratedという属性が付与されます。

SharpLabで、どういう風に付与されるか見てみましょう。

こんなC#のコードがあったら、

using System.Collections.Generic;
using System.Linq;

public class Person {
    public string FirstName { get; }
    public string LastName { get; }

    public Person(string firstName, string lastName)
        => (FirstName, LastName) = (firstName, lastName);
}

public class Program {
    public static void Main() {
        var array = new int[] {3, 1, 4, 1, 5, 9, 2};

        var result = array.Select(it => new { squared = it * it, cubed = it * it * it});
    }

    public static IEnumerable<int> Yield() {
        yield return 0;
        yield return 1;
        yield return 2;
    }
}

実際は、CompilerGeneratedが付与されたこんな感じになります。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[CompilerGenerated]
[DebuggerDisplay("\\{ squared = {squared}, cubed = {cubed} }", Type = "<Anonymous Type>")]
internal sealed class <>f__AnonymousType0<<squared>j__TPar, <cubed>j__TPar>
{
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly <squared>j__TPar <squared>i__Field;

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly <cubed>j__TPar <cubed>i__Field;

    public <squared>j__TPar squared => <squared>i__Field;

    public <cubed>j__TPar cubed => <cubed>i__Field;

    [DebuggerHidden]
    public <>f__AnonymousType0(<squared>j__TPar squared, <cubed>j__TPar cubed)
    {
        <squared>i__Field = squared;
        <cubed>i__Field = cubed;
    }

    [DebuggerHidden]
    public override bool Equals(object value)
    {
        <>f__AnonymousType0<<squared>j__TPar, <cubed>j__TPar> anon = value as <>f__AnonymousType0<<squared>j__TPar, <cubed>j__TPar>;
        return anon != null && EqualityComparer<<squared>j__TPar>.Default.Equals(<squared>i__Field, anon.<squared>i__Field) && EqualityComparer<<cubed>j__TPar>.Default.Equals(<cubed>i__Field, anon.<cubed>i__Field);
    }

    [DebuggerHidden]
    public override int GetHashCode()
    {
        return (405075540 * -1521134295 + EqualityComparer<<squared>j__TPar>.Default.GetHashCode(<squared>i__Field)) * -1521134295 + EqualityComparer<<cubed>j__TPar>.Default.GetHashCode(<cubed>i__Field);
    }

    [DebuggerHidden]
    public override string ToString()
    {
        object[] obj = new object[2];
        <squared>j__TPar val = <squared>i__Field;
        ref <squared>j__TPar reference = ref val;
        <squared>j__TPar val2 = default(<squared>j__TPar);
        object obj2;
        if (val2 == null)
        {
            val2 = reference;
            reference = ref val2;
            if (val2 == null)
            {
                obj2 = null;
                goto IL_0046;
            }
        }
        obj2 = reference.ToString();
        goto IL_0046;
        IL_0046:
        obj[0] = obj2;
        <cubed>j__TPar val3 = <cubed>i__Field;
        ref <cubed>j__TPar reference2 = ref val3;
        <cubed>j__TPar val4 = default(<cubed>j__TPar);
        object obj3;
        if (val4 == null)
        {
            val4 = reference2;
            reference2 = ref val4;
            if (val4 == null)
            {
                obj3 = null;
                goto IL_0081;
            }
        }
        obj3 = reference2.ToString();
        goto IL_0081;
        IL_0081:
        obj[1] = obj3;
        return string.Format(null, "{{ squared = {0}, cubed = {1} }}", obj);
    }
}
public class Person
{
    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly string <FirstName>k__BackingField;

    [CompilerGenerated]
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private readonly string <LastName>k__BackingField;

    public string FirstName
    {
        [CompilerGenerated]
        get
        {
            return <FirstName>k__BackingField;
        }
    }

    public string LastName
    {
        [CompilerGenerated]
        get
        {
            return <LastName>k__BackingField;
        }
    }

    public Person(string firstName, string lastName)
    {
        <FirstName>k__BackingField = firstName;
        <LastName>k__BackingField = lastName;
    }
}
public class Program
{
    [Serializable]
    [CompilerGenerated]
    private sealed class <>c
    {
        public static readonly <>c <>9 = new <>c();

        public static Func<int, <>f__AnonymousType0<int, int>> <>9__0_0;

        internal <>f__AnonymousType0<int, int> <Main>b__0_0(int it)
        {
            return new <>f__AnonymousType0<int, int>(it * it, it * it * it);
        }
    }

    [CompilerGenerated]
    private sealed class <Yield>d__1 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IDisposable, IEnumerator
    {
        private int <>1__state;

        private int <>2__current;

        private int <>l__initialThreadId;

        int IEnumerator<int>.Current
        {
            [DebuggerHidden]
            get
            {
                return <>2__current;
            }
        }

        object IEnumerator.Current
        {
            [DebuggerHidden]
            get
            {
                return <>2__current;
            }
        }

        [DebuggerHidden]
        public <Yield>d__1(int <>1__state)
        {
            this.<>1__state = <>1__state;
            <>l__initialThreadId = Environment.CurrentManagedThreadId;
        }

        [DebuggerHidden]
        void IDisposable.Dispose()
        {
        }

        private bool MoveNext()
        {
            switch (<>1__state)
            {
                default:
                    return false;
                case 0:
                    <>1__state = -1;
                    <>2__current = 0;
                    <>1__state = 1;
                    return true;
                case 1:
                    <>1__state = -1;
                    <>2__current = 1;
                    <>1__state = 2;
                    return true;
                case 2:
                    <>1__state = -1;
                    <>2__current = 2;
                    <>1__state = 3;
                    return true;
                case 3:
                    <>1__state = -1;
                    return false;
            }
        }

        bool IEnumerator.MoveNext()
        {
            //ILSpy generated this explicit interface implementation from .override directive in MoveNext
            return this.MoveNext();
        }

        [DebuggerHidden]
        void IEnumerator.Reset()
        {
            throw new NotSupportedException();
        }

        [DebuggerHidden]
        IEnumerator<int> IEnumerable<int>.GetEnumerator()
        {
            if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
            {
                <>1__state = 0;
                return this;
            }
            return new <Yield>d__1(0);
        }

        [DebuggerHidden]
        IEnumerator IEnumerable.GetEnumerator()
        {
            return System.Collections.Generic.IEnumerable<System.Int32>.GetEnumerator();
        }
    }

    public static void Main()
    {
        int[] obj = new int[7];
        RuntimeHelpers.InitializeArray(obj, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
        int[] source = obj;
        IEnumerable<<>f__AnonymousType0<int, int>> enumerable = source.Select(<>c.<>9__0_0 ?? (<>c.<>9__0_0 = <>c.<>9.<Main>b__0_0));
    }

    [IteratorStateMachine(typeof(<Yield>d__1))]
    public static IEnumerable<int> Yield()
    {
        return new <Yield>d__1(-2);
    }
}
[CompilerGenerated]
internal sealed class <PrivateImplementationDetails>
{
    [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 28)]
    private struct __StaticArrayInitTypeSize=28
    {
    }

    internal static readonly __StaticArrayInitTypeSize=28 572ED8A201DB898C54AEE5E176701DF001029BE8/* Not supported: data(03 00 00 00 01 00 00 00 04 00 00 00 01 00 00 00 05 00 00 00 09 00 00 00 02 00 00 00) */;
}
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2