C# 对象作为参数传递给另一个类,通过值还是引用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12997635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Object passed as parameter to another class, by value or reference?
提问by Carven
In C#, I know that by default, any parameters passed into a function would be by copy, that's, within the function, there is a local copy of the parameter. But, what about when an object is passed as parameter to another class?
在 C# 中,我知道默认情况下,传递给函数的任何参数都是通过复制的,也就是说,在函数内部,有参数的本地副本。但是,当一个对象作为参数传递给另一个类时呢?
Would a scenario like the following one be passed by reference or by value:
像下面这样的场景是通过引用还是通过值传递:
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);
}
In this case, would the class variable localObjbe having the same copy as the someTestObjcreated in the Maindriver class? Or would the two variables be pointing to a different object instance?
在这种情况下,类变量localObj是否someTestObj与Main驱动程序类中创建的变量具有相同的副本?或者这两个变量会指向不同的对象实例吗?
采纳答案by Rajee
Objects will be passed by reference irrespective of within methods of same class or another class. Here is a modified version of same sample code to help you understand. The value will be changed to 'xyz.'
对象将通过引用传递,而不管在同一类或另一个类的方法内。这是相同示例代码的修改版本,以帮助您理解。该值将更改为“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();
}
}
}
回答by Tim S.
Assuming someTestObjis a classand not a struct, the object is passed by reference, which means that both objand someTestObjrefer to the same object. E.g. changing namein one will change it in the other. However, unlike if you passed it using the refkeyword, setting obj = somethingElsewill not change someTestObj.
假设someTestObj是 aclass而不是 a struct,对象是通过引用传递的,这意味着obj和someTestObj引用同一个对象。例如,改变name一个就会改变另一个。但是,与使用ref关键字传递它不同,设置obj = somethingElse不会更改someTestObj。
回答by newacct
"Objects" are NEVER passed in C# -- "objects" are not values in the language. The only types in the language are primitive types, struct types, etc. and reference types. No "object types".
“对象”永远不会在 C# 中传递——“对象”不是语言中的值。该语言中仅有的类型是原始类型、结构类型等和引用类型。没有“对象类型”。
The types Object, MyClass, etc. are reference types. Their values are "references" -- pointers to objects. Objects can only be manipulated through references -- when you do newon them, you get a reference, the .operator operates on a reference; etc. There is no way to get a variable whose value "is" an object, because there are no object types.
类型Object、MyClass等是引用类型。它们的值是“引用”——指向对象的指针。对象只能通过引用来操作——当你new对它们进行操作时,你会得到一个引用,.操作符对一个引用进行操作;等等。因为没有对象类型,所以没有办法得到一个值“是”一个对象的变量。
All types, including reference types, can be passed by value or by reference. A parameter is passed by reference if it has a keyword like refor out. The SetObjectmethod's objparameter (which is of a reference type) does not have such a keyword, so it is passed by value-- the reference is passed by value.
所有类型,包括引用类型,都可以按值或按引用传递。如果参数有像refor这样的关键字,则参数通过引用传递out。该SetObject方法的obj参数(这是一个引用类型的)不具有这样的关键字,因此它是由值传递-该引用值传递。
回答by Farfarak
If you need to copy object please refer to object cloning, because objects are passed by reference, which is good for performance by the way, object creation is expensive.
如果需要复制对象请参考对象克隆,因为对象是通过引用传递的,顺便说一下对性能有好处,创建对象的开销很大。
Here is article to refer to: Deep cloning objects
这里是参考文章:深度克隆对象
回答by sjd
An Object if passed as a value type then changes made to the members of the object inside the method are impacted outside the method also. But if the object itself is set to another object or reinitialized then it will not be reflected outside the method. So i would say object as a whole is passed as Valuetype only but object members are still reference type.
一个对象如果作为值类型传递,那么在方法内部对对象成员所做的更改也会在方法外部受到影响。但是如果对象本身被设置为另一个对象或重新初始化,那么它不会在方法之外反映出来。所以我会说对象作为一个整体仅作为 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
}
回答by RitchieD
I found the other examples unclear, so I did my own test which confirmed that a class instance is passed by reference and as such actions done to the class will affect the source instance.
我发现其他示例不清楚,因此我进行了自己的测试,确认类实例是通过引用传递的,因此对类执行的此类操作将影响源实例。
In other words, my Increment method modifies its parameter myClass everytime its called.
换句话说,我的 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;
}
}
回答by Pavel Jablonsky
In general, an "object" is an instance of a class, which is an "image"/"fingerprint" of a class created in memory (via New keyword).
The variable of object type refers to this memory location, that is, it essentially contains the address in memory.
So a parameter of object type passes a reference/"link" to an object, not a copy of the whole object.
通常,“对象”是类的实例,它是在内存中创建的类的“图像”/“指纹”(通过 New 关键字)。
对象类型的变量是指这个内存位置,即本质上包含了内存中的地址。
因此,对象类型的参数将引用/“链接”传递给对象,而不是整个对象的副本。

