开发者

SEHException .net Conundrum

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 int or by not using a nullable object.

I have noticed the error doesnt get thrown in VS2010 only 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;
    }
}


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.


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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