私は列挙型が定数としてコンパイルされていることを理解しています。そのため、列挙型を変更すると大きな変化が生じます。なぜ私はEnumsが静的なreadonly変数が代わりに同じ方法でコンパイルされていないのだろうと思っていますか?なぜ列挙型は静的な値ではなく定数としてコンパイルされましたか?
答えて
これらはフィールドよりも効率的であるため、ILに直接埋め込むことができる場合と同じ方法でコンパイルする必要はありません。
[Enums]は、const値がロードされるのと同じ方法でロードされます。これらは、ILの に直接埋め込まれています。一方、フィールドは、パフォーマンスにいくらか影響を与えるフィールドロード命令 (ldsfld)を必要とします。したがって、列挙型は典型的な使用法ではconstと同じくらい速く です。フィールドはやや遅くなります。
(Source)
さて、パフォーマンスベースの決定だった。これはまさに私が探していたものです... "なぜ?"への答え。 –
はい。問題は「静的な読み込みの代わりに定数としてコンパイルされるのはなぜですか? ...基本的に、静的な読み込みの代わりに定数リテラルにするというデザインの決定はどうでしたか?私は間違っていないです場合 –
@my、読み取り専用インスタンスに設定され、インスタンス化 –
両方の回答は技術的には正しいものの、統計的に異なる定数(読取り専用)については説明がありません。 C#では、定数は常に速く読み取り専用よりも、その理由は非常にシンプルで、最高の小さなコード例で表現:
const int MyConstant = 10;
static readonly int MyReadonly = 20;
static void Main()
{
int result = MyConstant + MyReadonly;
// the above statement will be resolved to:
// int result = 10 + MyReadonly
}
コンパイル時に、コンパイラは、その定数の実際の値に定数へのすべての参照を置き換え。コンパイル時に定数をあらかじめ定義しなければならないので、そうすることができます。これは静的ではあるが実行時に実際に解決される静的読み取り値とは異なります。以下の例を見てみましょう:GB2132は、実際にこのコードを実行するように意図されているマシンに存在する場合、コンパイラが知る方法はありません
static readonly Encoding = Encoding.GetEncoding("GB2132");
。この値を解決する唯一の方法は、実行時です。 Staticは、値そのものがインスタンスの存続期間にバインドされていないことを保証し、読み取り専用で値が一度しか設定されないことを保証します。コンパイラがこのフィールドへの参照をコンパイル時に置き換える方法はありません。値を単に知ることができないからです。
論理的には、プリミティブ型だけを定数としてマークできます。
現在、列挙型の場合は非常に簡単です。列挙型は、整数値以上のものです。したがって、次のコード:
enum MyEnum
{
First,
Second,
Third
}
static void Main()
{
MyEnum test = MyEnum.First;
if (test == MyEnum.Second)
{
// whatever
}
}
はにコンパイラによって解決されます:ターンに一定のフィールドへの実際の参照を意味
const int MyEnum_First = 0;
const int MyEnum_Second = 1;
const int MyEnum_Third = 2;
static void Main()
{
int test = MyEnum_First;
if (test == MyEnum_Second)
{
// whatever
}
}
を作り、コンパイル時に既知の値に置き換えることができますコードの最終版は次のようになります。
static void Main()
{
int test = 0;
if (test == 1)
{
// whatever
}
}
恐ろしい説明、男 – ivowiblo
いやに設定できない定数と同じではありませんが、列挙型が変更を壊している理由の質問はありませんでしたが、することができますMicrosoftが静的な読み取り専用フィールドではなく定数としてそれらをコンパイルする理由を説明しました。彼らは、コンパイラはどちらかの道を行く機会があったことは、破壊の変更だろうと、疑問は、なぜ彼らが代わりに定数で行きましたし、誰かが単にパフォーマンス向上のために...それに答えました。 –
- 1. なぜ#列挙型の中に値を定義しますか?
- 2. なぜ 'Int32 value__'は列挙型メンバーとして表示されますか?
- 3. Javaの非静的な列挙型
- 4. 静的なvalueOf()メソッドのポイントは何ですか? (列挙型)
- 5. なぜMySQLのboolean型は列挙型ではなくtinyintにマップされますか?
- 6. phpmyadminが列挙型の値を作成しないのはなぜですか?
- 7. JavascriptをES6静的な列挙型のように外側に使用されるクラス内の列挙型は
- 8. なぜ列挙コンストラクタは、静的フィールドにアクセスすることができない
- 9. System.Net.Http.HttpMethodが列挙型ではなく、クラスであるのはなぜですか?
- 10. Doctrine列挙型で列挙されていない値を追加することはできませんか?
- 11. なぜtypedefは列挙型で使用されていますか?
- 12. は、なぜ、すべての列挙型は、列挙型<e>
- 13. Swiftでは、新しい変数を作成して列挙型に設定するのはなぜですか?
- 14. Resharperはこれらの列挙型が使用されていないと思うのはなぜですか?
- 15. なぜこの列挙型コードは静的フィールドへの不正な参照ですか?
- 16. 列挙値がEnumType.STRINGとしてではなく
- 17. 列挙型は静的ではありませんか?
- 18. 別の列挙型の基になる型として列挙型を使用できないのはなぜですか?
- 19. なぜ私は静的な最終変数を非静的なブロックで宣言していませんか?
- 20. 列挙型はモデルと見なされるべきですか?
- 21. 列挙型フィールドがシリアル化されているのはなぜですか?
- 22. Bashのこれらの例では、動的な型定義と静的な型指定がありますか?
- 23. はなぜWCFは有効なものとして列挙
- 24. なぜJson.Netは整数として列挙型の値を逆シリアル化し、有効なものとして受け入れますか?
- 25. static_castを使用しないで、厳密に型指定された列挙型を整数で初期化できるのはなぜですか?
- 26. なぜDの整数型は未定義ではなく固定されていますか?
- 27. これはなぜ動的バインディングではなく静的バインディングですか?
- 28. このJPA列挙型はなぜ機能しないのですか?
- 29. エンクロージングクラスのプライベート列挙型と静的フィールド
- 30. インデックス値の列挙型ではなく、代替オブジェクト
実行時にconstの値と同じように値を変更することはできません。それらが静的であれば、その価値が変わる可能性があることを意味します。 –