Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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) */;
}
RyotaMurohoshi
プログラミングが大好きで、 C#が大好きで、 .NETが大好きで、 LINQが大好きで、 JVM言語が大好きで、 ゲームで遊ぶことが大好きで、 ゲーム開発が大好きで、 頑張るのが大好きで、 Unityが大好きだったから...!
http://mrstar-memo.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした