差分
このページの2つのバージョン間の差分を表示します。
— |
blog:2023:2023-11-18 [2023-11-18 23:42] (現在) Decomo 作成 |
||
---|---|---|---|
行 1: | 行 1: | ||
+ | ====== C# | ||
+ | 僕はついさっき知ったばかりなんですけど、C# | ||
+ | |||
+ | <code csharp> | ||
+ | using System; | ||
+ | |||
+ | public class Program | ||
+ | { | ||
+ | enum Hoge { A, B } | ||
+ | enum Piyo { C, D } | ||
+ | | ||
+ | public static void Main() | ||
+ | { | ||
+ | Hoge h1 = 0, h2 = 0.0f; | ||
+ | Piyo p1 = 0x0, p2 = 0.0m; | ||
+ | Console.WriteLine($" | ||
+ | Console.WriteLine($" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | このコードは何の警告もなくビルドが通り、以下の実行結果が得られる。 | ||
+ | |||
+ | < | ||
+ | A, A | ||
+ | C, C | ||
+ | </ | ||
+ | |||
+ | 浮動小数点数やDecimalのゼロも同様の扱いっていうのが、なかなかのキモいポイント。C# | ||
+ | |||
+ | で、ここからが本題。 | ||
+ | |||
+ | そんな0のenumへの暗黙的型変換のおかげで、意図せぬメソッドのオーバーロード解決が行われ、小一時間ハマった。 | ||
+ | |||
+ | 以下のような処理メソッド'' | ||
+ | |||
+ | 何の疑いもなく動くと思いきや、ケース3のテストでのみ'' | ||
+ | |||
+ | <code csharp> | ||
+ | // 加算 | ||
+ | private static decimal? Add(decimal? | ||
+ | { | ||
+ | return v1 + v2; | ||
+ | } | ||
+ | |||
+ | // Addメソッドの単体テスト | ||
+ | void AddTest() | ||
+ | { | ||
+ | var privateType = new PrivateType(typeof(AddClass)); | ||
+ | |||
+ | // ケース1 | ||
+ | var value = (decimal? | ||
+ | Assert.AreEqual(2, | ||
+ | |||
+ | // ケース2 | ||
+ | value = (decimal? | ||
+ | Assert.AreEqual(1, | ||
+ | |||
+ | // ケース3 | ||
+ | value = (decimal? | ||
+ | Assert.AreEqual(1, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | |||
+ | ケース1~2は通っているのに見つからないとは一体…!? | ||
+ | |||
+ | * ケース1~2 | ||
+ | * InvokeStatic(String, | ||
+ | * ケース3 | ||
+ | * InvokeStatic(string, | ||
+ | |||
+ | ケース3では、第二引数の0.0mがBindingFlagsに暗黙キャストされた結果、引数を1つ持つ'' | ||
+ | |||
+ | この暗黙型変換を禁止ないし警告出してくれるコンパイルオプションとかないのかしら…ハマった時に死ぬほどわかりづらいんですけど…… |