2011-03-29 9 views
1

誰でも以下のコードがエラーを投げる理由を説明することはできますか?演算子のオーバーロードを変更してintを受け入れるか、nullを許可するオブジェクトを使用しないようにすることで、-1の値を10進数(-1M)にキャストすることで簡単に修正できます。SEHException .net Conundrum

私は、VS2010のみVS2008でスローされるエラーを気づいた。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var o1 = new MyObject?(new MyObject(2.34M)); 
     o1 *= -1; 
    } 
} 

public struct MyObject 
{ 
    public MyObject(Decimal myValue) 
    { 
     this.myValue = myValue; 
    } 

    private Decimal myValue; 

    public static MyObject operator *(MyObject value1, decimal value2) 
    { 
     value1.myValue *= value2; 
     return value1; 
    } 
} 

答えて

1

指定されたコードスニペットのreproはありません。ただし、使用したコードは、C#コンパイラの古いバグに該当するコードの種類に強く似ています。詳細はthis threadであり、Eric Lippertはすでにそれを認識しています。

1

これはところで、*の実装が間違っているVS 2008とVS 2010の両方で(私のマシン上)正常に動作します。それは次のようになります。

public static MyObject operator *(MyObject value1, int value2) 
{ 
    return new MyObject(value1.myValue * value2); 
} 

おそらくあなたは本当に失敗しているoperator *(MyObject value1, decimal value2)を意味しました。

+0

ありあり申し訳ありませんが、演算子のオーバーロードは10進数を除いている必要があります。ただし、intは問題ありません。メソッドの実装は正しいですが、MyObjectはそれにもっと多くのプロパティを簡単に持たせることができ、新しいオブジェクト(例のように)を返すことでこれらの値を失います。 – CeejeeB

1

これに少し追加するだけで、以下のコードはオペランドの順序を変更し、例外はスローされません。代わりに、プログラムが終了するとmyValueの値が(正しく) '無効な10進値'になります。

オペランドの順序が変更されていることに注意してください。ここでは、mainの* =をさらに明示的に拡張してサポートしています。

例外がスローされるのを防ぐためにこれらの美容上の変更が期待されませんでした。

これは、値がスタックに別の順序でプッシュされるのと関係がありますか?

// If you invert the order of the operands to MyObject.*() , and expand out the *= in main, 
// the thing runs without throwing the exception :s 

// If you step through, the value of myValue is correctly ‘invalid decimal value’ after * by -1. 

using System; 

namespace ConsoleApplication19 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var o1 = (MyObject?)new MyObject(2.34M); 
      o1 = -1 * o1 ; 
     } 
    } 

    public struct MyObject 
    { 
     private Decimal myValue; 

     public MyObject(Decimal myValue) 
     { 
      this.myValue = myValue; 
     } 

     public static MyObject operator *(Decimal value2, MyObject value1) 
     { 
      value1.myValue *= value2; 
      return value1; 
     } 
    } 
}