5

我对 C# 有点陌生,只是想知道是否有一个默认作为副本传递的类列表(常用)。我怎样才能识别它们?

我知道基本的基本对象类型——int、uint、float、strings……——是通过复制传递的。

4

4 回答 4

16

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

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

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

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

于 2010-08-24T08:49:33.850 回答
11

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

有关详细信息,请参阅 MSDN 。

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

于 2010-08-24T08:47:27.783 回答
3

一般来说,

  • value types,其中包括本机类型(int, float, ...)以及structs “按副本”传递(如您所说),而在

  • 引用类型,其中包括classes,只复制一个引用而不是完整的对象。

但是请注意,该字符串不是“通过复制”传递的!它是一个引用类型,但由于它是不可变的,它的行为类似于值类型

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

于 2010-08-24T08:48:32.647 回答
2

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

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 声明为类,则对 Code 的引用是相同的。

于 2010-08-24T09:07:36.723 回答