Possible Duplicate:
SEHException .net Conundrum
A Colleague pointed out this interesting exception which has started getting generated recently. (note this is a toy version of the actual code, for simplicity)
using System;
namespace ConsoleApplication19
{
class Program
{
static void Main(string[] args)
{
var o1 = new MyObject?(new MyObject(2.34M));
o1 *= -1; //This line throws SEHException
}
}
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;
}
}
}
The marked line throws an SEHException 'External component threw an exception'. Obviously the error is that -1 on that line should be -1M, so the arg is of the correct type, this change stops the exception being thrown. What's interesting though is by making a minor 'cosmetic' change to the code the exception is no longer thrown.
// 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;
}
}
}
Note all we've done is inverted the order of the arguments to the * defined for MyObject, and expanded the *= to be more explicit. I was thinking maybe the fact that the values get pushed to the stack in a different order avoids the exception? But I'm pretty clueless.
Just to clarify: I don't need a solution to stop the exception being thrown, we have that, I'm more interested in why the exception is being thrown, and why making minor cosmetic changes to the code 'fixes' the issue.
hint: also been advised that the exception isn't thrown in visual studio 2010, only 2008.
Any help is appreciated :)