为什么C#不支持运算符重载并通过引用传递?

时间:2009-10-31 16:04:15

标签: c# clr c++-cli operator-overloading command-line-interface

这是CLR限制还是语言设计决定?我尝试在C ++ / CLI中进行,当然它的工作原理是因为需要支持原生c ++:

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

            return nullptr;
        } 
    };

然后查看编译器省略的输出:

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

我走得更远,试图从C#项目调用这个操作符 - 当然我需要[不安全]去做(我需要指针):

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

unsafe
{
    t = t & &i;
} 

显然CLR没有那么难实现?我真的很想念运营商超载中的参考文献,并且至少想知道为什么这会丢失?

当我们需要在运算符重载中处理引用变量时,为什么C#不能隐藏不安全和指针背后的丑陋?即使我选择使用这种丑陋的解决方法,它也不适用于不允许不安全操作的Silverlight ......

2 个答案:

答案 0 :(得分:5)

在C#中,如果没有显式地将它们作为引用传递给你们,你的变量永远不会被被调用者更改(例如int.TryParse(s, out i),你明确指定了out关键字。通过允许重载操作符在未经您明确许可的情况下更改操作数的内容,此功能会使事情变得复杂。

例如,

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

在C#中引用这样的运算符时:

MyStruct x = new MyStruct();
MyStruct y = new MyStruct();
MyStruct z = x + y; // in C#, you never expect `x` to be changed.

答案 1 :(得分:1)

我认为这是因为运算符(在C#似乎采用的数学视图中)逻辑上是将其参数组合成一个新值,从不应该改变任何东西。 C ++似乎更多地将运算符视为一般操作的版本,语法比函数更方便,而不是特别表示数学的方法。我认为在C#中你几乎从来没有看到像为流操作定义运算符等等。