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

时间:2012-10-21 12:04:49

标签: c# pass-by-reference

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

7 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分:7)

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

答案 2 :(得分:3)

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

答案 3 :(得分:3)

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

换句话说,我的Increment方法每次调用时都会修改其参数myClass。

Point

答案 4 :(得分: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
    }

答案 5 :(得分:0)

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

以下是参考文章:Deep cloning objects

答案 6 :(得分:0)

通常,“对象”是类的实例,是在内存中创建的类的“图像” /“指纹”(通过New关键字)。
对象类型的变量引用此内存位置,也就是说,它实质上包含内存中的地址。
因此,对象类型的参数将引用/“链接”传递给对象,而不是整个对象的副本。