【问题标题】:SEHException .net ConundrumSEHException .net 难题
【发布时间】:2011-03-30 01:54:03
【问题描述】:

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

我注意到只有 VS2008 的 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;
    }
}

【问题讨论】:

    标签: c# .net puzzle


    【解决方案1】:

    没有使用给定代码 sn-p 的重现。但是,您使用的代码与 C# 编译器中的旧错误代码非常相似。详情在this thread,Eric Lippert 已经知道了。

    【讨论】:

      【解决方案2】:

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

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

      您的意思可能是 operator *(MyObject value1, decimal value2) 确实失败了。

      【讨论】:

      • 是的,很抱歉,运算符重载应该排除小数,除了 int 没有问题。该方法的实现是正确的,因为 MyObject 可以轻松地在其上拥有更多属性,并且通过返回一个新对象(如您的示例中),您会丢失这些值。
      【解决方案3】:

      为此添加一点,下面的代码对操作数重新排序,不再抛出异常,而是当程序退出时 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;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-18
        • 2011-02-02
        • 2012-05-11
        • 1970-01-01
        相关资源
        最近更新 更多