簡単な質問 - Decimal 型がこれらの定数を定義するのはなぜですか? なぜわざわざ?
これが言語によって定義されている理由を探しています。コンパイラーへの使用や影響は考えられません。そもそもなんでこれ入れるの?コンパイラは、Decimal.Zero と同じくらい簡単に 0m をインライン化できるので、コンパイラのショートカットとして購入するつもりはありません。
小さな説明。これらは実際には静的な読み取り専用値であり、定数ではありません。定数値はさまざまなコンパイラによってインライン化されているため、コンパイルされたアセンブリでそれらの使用状況を追跡することは不可能であるため、.Net では明確な違いがあります。ただし、静的な読み取り専用値はコピーされずに参照されます。これは、それらの使用を分析できることを意味するため、質問にとって有利です。
リフレクターを使用して BCL を掘り下げると、MinusOne と Zero が VB ランタイムでのみ使用されていることがわかります。主に、Decimal 値と Boolean 値の間の変換を提供するために存在します。なぜ MinusOne が使用されているのかが、偶然にも今日別のスレッドで取り上げられました (リンク)
奇妙なことに、Decimal.One の値を見ると、どこにも使用されていないことがわかります。
なぜそれらが明示的に定義されているのかについては...私は、確固たる理由があるとは思えません。特定のパフォーマンスはないようで、それらの存在に帰することができる便利な手段が少しあるだけです。私の推測では、BCL の開発中に誰かが利便性のために追加したものであり、削除されることはありませんでした。
編集
@Paleta によるコメントの後、const
問題をもう少し掘り下げました。の C# 定義でDecimal.One
はconst
修飾子が使用されますstatic readonly
が、IL レベルで として出力されます。const
C# コンパイラは、いくつかのトリックを使用して、この値を実質的に a (インライン リテラルなど)と区別できないようにします。これは、このトリックを認識する言語で表示されます (VB.Net はこれを認識しますが、F# は認識しません)。
一部の .NET 言語は 10 進リテラルをサポートしていません。このような場合、new Decimal(1) の代わりに Decimal.ONE を記述する方が便利 (かつ高速) です。
同じ理由で、Java の BigInteger クラスにも ZERO と ONE があります。
それについての私の意見は、それらは魔法の数を避けるのを助けるためにそこにあるということです.
マジック ナンバーは基本的に、コード内で任意の数値が浮かんでいる場所のどこにでもあります。例えば:
int i = 32;
これは、なぜi が 32 に設定されているのか、32 が何を意味するのか、そもそも 32 であるべきなのか、誰もわからないという意味で問題があります。神秘的で神秘的です。
同様に、これを行うコードをよく見かけます
int i = 0;
int z = -1;
なぜ0と-1に設定されているのですか? これはただの偶然ですか?彼らは何かを意味していますか?知るか?
Decimal.One
、Decimal.Zero
などは、アプリケーションのコンテキストで値が何を意味するかはわかりませんが (おそらくゼロは「欠落」などを意味します)、値が意図的に設定されており、何らかの意味がある可能性が高いことはわかります。
完璧ではありませんが、何も言わないよりはましです :-)
注最適化 のためではありません。次の C# コードを確認してください。
public static Decimal d = 0M;
public static Decimal dZero = Decimal.Zero;
ildasm を使用して生成されたバイトコードを確認すると、両方のオプションで同じMSIL が生成されます。System.Decimal
は値型であるためDecimal.Zero
、リテラル値を使用するよりも「最適」ではありません。
これらの 3 つの値はああああ !!!
それらは、私が末尾の 1と呼んでいるものと関係があるかもしれないと思います
この式があるとします:
(x)1.116666 + (y) = (z)2.00000
ただし、x、zは0.11および2.00に丸められ、(y) を計算するよう求められます。
そう思うかもしれませんy = 2.00 - 1.11
。実際にはyは0.88ですが、0.89になります。( 0.01の差があります)。
x と y の実際の値に応じて、結果は-0.01から+0.01まで変化します。場合によっては、これらの末尾の 1 の束を処理する場合、および物事を容易にするために、末尾の値が に等しいかどうかを確認できDecimal.MinusOne / 100
ますDecimal.One / 100
。Decimal.Zero / 100
それらを修正します。
これが私がそれらを利用した方法です。