私は列挙型が定数としてコンパイルされていることを理解しています。そのため、列挙型を変更すると大きな変化が生じます。なぜ私は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. Javaの非静的な列挙型
- 2. なぜMySQLのboolean型は列挙型ではなくtinyintにマップされますか?
- 3. Doctrine列挙型で列挙されていない値を追加することはできませんか?
- 4. なぜ列挙コンストラクタは、静的フィールドにアクセスすることができない
- 5. なぜtypedefは列挙型で使用されていますか?
- 6. は、なぜ、すべての列挙型は、列挙型<e>
- 7. Resharperはこれらの列挙型が使用されていないと思うのはなぜですか?
- 8. なぜこの列挙型コードは静的フィールドへの不正な参照ですか?
- 9. 列挙型はモデルと見なされるべきですか?
- 10. Bashのこれらの例では、動的な型定義と静的な型指定がありますか?
- 11. このJPA列挙型はなぜ機能しないのですか?
- 12. Javaで配列定数で定義された列挙型
- 13. 列挙型:列挙型の名前ではなく、そのint型の値を文字列として取得する必要があります
- 14. なぜ文字列[0] = "新しい値"はコンパイルされませんか?
- 15. 一般的な列挙型として扱う?
- 16. 列挙型フィールド内でソートしないでください
- 17. Javaでは、クラス内の列挙型は静的ですか?
- 18. 動的多型ではなく静的なC++
- 19. .NETでは、定数はJIT時ではなくコンパイル時に評価されるのはなぜですか?
- 20. C++/CLI:管理されていない列挙型から管理された列挙型へのキャスト
- 21. なぜC++で算術値または列挙値を暗黙的にブール値に変換できますか?
- 22. Python enumでSQLAlchemy列挙型列を定義すると、 "ValueError:有効な列挙型ではありません"
- 23. なぜ文字列は列挙型ではありませんか?
- 24. neo4j列挙型ではない動的関係型
- 25. なぜbasenameはコンパイルされたファイル名を返しますか?
- 26. Rails - レンダリングされたページを静的なHTMLファイルとして書くには?
- 27. このテンプレート関数が正しくコンパイルされるのはなぜですか?
- 28. HasFlagには一般的な列挙型がありますか?
- 29. なぜJava定数は静的であると宣言されていますか?
- 30. DBの列挙型または列挙型の列挙型
実行時にconstの値と同じように値を変更することはできません。それらが静的であれば、その価値が変わる可能性があることを意味します。 –