我一直在尝试理解Java和C#中“原语”的使用以及它们之间的区别(如果有的话)。我已经提出了一系列关于SO的问题,一些答案似乎混淆了问题而不是澄清它。一些答案(和一些MS文档)似乎提供了相互矛盾的陈述。来自SO
来自MS:http://msdn.microsoft.com/en-us/library/ms228360%28VS.80,lightweight%29.aspx
- “结构与类非常相似”
- “Int32
类包装int
数据类型”
- “另一方面,C#中的所有原始数据类型都是System命名空间中的对象。对于每种数据类型,都提供了一个简短的名称或别名。例如,int
是System的简称。的Int32" 。
我的困惑主要在于C#(我已经编程了一段时间)。
编辑以下段落已被@Jon Skeet确认为正确
编辑 @Jon已就C#发表了非常明确的声明,因此我将删除我建议的真相,并参考他的回答。
进一步的问题:对于这些术语的实际用途,应该达成共识吗?如果达成共识,我将非常感谢它明确阐述。否则我认为术语混乱,因此使用有限。
摘要感谢您提供非常明确的答案。在那些真正理解这一点并且MS文档是一致的人之间存在共识(参见@Jon接受的答案)(尽管他们在某些地方引用了Java并且我误读了这些用于C#)
答案 0 :(得分:12)
我没有看到MS文档对此存在矛盾(MSDN有时是错误的,但在这个具体问题上,我一直认为它是正确的)。您发布的MSDN链接说:
对于Java中的每种原始数据类型, 核心类库提供了一个 将它表示为的包装类 Java对象。例如,Int32 class包装int数据类型,以及 Double类包装双数据 类型。
另一方面,所有原始数据 C#中的类型是系统中的对象 命名空间。对于每种数据类型,简短 提供名称或别名。对于 instance是int的简称 System.Int32和double是简短的 System.Double的形式。
基本上,它说的是对的。在Java中,Integer
类是int
基元类型的包装器。在C#中,int
是System.Int32
结构的别名。第一段是关于Java而不适用到C#。
在.NET中,术语如下:
基元类型是将IsPrimitive
property设置为true的类型。原始类型是:
基元类型是布尔值,字节, SByte,Int16,UInt16,Int32,UInt32, Int64,UInt64,IntPtr,UIntPtr,Char, 双,单。
所有原始类型都是值类型,但反之亦然。
值类型是type that has value semantics, as opposed to reference semantics。通过值(而不是其引用)传递时复制整个值。值类型的局部变量存储在堆栈中。 struct
和enum
是值类型。
如上所述,所有原始类型都是值类型。它们是struct
命名空间中的System
个。在C#,int
,double
等中,关键字基本上是struct
个的别名。
答案 1 :(得分:12)
第一个要点是正确的。
第二个不是:.NET中的the primitive types是布尔,字节,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,IntPtr,UIntPtr,Char,Double和Single。结构不能通常设置为null
,但也有可空的值类型(Nullable<T>
)。这些仍然是值类型,但C#中的语法糖将“null”等同于“类型的空值”,对于可空值类型,HasValue
返回false的实例。
int
和System.Int32
是 C#中的完全同义词。前者只是后者的别名。他们编译为完全相同的代码。
在C#中,类和接口始终是引用类型。结构和枚举是值类型 - 但是每个结构都有一个盒装等价物(除了Nullable<T>
,CLR在装箱方面有不同的处理方式)。盒装类型没有单独的名称,并且不能在C#中显式引用(尽管它们可以在C ++ / CLI中)。在.NET中没有单独的包装类,如java.lang.Integer
。引入这样的类是有问题的,因为你可以在.NET中创建自己的值类型,这与Java不同。
有关参考类型和值类型的详细信息,请参阅my article about it。