我对C#有点新,只是想知道是否有一个类(常用)列表,默认情况下作为副本传递。我如何识别它们?
我知道基本的基本对象类型 - int,uint,float,strings,... - 是通过副本传递的。
答案 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)
一般来说,
值类型,其中包含原生类型(int
,float
,...)以及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的引用是相同的。