Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中,使用值类型与引用类型_C#_Class Design_Value Type_Reference Type - Fatal编程技术网

在C#中,使用值类型与引用类型

在C#中,使用值类型与引用类型,c#,class-design,value-type,reference-type,C#,Class Design,Value Type,Reference Type,我的问题是: 什么时候应该使用值类型,什么时候应该使用引用类型 其中一个的优点和缺点是什么 如果到处都使用引用类型呢?有什么害处吗 还请讨论每种方法的优缺点。我也想了解这一点 对没有自身标识的不可变项使用值类型(1是1),对其他项使用引用类型。您应该对表示值的小型不可变项使用值类型。 对于其他内容,请使用引用类型。 这是我在这一点上的参考。我主要使用引用类型tbh。IE类而不是结构。人们常说的要点是,结构应该只用于小块信息。这取决于具体情况。在对象浏览器中查看一下.net framewor

我的问题是:

  • 什么时候应该使用值类型,什么时候应该使用引用类型
  • 其中一个的优点和缺点是什么
  • 如果到处都使用引用类型呢?有什么害处吗

还请讨论每种方法的优缺点。我也想了解这一点

对没有自身标识的不可变项使用值类型(1是1),对其他项使用引用类型。

您应该对表示值的小型不可变项使用值类型。

对于其他内容,请使用引用类型。


这是我在这一点上的参考。我主要使用引用类型tbh。IE类而不是结构。人们常说的要点是,结构应该只用于小块信息。这取决于具体情况。在对象浏览器中查看一下.net framework会有所帮助,你会看到微软的人做了什么,你可以分析他们为什么创建某些类和结构。

对此似乎有很多困惑,Jon Skeet在他的书《深入C#,第二版》(第2.3节)中很好地澄清了这一点

我个人的方法可能正确也可能不正确,就是只使用结构/枚举(值类型)来表示轻量级的原子数据结构,我知道我将在某种逻辑或数学运算中经常使用这些结构-想想
Point
,等等

这样我就可以避免垃圾收集性能的损失。然而,Jon在他的书的那一部分中指出,没有真正的保证,特别是在运行时的新版本中,是否有什么东西会出现在堆栈上

所以,我最好的答案是谨慎地使用structs之类的东西,如果你这样做的话,要非常清楚为什么要使用它们。小心过早的优化。如果你能拿到一本书,请阅读乔恩书中的那一部分,因为他很好地阐明了整个主题


相关:

不可变值类型和不可变引用类型在语义上几乎相同;唯一的区别是引用类型支持可能有意义也可能没有意义的引用相等性检查,并且值类型可以封装在可为null的(Of T)中,而引用类型可以隐式为null。如果一个类型是不可变的,这取决于它的使用方式,那么可能有性能原因支持结构或类;对于某些操作(对于大小小于4字节的操作,几乎所有操作)而言,结构更快,而对于其他一些操作(尤其是对于大于16字节的操作),类可能会更快。此外,某些类型的操作在结构中基本上是不可能的

可变结构类型是有用的,与一些反对者声称的相反,但也有一些警告。如果有一个变量持有对可变类对象的引用,并且有人做了一些事情来更改该对象,那么所有持有该对象引用的人都将有效地“看到”该更改。如果一个人希望在不干扰其他任何东西的情况下改变一个对象,那么他必须知道他持有对该对象的唯一引用。通常,确保这一点的唯一方法是将对象中的所有数据复制到新的对象实例中,然后对该新实例进行更改。相反,如果一个人有一个可变结构,他可以简单地进行任何更改,而不必创建一个新实例


可变结构的唯一真正问题是.net使用各种抽象使其作为统一类型系统的一部分,而这些抽象可能导致在逻辑上应该使用原始结构的地方使用结构的副本。这些替换发生的时间并不总是很明显,它们可能会导致混淆和错误行为。

字符串应该有标识吗?:)@乔恩-特例。。。有人可能会说字符串应该被实现为值类型。我很想听听你对它的看法。@Jon,考虑到有一个内部字符串池(可以通过
string.IsInterned
)间接访问),有人可能会说字符串确实有某种特殊的标识。@Oded,对于长度不可能知道的字符串,您会在堆栈上保留多少空间?@Oded:如果它们被实现为值类型,那么它们基本上必须是对其他对象的引用——毕竟,字符串的大小在编译时是未知的。它们实际上是引用类型,假装是值类型。我猜他们可能在值中有计数,只需引用数据本身,这在某些情况下可能是有效的…你的帖子没有解释为什么应该使用值类型?如果你不能决定,几乎可以肯定它是一个
。合法地编写结构是非常罕见的。对于土耳其程序员,我有一篇关于它的博客文章