メソッドに構造体を変更させる目的でメソッドに構造体を渡したい場合、メソッドref
はパラメーターで修飾子を使用する必要があります。ref
パラメータなしで構造体をメソッドに渡すと、メソッドがその構造体のフィールドを変更することはできません。
ref
修飾子を使用する必要がないように、構造体をクラスに置き換えることを提案する人もいることに注意してください。変更可能なクラス オブジェクトへの参照を受け取るすべてのメソッドは、その後いつでも自由にオブジェクトを変更できるため、これは危険な概念です。変更可能なクラス オブジェクトへの参照を、受信者がそれを変更することを許可せずに渡す明確な方法はありません。任意の将来の時点でのオブジェクト。構造には、これらの問題のいずれもありません。
オブジェクトが type などの値型フィールドを保持している場合、MyBounds
IDrawing.Rectangle
を呼び出すと、それが変更されるFoo(MyBounds)
可能性がないことが保証されます。さらに、私が呼び出すと、変更される可能性があると予想できますが、メソッドが戻る前にすべての変更が完了します。変更可能なクラス型であった場合、調べなければ、将来任意の時点でのプロパティが変更される可能性があるかどうかを知る方法がありません。Foo
MyBounds
Bar(ref MyBounds)
Bar
MyBounds
Rectangle
Foo
Bar
MyBounds
構造体がクラスと異なることを理解していない人は、構造体の振る舞いに混乱するかもしれませんが、公開されたパブリック フィールドを持つすべての構造体は同じように振る舞います。構造体には、構造体で定義されたインスタンス メソッドとプロパティがパラメーターthis
として受け取るという悪い面がありref
ますが、次のようなことをしようとすると、次のようになります。
readonly System.Drawing.Rectangle myRect = whatever;
...
myRect.Offset(4,2);
システムは をパラメーターmyRect
として渡すことができないことを認識しref
(読み取り専用であるため)、診断を行わずにコードを次のように変更します。
readonly System.Drawing.Rectangle myRect = whatever;
...
System.Drawing.Rectangle temp = myRect;
temp.Offset(4,2);
ただし、ここで問題Rectangle
なのは、変更可能であるという事実ではなく、任意のすべての値型メソッドを呼び出すときに、上記のコード置換が正当であるとコンパイラが想定しているという事実です。Microsoft が属性を追加して、読み取り専用構造体で特定のメソッドを呼び出すと、そのような置換を実行するのではなく、エラーが発生することを示すまでの間、構造体で動作する構造体メソッドをコード化する唯一の安全な方法は、"in- place" は次のような形式を使用することになります: static void Offset(ref Rectangle it, int x, int y);
、その場合、本来のようRectangle.Offset(ref myRect, 4, 2);
に失敗します。