数学

2009-06-04 15 views
7

なぜそれが次のコードは動作しないことである。数学

endDate.AddDays(7-endDate.DayOfWeek); 

このあろうが:

endDate.AddDays(0-endDate.DayOfWeek + 7); 

(私は、次のコンパイルエラーで結果を意味し、「動作しません」とは:「『ダブル』に 『System.DayOfWeek』から変換できません」)

+2

この機能を含む、コンパイラのバグのいくつかの興味深い分析については、以下を参照してください。 http://blogs.gotdotnet.com/ericlippert/archive/2006/03/28/the-root-of-all-evil -part-one。aspx と http://blogs.gotdotnet.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx –

+1

Ericのブログ記事をお探しの方彼らはhttp://blogs.msdn.com/b/ericlippert/archive/2006/03/28/the-root-of-all-evil-part-one.aspxとhttp:// blogsに移動しました。 msdn.com/b/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx –

答えて

12

ラッセが言ったことを拡張する(あるいはむしろ少し明示的にする)。

0は、列挙型に変換可能である

0 - endDate.DayOfWeek becomes 
(DayOfWeek)0 - endDate.DayOfWeek 

そして、あなたは別の1つの列挙型を減算し、整数差を得ることができるのでので:

(DayOfWeek)0 - endDate.DayOfWeek == (int)endDate.DayOfWeek 

したがって、減算の結果以来、 intであれば、それに7を加えることができます。だから、

endDate.AddDays(0-endDate.DayOfWeek + 7); 

、月曜日の列挙値は、しかし1

0 - endDate.DayOfWeek == -1 + 7 == 6 

であれば、あなたは逆の操作を行うことはできません。

endDate.DayOfWeek - 0 + 7, 

計算の結果タイプは左端側に依存するためです。したがって、0 - endDate.DayOfWeekは整数になりますが、endDate.DayOfWeek - 0は列挙型DayOfWeekになります。

最も興味深いことに、この副作用を使用して、キャストせずに列挙型の値を取得することができますが、これは避けなければならないハキッシュで混乱していると考えられます。

int enumValue = -(0 - endDate.DayOfWeek); 
4

これは非常に興味深いです。これを行う正しい方法は次のとおりです。

endDate.AddDays(7 - (int)endDate.DayOfWeek); 

しかし、あなたの質問は解決策ではなく、その動作の理由です。コンパイラがゼロを扱う方法とは関係があります。ゼロが存在しない場合はどちらの行も失敗し、ゼロが存在する場合は両方の行が機能します。

+0

さらに、endDate.AddDays(DayOfWeek.Sunday - e.DayOfWeek)が機能します。それはDayOfWeekの日曜のフィールドにゼロを変換しています。本当に奇妙なのは、「ゼロトリック」が追加に失敗することです。意味endDate.AddDays(DayOfWeek.Sunday + e.DayOfWeek)はコンパイルされません。 –

4

あなたはそれらの整数値の差を取得するために、2つの列挙値を引くことができます。

using System; 

namespace ConsoleApplication10 
{ 
    public enum X { A, B, C, D } 
    public class Program 
    { 
     static void Main() 
     { 
      var x = X.D + X.A; 
      Console.Out.WriteLine(x); 
      Console.In.ReadLine(); 
     } 
    } 
} 

は3

を印刷しますが、追加することはできません、おそらく意味がありません。

"0"の場合、0はすべての列挙型に自動変換されるため、基本的に "0 - enumvalue"は "(enumtype)0 - enumvalue"と同じ意味を持ちます。