这是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 ......
答案 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#中你几乎从来没有看到像为流操作定义运算符等等。