1. ホーム
  2. c#

[解決済み】C#でオブジェクトを参照または値で渡す

2022-04-01 14:46:27

質問

C#では、非プリミティブ変数は参照渡し、プリミティブ値は値渡しと考えてきました。

つまり、メソッドに非プリミティブなオブジェクトを渡すと、メソッド内でそのオブジェクトに対して行われたことは、渡されたオブジェクトに影響を与えるということです。(C# 101的な話)

しかし、System.Drawing.Imageオブジェクトを渡すと、そうではないような気がするのですが?System.Drawing.Image オブジェクトを別のメソッドに渡して、そのオブジェクトに画像をロードし、そのメソッドをスコープ外に出して呼び出し元のメソッドに戻した場合、その画像は元のオブジェクトにロードされないのでしょうか?

これはなぜですか?

解決方法は?

対象物 は全く渡されません。デフォルトでは、引数は評価され、その は、呼び出すメソッドのパラメータの初期値として、値で渡されます。ここで重要なのは、valueは参照型のための参照、つまりオブジェクト(またはnull)を取得するための手段であるということです。そのオブジェクトに対する変更は、呼び出し元から見えるようになります。しかし、パラメータの値を変更して別のオブジェクトを参照するようにすると、次のようになります。 ない のデフォルトである値による受け渡しを使用している場合は、表示されません。 すべて の型があります。

参照渡しを使いたい場合は が必要です。 使用 out または ref は、パラメータの型が値型であるか参照型であるかを表します。この場合、事実上、変数自体が参照渡しされるため、パラメータは引数と同じ格納場所を使用し、パラメータ自体への変更は呼び出し側で確認されます。

だから

public void Foo(Image image)
{
    // This change won't be seen by the caller: it's changing the value
    // of the parameter.
    image = Image.FromStream(...);
}

public void Foo(ref Image image)
{
    // This change *will* be seen by the caller: it's changing the value
    // of the parameter, but we're using pass by reference
    image = Image.FromStream(...);
}

public void Foo(Image image)
{
    // This change *will* be seen by the caller: it's changing the data
    // within the object that the parameter value refers to.
    image.RotateFlip(...);
}

私は の記事で、もっと詳しく説明しています。 . 基本的に、quot; pass by reference"は、あなたが考えているような意味ではないのです。