C# の はメンバーのビットで構成されているため、フィールドを含むstruct
値型を持つことはできません。T
T
// Struct member 'T.m_field' of type 'T' causes a cycle in the struct layout
struct T { T m_field; }
私の理解では、上記のタイプのインスタンスはインスタンス化できない* ということです。インスタンス化しようとすると、インスタンス化/割り当ての無限ループが発生します (スタック オーバーフローが発生すると思いますか? ** )。または、別の見方をすると、定義自体が意味をなさないということかもしれません。おそらく、これは「このステートメントは偽です」のような、自滅的なエンティティです。
しかし不思議なことに、このコードを実行すると、
BindingFlags privateInstance = BindingFlags.NonPublic | BindingFlags.Instance;
// Give me all the private instance fields of the int type.
FieldInfo[] int32Fields = typeof(int).GetFields(privateInstance);
foreach (FieldInfo field in int32Fields)
{
Console.WriteLine("{0} ({1})", field.Name, field.FieldType);
}
...次の出力が得られます。
m_value (System.Int32)
どうやら、私たちはここで「嘘」をつかれています***。もちろん、、などのプリミティブ型は、int
C double
# の奥深くで特別な方法で定義する必要があることは理解しています (システム内のすべての可能なユニットをそのシステムの観点から定義することはできません... できますか? いずれにしても、別のトピックです)。私はただ知りたいだけです何が起きてる。
System.Int32
型は(例えば)32ビット整数の格納を実際にどのように考慮するのでしょうか?より一般的には、値型(値の種類の定義として)に、型が自体?それはただ亀はずっと下にいる。
黒魔術?
*別の話ですが、これは値型(「インスタンス化」)を表す正しい言葉でしょうか?「参照のような」意味合いがあるように感じますが、それは私だけかもしれません。また、私は5月以前にもこの質問をしたことがあるのですが、もしそうなら、人々が何と答えたか忘れてしまいました。
**両方マルティン・ロイスそしてエリック・リパートこれは完全に正確ではないし、問題に対する適切な見方でもないと指摘しています。詳細については、彼らの回答を参照してください。
***OK、誰も嘘をついていないことはわかっています。私がこれを嘘だと思ったと示唆したかったわけではありません間違い; 当初私は、それが単純化しすぎているのではないかと疑っていました。考える)thecoopの回答、それは私にとってはずっと理にかなっています。
ベストアンサー1
私の知る限り、アセンブリに格納されているフィールド シグネチャ内には、'コア' プリミティブ型 (符号付き/符号なし整数、浮動小数点数 (および参照型で特殊なケースである文字列)) を表す特定のハードコードされたバイト パターンがあります。CLR は、これらをネイティブに処理する方法を知っています。シグネチャのビット パターンについては、CLR 仕様の Partition II、セクション 23.2.12 を参照してください。
BCL内の各プリミティブ構造体 ( など) 内には[mscorlib]System.Int32
その[mscorlib]System.Single
ネイティブ型の単一のフィールドがあり、構造体はその構成フィールドとまったく同じサイズであるため、各プリミティブ構造体はメモリ内のネイティブ型と同じビット パターンであり、そのため、CLR、C# コンパイラ、またはそれらの型を使用するライブラリによって、いずれとしても解釈できます。
C# ではint
、double
などは mscorlib 構造体の同義語であり、それぞれ CLR によってネイティブに認識される型のプリミティブ フィールドを持ちます。
(ここではさらに複雑な点があります。CLR 仕様では、「短縮形」を持つ型 (ネイティブ CLR 型) は常にint32
ではなくその短縮形 ( )としてエンコードする必要があると規定valuetype [mscorlib]System.Int32
されています。したがって、C# コンパイラはプリミティブ型についても認識しますが、C# コンパイラと CLR で、たとえばプリミティブ構造体のメソッド呼び出しに対して実行される正確なセマンティクスと特殊処理についてはよくわかりません)
したがって、ゲーデルの不完全性定理により、それを定義できるシステムの「外部」に何かが存在する必要があります。これが、CLR が 4 バイトをネイティブまたはC# からエイリアスされたint32
のインスタンスとして解釈できるようにするマジックです。[mscorlib]System.Int32