6

これは CLR の制限ですか、それとも言語設計上の決定ですか? もちろん、ネイティブの C++ をサポートする必要があるため、C++/CLI で実行しようとしました。

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# が unsafe とポインターの背後にある醜さを隠せないのはなぜですか? この醜い回避策を選択したとしても、安全でない操作が許可されていない Silverlight では機能しません...

4

2 に答える 2

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.
于 2009-10-31T16:08:41.090 に答える
1

これは、演算子(C#が取るように見えるより数学的な見方では)が論理的にその引数を新しい値に結合するものであり、何も変更することは想定されていないためだと思います。C ++は、特に数学を表現する方法としてではなく、関数よりも便利な構文を備えた一般的な操作のバージョンとして演算子を考慮しているようです。C#では、ストリーム操作の演算子を定義するなどのことはほとんど見られないと思います。

于 2009-10-31T16:15:26.660 に答える