String 和 string

如果你是个C#初学者,也许你曾经怀疑过这个
问题:「书上不是说C#是个大小写有别的语言
吗 那为什麼这两个程式都可以跑 」
using System;
class Class1
{
static void Main(string[] args)
{
string s = "I love dotspace.";
//这个string是小写开头
Console.WriteLine(s);
}
}
using System;
class Class1
{
static void Main(string[] args)
{
String s = "I love dotspace.";
//这个String是大写开头
Console.WriteLine(s);
}
}
事实上,这两个程式不但都能跑,如果你使用
ildasm来看这两段程式码编译出来的IL码的
话,你还会发现这两个程式根本就产生了一模一
样的IL码.这到底是怎麼一回事呢,这两段程
式码究竟有没有差别呢
内建型别(Predefined Type)
按照坊间升研究所补习班教的答题技巧指导来
看,若这一题只有10分,答案应该是「String
指的是System.String类别,而string则是C#内
建的关键字.事实上,string正是对应到
System.String类别,也可说string是System.String
类别在C#中的化名(alias),因此两段C#程式码
都会编译出相同的IL码,对於CLR而言这两者
是没什麼差别的.」
若是这题被配了有40分呢 那也许我们得由什
麼叫做内建型别(Predefined Type)谈起.
内建型别,又称做原生型别(Primitive Type),顾
名思义就是一个语言内建的型别.也就是说,一
个符合该语言标准的编译器,应该要能直接支援
这种型别.一般来讲,这意味著该语言应该会为
该型别规范出一个语言关键字,而编译器要能认
得这个关键字并在编译时产生适当的码.以C#
来说,像是整数(int),浮点数(float),字串(string)
等都是内建型别,你可以直接使用这些关键字撰
写你的程式,而C#编译器将能看懂这些关键字
并为你编译出适当的IL码供执行之用.这边还
有个比较不严谨的简陋讲法,「程式语言有提供
化名(alias)的型别就是该语言的内建型别了」.
为什麼需要内建型别呢
为什麼要让编译器支援这些关键字来对应这些
型别呢 有一个原因是因为这些型别实在太常
用了,透过这样的方式会方便许多.当你想要用
一个变数来储存年龄时,你想要怎麼写呢 是
int age = 20;
还是
System.Int32 age = new System.Int32();
age = 20;
毕竟整数,浮点数,字元,字串等型别在程式中
实在太常用了.如果每次都得来一行
System.Int32 age = new System.Int32();
实在吃不消不是吗
此外,内建型别也意味著编译器在设计时就已经
了解这些型别的实作细节,所以编译器对於内建
型别可以有更多的处理知识,因而能更有弹性且
有力的处理这些型别.举例来说,在使用内建型
别时我们可以不用new来new去,一行
int i = 10;
就通通搞定.而在将精度较低的内建型别转型至
精度较高的内建型别时我们可以不需多做指示
地让它隐式转型(Implicit cast):
int i = 20;
double j = i;
请注意,这和衍生类别能自动向上转型(upcast)
为基底类别的情况并不一样,因为int并不是继
承double而来,他们都是继承自
System.ValueType,换言之,在继承体系之中,
他们俩是平行的.此例之中int之所以能自动地
转型成double乃是因为编译器知道int和double
这两个内建型别是做什麼用的,并判断出可以无
害的将int转型为double,因此能顺利编译过关
且正常运作.
那麼,到底要String还是string
现在,你应该已经知道什麼叫内建型别,也了解
Stringstring到最後都是一样的,因为这两
种程式码都会产生相同的IL码.那麼,我们到
底应该使用哪种风格来撰写程式呢 在C#语言
规格书1.2.1中是这样说的:「As a matter of style,
use of the keyword is favored over use of the
complete system type name.」很明显地它的建议
是使用关键字.不过相反的主张也有人支持,基
本精神是认为使用FCL名称会使程式较为清
楚,因为同一个FCL型别在不同语言也许会使
用不同的别名(alias),或是相同的别名在不同的
程式语言中可能会对应到不同的FCL型别,使
用FCL名称可以避免必须使用多种语言工作或
不熟悉此语言的程式设计师产生混淆.举例来
说,如果程式中是清清楚楚的宣告成Int32,那
无庸置疑地这个变数就是Int32.但若是宣告为
long,那在某些语言可能是对应到Int32,有些则
是对应到Int64.基本上,我个人是觉得两种风
格间没有明显优劣差异,所以依你自己的喜好择
一即可,唯一的建议是「最好不要混用」.混用
会导致程式风格混乱,在阅读和维护上都有可能
造成困扰.
结语
本文有点小题大作地讨论了内建型别相关的议
题,看完本文後您应该了解了何谓内建型别,以
及它存在的理由,也了解到在C#中使用语言关
键字或是FCL类别名称宣告变数对底层而言都
是一样的.当然,也知道了为什麼写String
string都可以.

posted on 2008-01-09 13:40  小子好黑  阅读(370)  评论(0编辑  收藏  举报

导航