Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does not C# support operator overloading with pass by reference?

Is this a CLR restriction or a language design decision? I tried to do it in C++/CLI, of course where it works because the need to support native c++:

public ref class Test
    {
        public:
        static Test^ operator &( Test^ msg, int& i )
        {
            i = i + 1;

            return nullptr;
        } 
    };

and then looked at the compiler omitted output:

public: static Test __gc* op_BitwiseAnd(Test __gc* msg, Int32 __gc** modopt(IsImplicitlyDereferenced __gc*) i)
{
    i[0] += 1;
    return 0;
}

I went further and tried to call this operator from C# project - and of course I needed to go [unsafe] to do it( I needed pointer ):

Test t = new Test();
int i = 0;

unsafe
{
    t = t & &i;
} 

Obviously not so hard to implement for the CLR? I really miss pass by reference in operators overloading and would like to at least in light myself in why is this missing?

Why can't C# hide the ugliness behind the unsafe and pointers when we need to deal with reference variables in our operator overloads? Even if I chose to go with this ugly workaround it wouldn't work in Silverlight, where unsafe operations is not allowed...

like image 549
Ivan Zlatanov Avatar asked Oct 31 '09 16:10

Ivan Zlatanov


2 Answers

In C#, your variables are never altered by callees without you explicitly passing them as references (e.g. int.TryParse(s, out i) where you explicitly specify the out keyword). This feature would make things complicated by allowing the overloaded operator alter the contents of the operands without your explicit permission.

For instance,

public static MyStruct operator + (ref MyStruct left, ref MyStruct right) {
    left = new MyStruct(); // !!!!!!!!
    return something(left, right);
}

When you reference such an operator in C#:

MyStruct x = new MyStruct();
MyStruct y = new MyStruct();
MyStruct z = x + y; // in C#, you never expect `x` to be changed.
like image 83
mmx Avatar answered Nov 15 '22 20:11

mmx


I think it is because an operator (in the more mathematical view that C# seems to take) is logically something that combines its arguments into a new value, never supposed to be mutating anything. C++ seems to consider operators more as a version of general operations with more convenient syntax than functions, than as a way to represent maths in particular. I think that in C# you'll almost never see things like defining operators for stream operations and such.

like image 26
Joren Avatar answered Nov 15 '22 20:11

Joren