SEHException .net Conundrum - PullRequest
       6

SEHException .net Conundrum

1 голос
/ 29 марта 2011

Может кто-нибудь объяснить, почему приведенный ниже код выдает ошибку. Это можно легко исправить, приведя значение -1 к десятичному знаку (-1M), изменив перегрузку оператора для принятия значения типа int или не используя обнуляемый объект.

Я заметил, что ошибка не выдается в 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;
    }
}

Ответы [ 3 ]

1 голос
/ 29 марта 2011

Нет воспроизведения с данным фрагментом кода.Однако используемый вами код сильно напоминает тот код, который выпадает из-за старой ошибки в компиляторе C #.Подробности в этой теме , Эрик Липперт уже знает об этом.

1 голос
/ 29 марта 2011

Просто чтобы добавить кое-что к этому, приведенный ниже код переупорядочивает операнды, и исключение больше не генерируется, вместо этого значение myValue (правильно) является «неверным десятичным значением» при выходе из программы.

Обратите внимание, что изменился только порядок операндов, и мы расширили * = в 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;
        }
    }
}
1 голос
/ 29 марта 2011

Он отлично работает ( на моей машине ) как в VS 2008, так и в VS 2010. Кстати, ваша реализация * неверна.Это должно быть:

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

Возможно, вы имели в виду operator *(MyObject value1, decimal value2), который действительно терпит неудачу.

...