字符串是原始类型吗?


70

我对字符串和原始类型感到好奇。文章像这样说字符串是基本类型。但是,有关MSDN的第二篇文章并未将字符串列为原始类型。

但是,当我运行第二篇文章中提供的代码时,它显示String不是Primitive type

有人可以指导我吗?


4
您可以随时尝试第二篇文章的代码示例并亲自发现。
凯特,2010年

我尝试了代码,它显示字符串不是原始类型
Ram 2010年

11
@kyte:我相信OP希望对MSDN上的两个Microsoft官方页面对string是否为原始类型有不同的意见。如果没有有效的论点,告诉他只使用其中一个来源不是很有帮助
Isak Savo 2010年

那么X类型是原始类型,Y类型不是原始类型,那又是什么呢?我很挑衅,但出于好奇,您真正要确定的是什么?
smirkingman

Answers:


48

这两篇文章都说字符串不是原始类型。不是。

如果编译并运行第二篇文章中的示例代码,它将打印:

字符串不是原始类型。

我认为对此感到困惑的是,创建新字符串的语法类似于创建值类型。

在定义值类型时,所有这些都是相等的(无论如何在32位系统上)

System.Int32 a = new System.Int32(5);
System.Int32 a = 5;
int a = 5;

就像在创建引用类型字符串时一样:

System.String s = new System.String(new char[]{'h', 'e', 'l', 'l', 'o'});
System.String s = "hello";
string s = "hello";

同样,即使它们是引用类型,我们也可以按值比较字符串:

s == "hello";//true

这仍然不会使字符串成为原始类型。

问题的公认答案应为您提供详细信息。


4
如果您看到第一篇文章,则说Visual Basic .NET定义了以下原始类型:列出:String引用类型,它表示Unicode字符序列并映射到System.String。字符串类型的默认值为空引用。
拉姆

1
@Ram-但是您已经将此问题标记为C#...在很多地方,VB使用的解释略有不同。(澄清; [vb.net]标签稍后添加)
Marc Gravell

@ Marc-感谢您指出。我已包含VB.NET标签。我只想知道C#和VB.NET基本类型之间是否有任何区别。
拉姆(Ram)2010年

5
@Ram-它们是完全相同的类型,因此没有实际差异。如果VB要调用字符串原语,则可以。但这并不能使其成为.NET原语。
马克·格拉韦尔

47

没有关于基本类型的“ Microsoft”定义。

在给定的上下文中只有原始类型的定义。

  • CLR将基本类型定义为:
    • System.Boolean
    • System.Byte
    • System.SByte
    • System.Int16
    • System.UInt16
    • System.Int32
    • System.UInt32
    • System.Int64
    • System.UInt64
    • System.IntPtr
    • System.UIntPtr
    • System.Char
    • System.Double
    • System.Single
  • VB.NET规范版本10(在7.3节中)将“原始类型”定义为具有该类型的关键字别名的类型(从而允许在不导入System名称空间的情况下使用该类型),这是一种定义该类型实例的方法用文字 并允许将这些类型用作常量;VB.NET中的原始类型是:
    • System.Byte
    • System.SByte
    • System.UInt16UShort
    • System.Int16Short
    • System.UInt32UInteger
    • System.Int32Integer
    • System.UInt64ULong
    • System.Int64Long
    • System.Single
    • System.Double
    • System.Decimal
    • System.Boolean
    • System.DateTimeDate
    • System.Char
    • System.String
  • C#规范(版本4)定义了某些类型的关键字别名,还定义了为某些值指定文字的方式。它还分别定义了常量表达式中可用的类型;C#拥有的与“原始类型”最接近的概念在第4.1.4节:简单类型中。(“原始”一词在600页的文档中仅使用了两次);这些原始类型被简单地定义为“在C#中具有关键字别名的值类型”-string在该部分中未提及:

    • System.SBytesbyte
    • System.Bytebyte
    • System.Int16short
    • System.UInt16ushort
    • System.Int32int
    • System.UInt32uint
    • System.Int64long
    • System.UInt64ulong
    • System.Charchar
    • System.Singlefloat
    • System.Doubledouble
    • System.Booleanbool
    • System.Decimaldecimal

您会发现所有这些东西之间只有部分重叠;CLR将两种指针类型都视为原始类型,VB.NET和C#均将十进制视为原始/简单类型,只有VB.NET将DateTime视为特殊的东西,VB.NET和C#均具有关键字别名和字符串的文字语法但只有VB.NET将其指定String为“原始类型”,而C#仅将其规范的一部分专门用于System.String...

结论:不同的上下文对“原始类型”是什么有不同的定义。没关系-只要学习如何使用您的编程语言,就不必为此类多态单词而斗争和思考。就个人而言,我想知道为什么该财产Type.IsPrimitive甚至存在。

至于System.String

  • CLR:没什么特别的,它只是一个引用类型。
  • VB.NET:它是原始类型;
  • C#:String是它自己非常特别的雪花;

1
对于CLR,我认为这不是String“只是另一种引用类型”。字符串和数组是唯一其大小不受其类型暗示的对象。此外,我相信string是运行时在加载程序集时会自动生成包含该程序集中存储的数据的实例的唯一类型。
超级猫

该部分未提及“在C#中具有关键字别名的值类型”-字符串。好吧,字符串毕竟是引用类型。
亚历山大·贡奇

我试图理解CLR,VB.NET和C#之间的“ IsPrimitive”差异的含义。例如,如果我用C#编写的代码包含基于对象的原始类型的条件,并且我的单元测试断言它对于DateTime(C#认为不是原始的)可以按预期工作。然后,我编译了一个由开发人员使用VB.NET引用的DLL(它认为DateTime是原始的),我的DLL的行为是否会有所不同(换句话说,仅在C#上下文中值得进行单元测试,这是没用的) )?
马特2015年

