1

C# でメソッドにパラメーターを渡すことについて、1 つのことを理解していません。私が見たところ、C# のオブジェクトは、参照によって渡されたように動作したり、値によって渡されたように動作したりすることがあります。このコードでは、method()1 つは参照渡し、もう 1 つは値渡しです。これらは両方とも期待どおりに実行されます。しかしUpdate()、オブジェクトを作成して値で渡すと、元のオブジェクトを更新しているように動作することがわかります。

元のオブジェクトを で更新するUpdate(myString input)のに で更新しないのはなぜmethod(myString input)ですか?

これは非論理的です!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassPassing
{
class Program
{
    static void Main(string[] args)
    {
        myString zmienna = new myString();

        Update(zmienna);
        Console.WriteLine(zmienna.stringValue);
        Console.WriteLine(zmienna.stringValue2);
        Console.ReadLine();

        zmienna.stringValue = "This has run in main";
        zmienna.stringValue2 = "This is a help string";

        method(zmienna);
        Console.WriteLine(zmienna.stringValue);
        Console.WriteLine(zmienna.stringValue2);
        Console.ReadLine();

        method(ref zmienna);
        Console.WriteLine(zmienna.stringValue);
        Console.WriteLine(zmienna.stringValue2);

        Console.ReadLine();
    }

    static void method(myString input)
    {
        input = new myString();
    }

    static void method(ref myString input)
    {
        input = new myString();
    }

    static void Update(myString input)
    {
        input.stringValue2 = "This has run in update method";
    }
}

public class myString
{
    public string stringValue { get; set; }
    public string stringValue2 { get; set; }

    public myString() { stringValue = "This has been just constructed";   this.stringValue2 = "This has been just constructed"; }
}

}`

4

4 に答える 4

0

コンピュータのメモリが一連のボックスであり、ラベルを使用して名前を付けることができると想像してください。

myString zmienna = new myString();

ここでは、 のインスタンスを含むボックスを割り当て、それを指すmyStringラベルを設定します。zmiennaそれで:

static void method(myString input)
{
    input = new myString();
}

このメソッドでinputは、別のラベルです。最初にメソッドを呼び出して、最初のインスタンスでラベルinputが同じボックスを指すようにします。ただし、メソッドの本体で別のボックスを割り当て、その新しいボックスを指すようにラベルを変更します。 input最初のボックスは何も処理されておらず、zmiennaラベルも何も処理されていません。

static void method(ref myString input)
{
    input = new myString();
}

ここで、refキーワードのために、最初の「メモリー ボックス」の場所を渡すだけでなく、実際のラベルを付けます。したがって、このメソッドの本体zmiennaは、新しく作成されたボックスを指すようにラベルを更新し、 の 2 番目のインスタンスを使用しmyStringます。最初のボックスは、ラベルが指定されていないため、忘れられています。

static void Update(myString input)
{
    input.stringValue2 = "This has run in update method";
}

この場合、最初のメソッドとまったく同じ方法で、最初のボックスのアドレスを渡します。したがって、2 つのラベルがあります:zmiennainput- 両方とも同じボックスを指しています。したがって、 が指す同じボックス内input.stringValue2のフィールドにアクセスします。stringValue2zmienna

この説明で使用しているラベル用語ではなく、実際に使用されている正確な用語は参照です。どういうわけか、多くの人がこの方法で理解しやすいと感じています:)

于 2013-11-14T14:37:55.433 に答える