2016-02-04 56 views
-1

为自定义类的向量和矩阵之间的数学运算编写代码我遇到了一个奇怪的问题(至少对我而言)。C#重载运算符给出了不同的结果

类型之间的重载运算符在不同的地方给出不同的结果。我挖掘出该操作的结果对“运营商+(...)”内部如何创建新实例很敏感。

我已经创建了显示差异的简单代码(见下文)。 两个班正在做同样的事情,预计会有相同的结果,但实际上并不相同。 Type2的重载操作符和“test”函数修改变量。 我还没有在MSDN中发现任何警告。这种行为并不直接由语法标记(由“ref”关键字引起)。

任何人都可以推荐一个关于这个问题的链接? 它预测的行为或C#语法中的错误?

using System; 

namespace test_operator_overload 
{ 
    class Program 
    { 
     static void Main() 
     { 
      Type1 A1 = new Type1(1); 
      Console.WriteLine(A1);   // 1 - OK 
      Console.WriteLine(A1 + A1);  // 2 - OK 
      Console.WriteLine(A1);   // 1 - OK 

      Console.WriteLine(); 

      Type2 B1 = new Type2(1); 
      Console.WriteLine(B1);   // 1 - OK 
      Console.WriteLine(B1 + B1);  // 2 - OK 
      Console.WriteLine(B1);   // 2 - Not OK 

      Console.WriteLine(); 

      Type2 C1 = new Type2(1); 
      Console.WriteLine(C1);   // 1 - OK 
      Console.WriteLine(test(C1)); // 2 - OK 
      Console.WriteLine(C1);   // 2 - Not OK 
     } 

     static Type2 test(Type2 a) 
     { 
      a.x += 1; 
      return a; 
     } 
    } 



    class Type1 
    { 
     public double x; 

     public Type1(double x) 
     { 
      this.x = x; 
     } 

     public static Type1 operator +(Type1 a, Type1 b) 
     { 
      return new Type1(a.x + b.x); 
     } 

     public override string ToString() { return GetType().Name + " (" + x + ")"; } 
    } 


    class Type2 
    { 
     public double x; 

     public Type2(double x) 
     { 
      this.x = x; 
     } 

     public static Type2 operator +(Type2 a, Type2 b) 
     { 
      a.x += b.x; 
      return a; 
     } 

     public override string ToString() { return GetType().Name + " (" + x + ")"; } 
    } 
} 
+0

寻求调试帮助的问题(“为什么这个代码不工作?”)必须包含所需的行为,特定的问题或错误以及在问题本身中重现问题所需的最短代码。没有明确问题陈述的问题对其他读者无益。请参阅:如何创建最小,完整和可验证示例。 – mybirthname

+3

运算符中的参数变化必然会引起混淆。没有人期待操作员的这些副作用。 –

+2

'clsB'的运算符没有创建新的实例。它们在表达式的评估过程中*改变*操作数的属性。因此,在其表达式中使用两次的“B2”属性对于两种不同的操作具有不同的值。 –

回答

1

您的+运营商Type2是borked的,您不应修改运营商的输入。

运营商对结合输入操作输入和返回的新结果。

+0

是的,我已经将结构应用于所有使用重载操作符的类。现在它快了大约30%。 但我在例子中解释的问题仍然不清楚。 正如在MSDN中提到的:[link](https://msdn.microsoft.com/EN-US/library/8f1hz171(v = VS.140,d = hv.2).aspx) “...更改当控制回到调用过程时,值不会被保留。“ 在我的示例中,当我使用重载操作符或调用函数“test”时,参数值在控件传回给调用过程后发生更改。 所以。怎么了? – Dennis

+0

呃,它确实在做你所要求的。添加输入,然后将其中一个输入值设置为等于结果..运算符与函数没有区别,因为它们通过引用获取输入,并可以修改它们的值。 – Henrik

+0

文档@丹尼斯提到谈论通过价值与传递引用,而不是“传递*参考”,所以虽然他引用的文档在技术上是正确的,但与他的问题无关。 –