2
@Matt:该IsPrimitive函数具有相同的行为,无论从哪种.NET语言调用它,它都是CLR定义。
Jean Hominal

IMO,这是更好的答案。更好地强调CLR,C#和VB.Net之间的差异。在评论中还指出,IsPrimitive是基于CLR行为的,这很有意义并且很容易理解。
Landon Poch 2015年

9

立场变更更新:否,因为代码没有说谎

Console.WriteLine(typeof(string).IsPrimitive); => False
Console.WriteLine(typeof(int).IsPrimitive); => True

-----更新结束。
但是一些在线文档似乎将String视为原始类型。我认为-基于以下“原始”定义。(我的个人定义将是无法进一步细分为组件类型的类型。但是我想我们在这里只是“学究”,对我来说这大部分不是问题。)

C#中的所有原始数据类型都是System名称空间中的对象。对于每种数据类型,都提供了简称或别名。

来源:http : //msdn.microsoft.com/zh-cn/library/ms228360%28VS.80%29.aspx 另一篇赞成的文章-MSDN Mag文章

简介:我想答案取决于您对基本类型定义,该定义不是明确定义的。来源:Eric Lippert在另一个SO线程上。


根据您的定义,我猜只有一点是原始的吗?;-)(例如,Int32最多堆叠4个字节)
Isak Savo 2010年

1
该定义并不意味着System名称空间中的所有类型都是基元(我可以System在程序集中的名称空间中添加类型,所以它们将成为基元吗?),它只是说明所有现有的基元类型都可以在System其他地方找到。
最大

@Isak-您可以采取任何极端指导:)在大多数情况下,从Int中取出第3个字节没有单独/特定的用途。从组合的Address类型中获取FirstName确实可以。所以Int对我而言将是原始的。地址不会。
Gishu 2010年

@max-我还为该类型包括了语言定义的别名-因此String具有别名字符串。System名称空间中的自定义类型将没有一个AFAIK。
Gishu 2010年

@gishu:是的,我知道,我故意将其发挥到极致。我会说,提取一个int的第三个字节与提取一个字符串的第三个字符一样普遍-我偶尔都会做。我给你+1为您总结,因为这对现货-似乎没有人能够清楚地界定什么原始的手段
伊萨克萨沃

5

.NET定义(摘自您的文章):

基本类型为布尔,字节,字节,Int16,UInt16,Int32,UInt32,Int64,UInt64,Char,Double和Single。

所以不行。内置且非常重要:是的,但不是原始的。

VB使用的定义似乎与CLI和C#略有不同。


IntPtr的也是基本类型
Esperadoce

@Esperadoce同意了,但是我引用了OP的链接文章
Marc Gravell

3

根据Microsoft对“原始”的定义,字符串不被视为原始类型。另一方面,Microsoft倾向于使用术语而不真正制定清晰或一致的定义(例如“非托管资源”),并且可以有效地将“原始”定义为包括“字符串”,“数组”和“对象”,因为如果没有它们,将无法定义可以有效模拟它们的类型。


好答案。VB.NET也认为DateTime是原始的,按照我的观点也可以。
nawfal 2014年

2

不,字符串不是原始类型。

但是,它具有原始类型共有的一些特征。

该语言在代码中支持字符串文字,因此您不必String使用new关键字显式创建实例即可获取字符串对象。

还支持使用+运算符连接字符串,编译器将其转换为对该String.Concat方法的调用。

字符串是不可变的,这意味着它在大多数情况下都具有值类型语义,就像原始类型一样。


那为什么不是原始的呢?我的意思是其他原始类型没有什么特征?
Isak Savo 2010年

我的意思是您说它不是原始类型,但随后列出了可能认为它应该称为原始类型的内容。您从未提及过为什么它不是原始类型。(我很感兴趣,但我不是最不赞成的人)
Isak Savo 2010年

@Isak Savo:基本类型是处理器可以本地处理的值。处理器具有添加双打的指令,但没有字符串。
Guffa

1

字符串是一种特殊的原始类型。它不是值类型,但是可以视为原始类型,因为可以通过编写文字(例如/“ hello”)来创建它,并且可以声明字符串类型的常量。话虽如此,IsPrimitive的值返回false

Console.WriteLine("hello".GetType().IsPrimitive) // output = False

编辑:我想在这里取回我的答案。从技术上讲,它不是原始类型,但是具有我上面提到的属性。


我建议原始类型的有用定义应该包括一些东西,如果这些东西如果没有由编译器和运行时明确处理,则不能在用户代码中有效地进行仿真。根据该定义,字符串和数组将是原始类型,因为它们具有特殊的处理方式,这与用户代码无法执行的任何操作不同。
2012年

1

在c#中,类型主要定义为两种类型:值类型和原始类型。

首先看一下C#中基本类型的定义

另一方面,C#中的所有原始数据类型都是System名称空间中的对象。对于每种数据类型,都提供了简称或别名。例如,int是System.Int32的缩写,而double是System.Double的缩写。

现在,请阅读这篇文章以了解它们之间的区别:原始类型和值类型

System.String映射到“ string”,这是CLI中的原始类型。但实际上,值类型是在堆栈中而不是在堆空间中的类型。

因此,关键是值类型与原始类型。按照Microsoft对原语的定义,它是一种原语类型,但从更一般的意义上讲,它不是。


1
值类型和原始类型?也许您是指引用类型
亚历山大·贡奇


-2

它们不是,因为它们是字符序列


4
您应该多备份一些答案,这样才有价值
JMax 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.