あなたの質問に答えるために、最初にValueTypesを見てみましょう。ValueTypeはValueを保持します。つまり、値を保持する別のメモリ位置を指すのではなく、メモリ位置が値になります。
したがって、int i = 10;
int j = i;
ここで何が起こるかというと、iの値のコピーがjに割り当てられます。どちらも同じ値ですが、メモリ内の異なる場所にあります。つまり、値タイプを別の値タイプに割り当てるたびに、コピーが作成されます。
これをReferenceTypesと契約します。
オブジェクトo=10;
オブジェクトp=o;
oはReferenceTypeであるため、oは値10を保持するメモリ位置を指します(実際にはボックス化されていますが、単純にしておきます)。次の行で、pは同じメモリ位置を指しています。言い換えれば、参照タイには2つのことがあります。1.アドレスポインタ2.実際の「モノ」を保持する実際のメモリ位置(アドレスが指す)。
あなたがそれをはるかにうまくやれば、私たちは価値と参照による通過に進むことができます。
C#では、パラメーターは値で渡されます。したがって、valueTypeパラメーターを期待するメソッドにvalueTypeを渡す場合は、
int i = 10;
SomeMethod(i);
Console.WriteLine(i);
static void SomeMethod(int value)
{
value = 20;
}
SomeMethodが呼び出されると、iの値のコピーがメソッドに送信されます。メソッドがパラメーターを操作する場合、元の変数iには影響しません。したがって、コンソールウィンドウに表示されるのは10です。
これを参照型と契約します。
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(c);
Console.WriteLine(c.Name);
}
static void SomeMethod(Customer customer)
{
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}
cは参照型なので。そして、C#はパラメータを値で渡します。参照の「値」のコピーが渡されます。つまり、アドレスcが指している値が渡されます。このメソッドでは、アドレスが同じであるため(コピーですが、同じメモリ位置を指します)、メソッドはオブジェクトの状態を操作できます。したがって、コンソールウィンドウに表示されるのは、「マイク」ではなく「ジョン」です。
ただし、メソッドが別のインスタンスをパラメーター(この場合は「顧客」と呼ばれる)に割り当てようとする場合。その後、物事は変化します。
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(c);
Console.WriteLine(c.Name);
}
static void SomeMethod(Customer customer)
{
customer = new Customer();
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}
このメソッドでは、Customerの新しいインスタンスを作成し、それをパラメーターcustomerに割り当て、この新しいインスタンスの名前を「John」に設定していることに注意してください。コンソールウィンドウに表示されるのは「マイク」であり、ジョンではありません。
これは、元の変数(c)のコピーがメソッドに渡される前に作成されたためです。このメソッドでは、別のアドレスがあり、その新しいアドレスを操作して、元のインスタンスが変更されないようにします。わかる?
わかりました、それが理にかなっているなら。では、SomeMethodに、私たちがやろうとしたことを実際に実行できるようにしたいとしたらどうでしょうか。そうですね、パラメータを値で渡すことはできませんが、参照で渡す必要があります。変数cと2つの部分(それが指しているアドレスの値とアドレス自体)が渡されていることを意味します。これで、参照型を参照で渡すことになります。
class Program
{
static void Main(string[] args)
{
Customer c = new Customer() { Name = "Mike" };
SomeMethod(ref c);
Console.WriteLine(c.Name);
}
static void SomeMethod(ref Customer customer)
{
customer = new Customer();
customer.Name = "John";
}
}
class Customer
{
public string Name { get; set; }
}