Can anyone explain why the below code throws an error. It can easily be fixed by either casting the -1 value to a decimal (-1M), by changing the operator overload to accept an i
Just to add a little something to this, the code below re-orders the operands, and exception is no longer thrown, instead the value of myValue is (correctly) 'invalid decimal value' when the program exits.
Note only the order of the operands has changed, and we've expanded the *= in main to be more explicit and support this.
I wouldn't have expected these cosmetic changes to prevent the exception being thrown.. but they do.
Thought this might have something to do with the values getting pushed to the stack in a different order?
// 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;
}
}
}
It works fine (on my machine) in both VS 2008 and VS 2010. BTW, your implementation of *
is incorrect. It should be:
public static MyObject operator *(MyObject value1, int value2)
{
return new MyObject(value1.myValue * value2);
}
Probably you've meant operator *(MyObject value1, decimal value2)
which is really failing.
No repro with the given code snippet. The code you used however strongly resembles the kind of code that falls over on an old bug in the C# compiler. The details are in this thread, Eric Lippert is already aware of it.