通过复制或参考?

时间:2010-08-24 08:44:35

标签: c# pass-by-reference pass-by-value

我对C#有点新,只是想知道是否有一个类(常用)列表,默认情况下作为副本传递。我如何识别它们?

我知道基本的基本对象类型 - int,uint,float,strings,... - 是通过副本传递的。

4 个答案:

答案 0 :(得分:16)

在C#/ .Net对象中可以分类为值或引用类型[1]。值类型是从System.ValueType派生的任何类型,并在C#中使用struct类型声明定义。这些是通过复制/值传递的。

引用类型是不是从System.ValueType派生而且在C#中使用class关键字定义的类型。引用类型实例的标识符称为引用(类似于指针)。这些也是默认值传递,但只传递引用而不是整个对象。

您的问题还提到string个实例是通过副本传递的。 .Net中的String是一种引用类型(直接从System.Object派生),因此不会通过完整副本传递。

[1]指针在这里可能值得他们自己的课,但我在这个讨论中忽略了它们。

答案 1 :(得分:11)

默认情况下,所有类型都按值传递。 值类型struct)和引用类型class)之间的区别在于值类型 copy 值的值传递给方法,而对于引用类型,只传递一个引用。

See MSDN了解详情。

此外,不要混淆值/引用类型的概念,以及按值或引用传递参数的概念。有关详细信息,请参阅Jon Skeet的this article

答案 2 :(得分:3)

一般来说,

  • 值类型,其中包含原生类型(intfloat,...)以及struct s复制“(如你所说),而在

  • 引用类型,其中包含class es,仅复制引用而不是整个对象。

但请注意, string 未通过“复制”传递!它是一种引用类型,但由于它是不可变的,it behaves similar to a value type

请注意,ref关键字在两种情况下都很有用:对于值类型,这意味着将值复制回来。对于引用类型,这意味着可以更改引用(即,您可以将变量分配给新对象,而不仅仅是更改对象的属性。)

答案 3 :(得分:2)

另请注意,struct对象可以包含引用类型:

struct Currency
{
    int Amount {get;set;} // is referenced by value (copy)
    string Code {get;set;} // is referenced by reference
}

当您使用这样的结构时:

var obj1 = new Currency{Amount = 1, Code = "USD"};
var obj2 = obj1;

然后

object.ReferenceEquals(obj1.Code, obj2.Code); // false - string is reference type, but used inside value type

如果您已将Currency声明为class,则对Code的引用是相同的。