C#でクラスのオブジェクトをメソッドに渡す際の注意点
C#で開発をしていると、メソッドにクラスのオブジェクトを渡した場合、
そのオブジェクトをnewすると、参照渡しであるにもかかわらず、親の
オブジェクトに値が伝わらない問題に直面することがあります。
このブログでは、その原因と解決策について解説します。
問題の背景
クラスのオブジェクトをメソッドに渡す際、C#では参照渡しが行われます。
通常、参照渡しではオブジェクトそのものではなく、そのオブジェクトへの
参照が渡されるため、メソッド内でオブジェクトの内容を変更すると、呼び出し元にも
変更が反映されます。
しかし、メソッド内でオブジェクトをnewしてしまうと、元の参照が
新しいオブジェクトを指すようになるため、呼び出し元のオブジェクトには
変更が伝わりません。
コード例
このコードでは、ModifyObjectメソッド内でオブジェクトobjに新しいインスタンスを
割り当てています。
その結果、元のmyObjのValueプロパティには変更が反映されません。
public class MyClass
{
public int Value;
}
public void ModifyObject(MyClass obj)
{
obj = new MyClass();
obj.Value = 10;
}
public void Main()
{
MyClass myObj = new MyClass();
myObj.Value = 5;
ModifyObject(myObj);
// myObj.Valueは5のまま
Console.WriteLine(myObj.Value); // 出力: 5
}
解決策
この問題を回避するためには、メソッド内で新しいインスタンスを
作成するのではなく、渡されたオブジェクトのプロパティを直接変更するようにします。
このように修正することで、呼び出し元のオブジェクトに変更が反映されます。
public void ModifyObject(MyClass obj)
{
obj.Value = 10;
}
また、refをつけることにより、この問題を解決することができます。
public class MyClass
{
public int Value;
}
public void ModifyObject(ref MyClass obj)
{
obj = new MyClass();
obj.Value = 10;
}
public void Main()
{
MyClass myObj = new MyClass();
myObj.Value = 5;
ModifyObject(ref myObj);
// myObj.Valueは10
Console.WriteLine(myObj.Value); // 出力: 10
}
まとめ
C#でクラスのオブジェクトをメソッドに渡す際には、新しいインスタンスを
作成するのではなく、渡されたオブジェクトのプロパティを変更することが重要です。
これにより、呼び出し元のオブジェクトに正しく変更が反映されます。
これができない場合はrefをつければ、親に渡すことができます。