经常在.NET/C#相关的资料中看到一个词: "Primitive type", 但是技术作家或译者都在以一种不那么严谨的方式在使用这个词, 似乎它的意思是不言自明的.
C#中可以直接使用 int, long, char来定义一个简单类型, 这3个无疑属于 primitive type, 容易形成的模糊印象是:
编译器parse 源代码时直接支持其类型的某种简写形式的类型是primitive type. 比如int是对System.Int32的简化
"简单"类型是primitive type.
primitive type都是value type.
但论及C#中类型的资料都会接下来说到 value type, reference type, 那么 primitive type又跟这两种非此即彼的分类法有什么关系, 一个疑问是:
string 也是个 reference type(别奇怪, 我保证)
但看起来它也是由C#编译器直接支持的关键字, 它的使用频率不亚于int, 好象也应该是 primitive type.
想搞清楚定义当然要找<<
C# Programming Language>>, 作者是C#设计者本人, 但奇怪的是, 这本书中仅有两处用到了 primitive这个词:
而且, 没有对什么是 primitive types作出定义. 也是以一种随意的方式在使用, 没把它当成专有术语.
同样是该书, 把上面提到的int, long之类称为"simple type":
注意这里有13个, 简单类型显然必需是值类型, 因为简单即是相对引用类型在内存管理的复杂性上而言.
接近于给出定义的是牛人 Jeffrey Richter 在MSDN上的一篇文章中给出的:
这个词的概念至此慢慢清晰起来:
所谓primitive , 在金山词霸里的意思摘录如下:
"天生"的意思最为接近, 翻译Jeffrey Richter的Applied .NET Framework第一版的 李建忠译为"基元"类型, 我觉得"原生"更能传达这个意思. 所谓"天生", 所谓"属于自然力量" 在C#的语境里就是编译器所直接支持, 它的力量来自C#编译器, 不是大自然, 因为编译器为它们提供了来自 CTS类型系统中的别名. 如果仅从这一点来理解, 事情就简单了. 但是根据这个定义, 前面列出的13个类型并没有列出所有的 primitive type, 除此之外还有 string和object, 注意这两个可都是reference 类型, 这首先打破了第一个容易形成的错误印象:
- primitive type都是值类型, 或primitive type都是简单类型.
另一本书:
|
by Richard Conway et
al. |
ISBN:1590592573 |
Apress © 2003 |
的第一章有一个小标题, 也是专述 Primitive types:
注意这里列出的是15种类型, 多了object和string, 这个结果跟Jeffrey Richter的定义是一致的. 但这本书中没有类型定义的方式来说明什么是primitive type, 而是列举所有的primitive type, 然后说明其特征, 它总结说这个类型享有来自语言本身的直接支持:
- Literal syntax 字面值语法
- Operator support
依我看, 操作符支持不能算, 因为C#也支持操作符重载, 自定义类型包括值类型也可以重载操作符, 比如Size类型, 是值类型, 不是primitive 类型, 但是也可以直接使用+号操作符.
这本书里有一句话类似于Jeffrey Richter的定义:
Each of these primitive types is actually just a synonym for a standard type in
the .NET Framework's
System namespace.
结论:类型分类
至此, 要对C#中类型进行分类, 可以根据不同的分类标准来:
值类型, 或引用类型, 非此即彼, 两者合在一起构成类型的全集.
primitive 类型, 或非 primitive 类型.
把这看成两种不同的分类标准就好办了, 不如此, 就会出现类似下面的情形:
男人, 女人
老年人, 非老年人
讨论primitive 是否一定是值类型, 正如讨论老年人是否一定是男人一样.
澄清概念的命题陈述
- primitive type是指编译器由提供类型别名的某个CTS类型, 其中包括值类型和引用类型
- primitive type不一定都是符合CLS规范(用于保证不同.NET语言互操作性), 如decimal
- 对primitive type提供的特别的通过字面值来构造类型的语法只是语法上的方便
正如Jeffrey所说,
int i = 5;
与
System.Int32 i = new System.Int32(5);
在编译后生成的IL代码是一样一样一样的.
来自微软的矛盾
下面的内容来自MSDN中Type.IsPrimitive 这个Property:
注意这里没有用etc, 而且全部列举, 特别注意没有string和object, 而且, 没有decimal. 总共12个.
Type类在类库中绝不是一个可有可无的角色, 其IsPrimitive属性这么定义显然更具说服力. 因为C# spec的ECMA规范中也只是在少数几处使用primitive, 并没有定义.
下面是实测结果:
代码如下:
//Purpose: test what is a primitive type
using System;
using System.Reflection;
using System.Diagnostics;
namespace Slimzhao.Csharp.Test.PrimitiveType
{
class Test
{
public static void Main(string[] args)
{
try
{
string[] type_names = {
"System.Int16",
"System.UInt16",
"System.Int32",
"System.UInt32",
"System.Int64",
"System.UInt64",
"System.Byte",
"System.SByte",
"System.Char",
"System.Boolean",
"System.Single",
"System.Double",
"System.Decimal",
"System.String",
"System.Object",
};
int i = 1;
foreach(string type_str in type_names )
{
Type t = Type.GetType( type_str );
Console.WriteLine( string.Format("{2,-3} {0,-15} is {1,-5}primitive type.", t,
t.IsPrimitive
? ""
: "not "
, (i++).ToString() + "."
) );
}
}
catch(Exception e)
{
Console.WriteLine( e.ToString() );
}
}
}
}
|
阅读(2314) | 评论(0) | 转发(0) |