Search code examples
c#operator-overloadingreference-type

C# overload operator gives different results


Writing the code for the mathematical operations between my custom classes of vectors and matrices I have faced a strange (at least for me) problem.

The overloaded operators between types give different results in different places. I have dug out that the result of the operation is sensitive on how the new instance is created inside the "operator +(...)".

I have created the simple code showing the difference (see below). Two classes are making the same thing and the same result is expected, but in reality not the same. The overloaded operator of Type2 and the function "test" modify the variable. I have not found any warning about this in MSDN. This behavior is not marked directly by syntax (f.e. by the "ref" keyword).

Can anyone recommend a link about this problem? Is it predicted behavior or a mistake in the C# syntax?

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 + ")"; }
    }
}

Solution

  • Your + operator for Type2 is borked, you should not modify the inputs in the operators.

    Operators operate on the input by combining the inputs and returning the new results.