Help us understand the problem. What is going on with this article?

数値リテラルの拡張メソッド呼び出しでハマった

More than 1 year has passed since last update.

数値に対する拡張メソッドを書いていて、リテラルに対して実行したときにハマったのでメモ。

例えば、以下のような拡張メソッドがあったとして、

public static class NumEx
{
  public static double Ceiling(this double num) => Math.Ceiling(num);
}

次のように負数の数値リテラルに対して実行すると期待した値とは異なる値が返ってくる。

Console.log(-1.5.Ceiling()); // --> -1.0を期待
> -2 // しかし実行すると-2.0が返る

これは演算子の優先順位の問題で、マイナスの単項演算子の優先順位が拡張メソッドの
呼び出しよりも弱いために、拡張メソッドの呼び出し結果に対してマイナスの単項演算子
が評価されているためこうなってしまう。

Console.log(-1.5.Ceiling());   // <- この記述は
Console.log(-(1.5.Ceiling())); // <- このように解釈される

回避するには、リテラルに対して直接拡張メソッドを実行するのではなく、いったん変数に
格納してやるか、()で括って優先順位を明示的に示してやればよい。

var n = -1.5;
Console.log(n.Ceiling());
> -1
Console.log((-1.5).Ceiling());
> -1

リテラルに対して拡張メソッドを実行するときは意識しておかないと、忘れたころにまたハマりそう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away