通过值或引用将对象作为参数传递给另一个类?

在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是否与Main驱动程序类中创建的someTestObj具有相同的副本? 或者两个变量是否指向不同的对象实例?

无论在同一类或另一类的方法中,对象都将通过引用传递。 以下是相同示例代码的修改版本,以帮助您理解。 该值将更改为“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(); } } } 

“对象”永远不会在C#中传递 – “对象”不是语言中的值。 该语言中唯一的类型是基本类型,结构类型等和引用类型 。 没有“对象类型”。

ObjectMyClass等类型是引用类型。 它们的值是“引用” – 指向对象的指针。 对象只能通过引用来操作 – 当你对它们进行new操作时,你会得到一个引用,即. 操作员操作参考; 因为没有对象类型,所以无法获得其值为“是”对象的变量。

所有类型(包括引用类型)都可以通过值或引用传递。 如果参数具有refout类的关键字,则通过引用传递参数。 SetObject方法的obj参数(具有引用类型)没有这样的关键字,因此它通过值传递 – 引用按值传递。

假设someTestObj是一个class而不是struct ,则该对象通过引用传递,这意味着objsomeTestObj引用同一个对象。 例如,在一个中更改name将在另一个中更改它。 但是,与使用ref关键字传递它不同,设置obj = somethingElse不会更改someTestObj

如果作为值类型传递,则对方法内部对象的成员所做的更改也会受到方法外的影响。 但是如果对象本身设置为另一个对象或重新初始化,那么它将不会反映在方法之外。 所以我会说对象作为一个整体仅作为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 } 

我发现其他示例不清楚,所以我做了我自己的测试,确认了一个类实例通过引用传递,因此对该类执行的操作将影响源实例。

换句话说,我的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; } } 

如果你需要复制对象请参考对象克隆,因为对象是通过引用传递的,这对性能有好处,对象创建很昂贵。

这篇文章可以参考: 深度克隆对象