SEHException .net难题

任何人都可以解释为什么下面的代码会抛出错误。 可以通过将-1值转换为十进制(-1M),通过更改运算符重载以接受int或不使用可空对象来轻松修复它。

我注意到只有VS208才会在VS2010中抛出错误。

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; } } 

没有使用给定代码段的repro。 但是,您使用的代码非常类似于C#编译器中的旧错误所涉及的代码类型。 细节在这个post中 ,Eric Lippert已经意识到了这一点。

它在VS 2008和VS 2010中都能正常工作( 在我的机器上 )。顺便说一句,你的*的实现是不正确的。 它应该是:

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

可能你的意思是operator *(MyObject value1, decimal value2)真的失败了。

只是为此添加一些内容,下面的代码重新排序操作数,不再抛出exception,而是当程序退出时,myValue的值是(正确)’无效的十进制值’。

请注意,只有操作数的顺序已经改变,我们已经扩展了main中的* =以更加明确并支持它。

我不会期望这些外观变化可以防止exception被抛出……但他们确实如此。

认为这可能与以不同顺序推送到堆栈的值有关?

 // 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; } } }