21

C#では、デフォルトで、関数に渡されるパラメーターはすべてコピーによって行われることを知っています。つまり、関数内にパラメーターのローカルコピーがあります。しかし、オブジェクトがパラメーターとして別のクラスに渡される場合はどうでしょうか。

次のようなシナリオは、参照または値によって渡されますか?

class MyClass {
   private Object localObj;

   public void SetObject(Object obj) {
      localObj = obj;
   }
}

void Main() {
   Object someTestObj = new Object();
   someTestObj.name = "My Name";
   MyClass cls = New MyClass();
   cls.SetObject(someTesetObj);
}

この場合、クラス変数は、ドライバークラスで作成されたlocalObjものと同じコピーを持ちますか?または、2つの変数が異なるオブジェクトインスタンスを指しているのでしょうか?someTestObjMain

4

7 に答える 7

21

「オブジェクト」は C# では決して渡されません。「オブジェクト」は言語の値ではありません。言語の唯一の型は、プリミティブ型、構造体型など、および参照型です。「オブジェクトタイプ」はありません。

Object、などの型MyClassは参照型です。それらの値は「参照」、つまりオブジェクトへのポインタです。オブジェクトは参照を通じてのみ操作できます。オブジェクトを操作するnewと、参照が取得され、.演算子は参照を操作します。オブジェクト型がないため、値がオブジェクトである変数を取得する方法はありません。

参照型を含むすべての型は、値または参照によって渡すことができます。reforのようなキーワードがある場合、パラメーターは参照によって渡されますoutSetObjectメソッドのパラメーターobj(参照型) にはそのようなキーワードがないため、によって渡されます。参照は値によって渡されます。

于 2012-10-21T20:08:01.673 に答える
12

同じクラスまたは別のクラスのメソッド内に関係なく、オブジェクトは参照によって渡されます。理解を助けるために、同じサンプル コードの修正版を次に示します。値は「xyz」に変更されます。

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

namespace ConsoleApplication1
{
    public class Employee
    {
        public string Name { get; set; }
    }

    public class MyClass
    {
        public Employee EmpObj;

        public void SetObject(Employee obj)
        {
            EmpObj = obj;
        }
    }

    public class Program
    {
       static void Main(string[] args)
        {
            Employee someTestObj = new Employee();
            someTestObj.Name = "ABC";

            MyClass cls = new MyClass();
            cls.SetObject(someTestObj);

            Console.WriteLine("Changing Emp Name To xyz");
            someTestObj.Name = "xyz";

            Console.WriteLine("Accessing Assigned Emp Name");
            Console.WriteLine(cls.EmpObj.Name); 

           Console.ReadLine();
       }       
    }
 }
于 2012-10-21T12:19:49.447 に答える
6

私は他の例が不明確であることを発見したので、クラスインスタンスが参照によって渡され、クラスに対して行われたそのようなアクションがソースインスタンスに影響を与えることを確認する独自のテストを行いました.

つまり、私の Increment メソッドは、呼び出されるたびにパラメーター myClass を変更します。

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass();
        Console.WriteLine(myClass.Value);  // Displays 1
        Increment(myClass);
        Console.WriteLine(myClass.Value);  // Displays 2
        Increment(myClass);
        Console.WriteLine(myClass.Value);  // Displays 3           
        Increment(myClass);
        Console.WriteLine(myClass.Value);  // Displays 4
        Console.WriteLine("Hit Enter to exit.");
        Console.ReadLine();
    }

    public static void Increment(MyClass myClassRef)
    {
        myClassRef.Value++;
    }
}

public class MyClass
{
    public int Value {get;set;}
    public MyClass()
    {
        Value = 1;
    }
}
于 2015-12-16T20:22:37.873 に答える
5

someTestObjが でclassあり ではないと仮定するとstruct、オブジェクトは参照によって渡されます。つまり、 と の両方が同じオブジェクトobjを参照します。someTestObjたとえばname、一方を変更すると、他方も変更されます。refただし、キーワードを使用して渡した場合とは異なり、設定obj = somethingElseは変更されませんsomeTestObj

于 2012-10-21T12:09:30.757 に答える
2

オブジェクトが値型として渡された場合、メソッド内のオブジェクトのメンバーに加えられた変更は、メソッドの外部にも影響します。ただし、オブジェクト自体が別のオブジェクトに設定されているか、再初期化されている場合、メソッドの外部には反映されません。したがって、オブジェクト全体は Valuetype としてのみ渡されますが、オブジェクト メンバーは参照型のままです。

private void button1_Click(object sender, EventArgs e)
{
    Class1 objc ;
    objc = new Class1();
    objc.empName = "name1";
    checkobj(objc);
    MessageBox.Show(objc.empName);  //propert value changed; but object itself did not change
}

private void checkobj (Class1 objc)
{
    objc.empName = "name 2";
    Class1 objD = new Class1();
    objD.empName ="name 3";
    objc = objD ;
    MessageBox.Show(objc.empName);  //name 3
}
于 2013-02-22T10:41:28.280 に答える
0

オブジェクトをコピーする必要がある場合は、オブジェクトの複製を参照してください。オブジェクトは参照によって渡されますが、これはパフォーマンスに優れているため、オブジェクトの作成にはコストがかかります。

参照する記事は次のとおりです。ディープクローンオブジェクト

于 2012-10-22T13:00:14.493 に答える