1. ホーム
  2. c#

[解決済み] 列挙型の値に0.0を割り当てることができ、1.0を割り当てることができない理由

2023-03-30 10:31:14

質問

好奇心からなのですが、なぜ列挙型の変数に0.0を代入することはできても、1.0を代入することはできないのでしょうか?次のコードを見てください。

public enum Foo
{
    Bar,
    Baz
}

class Program
{
    static void Main()
    {
        Foo value1 = 0.0;
        Foo value2 = 1.0;   // This line does not compile
        Foo value3 = 4.2;   // This line does not compile
    }
}

数値型と列挙値の間の変換はキャストでしかできないのでは?つまり、私はFooを書くことができます value2 = (Foo) 1.0; と書くと、2行目の Main がコンパイルできるようになります。なぜ例外が発生するかというと、値 0.0 という値で例外が発生するのはなぜでしょうか?

どのように解決するには?

0.0が使えるのはバグです。コンパイラは暗黙のうちに値0を持つ定数式をすべて0として扱ってしまいます。

さて、それは 正しい から暗黙のうちに変換することを許可しています。 int 式からenumへの暗黙の変換を許可しています。

暗黙の列挙変換は、10進整数リテラル0を任意の列挙型とその基礎となる型が列挙型である任意のnullable型に変換することを許可しています。後者の場合、変換は基礎となるenum型に変換し、結果をラップすることによって評価されます(§4.1.10)。

私は以前この件についてC#チームと話をしたことがあります。 偶然 0.0 (および 0.0m と 0.0f) から enum 値への変換を削除したかったのですが、残念ながら、あまりにも多くのコードを壊してしまったと思います - そもそも許されるべきでなかったにもかかわらず。

Mono の mcs コンパイラはこれらの浮動小数点数の変換をすべて禁止しています。 は行います。 は許可します。

const int Zero = 0;
...

SomeEnum x = Zero;

にもかかわらず Zero は定数表現ですが ではなく は10進数リテラルではありません。

将来的にC#の仕様が変更され、値が0の任意の整数定数式が許されるようになっても不思議ではありません(すなわち mcs を模倣したもの)、しかし、浮動小数点数変換が今まで通り 公式に が正しくなるとは思っていません。(もちろん、私は以前にも C# の未来予測について間違っていたことがありますが...)