C# で参照によってオブジェクトを渡す
このチュートリアルでは、C# でオブジェクトを関数に渡す方法について説明します。
C# で変数を値で関数に渡す
C# では、すべての値型変数がデフォルトで値によって渡されます。変数を値で関数に渡し、その変数を関数で変更するとします。その場合、関数の引数で渡される変数の値には影響しません。ここで発生するのは、渡された変数の個別のコピーがメモリに作成され、すべての操作がその特定のコピーに対して実行されることです。次のコード例は、C# で値型変数を値で渡す方法を示しています。
using System;
namespace pass_object_by_reference {
class Program {
static void method1(string value) {
value = "something";
Console.WriteLine("New value = {0}", value);
}
static void Main(string[] args) {
string valueType = "Nothing";
method1(valueType);
Console.WriteLine("Original Value = {0}", valueType);
}
}
}
出力:
New value = something
Original Value = Nothing
上記のコードでは、文字列変数 valueType
を値で method1()
関数に渡しました。この関数は、渡された変数に新しい値を割り当てます。valueType
変数を値ごとに method1()
関数に渡すと、同じ値を持つ変数の 2つの異なるコピーがメモリに作成されます。次に、変数の 2 番目のコピーが something
値に変更されます。この 2 番目のコピーには、method1()
関数内でのみアクセスできます。この 2 番目の値を変更しても、元の変数 valueType
は変更されません。
C# で変数を関数に参照で渡す
C# で ref
キーワードを使用して参照することにより、値型変数を渡すこともできます。ref
キーワードは、値が参照によって渡される関数に渡されることを指定します。このアプローチでは、メモリ内に変数のコピーが 1つだけ存在し、変数の値を指す関数に別のポインタが渡されます。次のコード例は、C# で ref
キーワードを使用して参照によって値型変数を渡す方法を示しています。
using System;
namespace pass_object_by_reference {
class Program {
static void method1(ref string value) {
value = "something";
Console.WriteLine("New value = {0}", value);
}
static void Main(string[] args) {
string valueType = "Nothing";
method1(ref valueType);
Console.WriteLine("Original Value = {0}", valueType);
}
}
}
出力:
New value = something
Original Value = something
上記のコードでは、C# で ref
キーワードを指定して method1()
関数を参照することにより、値型変数 valueType
を渡しました。method1()
関数は、引数として valueType
変数への参照を取り、valueType
変数の値を something
に変更します。今回は、元の値が変更されます。
C# の関数への参照によるオブジェクトの受け渡し
デフォルトでは、クラスインスタンス、構造体インスタンスなどのすべての参照型変数は、C# の関数に参照によって渡されます。ここで起こることは、元のオブジェクトがパラメーターとして関数に渡されることは決してないということです。オブジェクトへの新しい参照は、関数への引数として値によって渡されます。したがって、同じメモリ位置を指すポインタのコピーが 2つあることになります。そのポインタの値を変更すると、元のオブジェクトの値も変更されます。次のコード例は、C# の関数を参照してオブジェクトを渡す方法を示しています。
using System;
namespace pass_object_by_reference {
public class Sample {
public string s { get; set; }
}
class Program {
static void dosomething(Sample obj) {
obj.s = "something";
}
static void Main(string[] args) {
Sample sam = new Sample();
sam.s = "Nothing";
dosomething(sam);
Console.WriteLine(sam.s);
}
}
}
出力:
something
上記のコードでは、sam
オブジェクト内の s
プロパティを変更する dosomething()
関数を参照して、オブジェクト sam
を渡しました。元の sam
オブジェクトの値を変更し、sam.s
プロパティに something
を割り当てます。これは参照によってオブジェクトを渡すデフォルトの方法ですが、このアプローチには 1つの例外があります。渡されたオブジェクトを new
キーワードとクラスコンストラクタで初期化すると、オブジェクトの個別のコピーがメモリ内に作成されます。そのオブジェクトの値を変更しても、パラメーターとして渡された元のオブジェクトは変更されません。次のコード例は、このオブジェクトが値によって C# の関数に渡されるシナリオを示しています。
using System;
namespace pass_object_by_reference {
public class Sample {
public string s { get; set; }
}
class Program {
static void dosomething(Sample obj) {
Console.WriteLine("Initial passed value = {0}", obj.s);
obj = new Sample();
obj.s = "something";
Console.WriteLine("New value = {0}", obj.s);
}
static void Main(string[] args) {
Sample sam = new Sample();
sam.s = "Nothing";
dosomething(sam);
Console.WriteLine("Original Value = {0}", sam.s);
}
}
}
出力:
Initial passed value = Nothing
New value = something
Original Value = Nothing
上記のコードでは、オブジェクト sam
を C# の dosomething()
関数に値で渡しました。dosomething()
関数は引数を取り、その初期値を出力し、値を変更し、変更された値を出力します。この新しい値は新しいメモリ位置に割り当てられ、元のオブジェクト sam
からはアクセスできません。
Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.
LinkedIn