C#-char类型的⼀些介绍
Char
C#⾥⾯的char,其实就是System.Char类型的别名,它代表⼀个Unicode字符(是这样吗?),占⽤两个字节。
例如:char c = ‘A’;
char占⽤两个字节,也就是16位,其实本质上char其实就是16位的⽆符号整型数值,范围是0到65535,也就是和⽆符号short的范围是⼀样的。
转义字符
有⼀些字符⽆法通过字⾯的意思来进⾏解释,这时候就可以使⽤转义字符。
转义字符是以 / 开始,后边跟着⼀个有特殊意义的字符。
例如:
char newLine = '\n'; 这个表⽰换⾏
char backSlash = '\\'; 这个就表⽰ \
转义字符的列表如下:
还有\u(\x)这两个转义字符可以让你通过4位16进制的形式来表⽰任意的Unicode字符,例如:
char copyrightSymbol = '\u00A9'; // ©
char omegaSymbol = '\u03A9'; // Ω
char newLine = '\u000A'; // 换⾏
转换
char类型的变量可以隐式的转换到可容纳⽆符号short类型的数值类型,例如:
字符扩展
char只能代表⼀个Unicode字符, 其实这句话不太准确。
我们知道Unicode⾥ 65 代表着字母 A,但其实65是A的Unicode代码点,通常是这样来表⽰的 U+0041,16进制的41就是10进制的65。
⽽看这个例⼦,德语⾥⾯有个字符:ß,它的UniCode是 U+00DF,但就其本⾝⽽⾔,ß 不是⼀个字母,ß被认为等价于ss(也就是两个s),例如fußball就相当于fussball。
⽽⽤在字符/字符串⽐较的时候,就不可以把ß当作⼀个字符来处理,⽽是把ß=ss。
⽽ß所对应的U+00DF这个代码点就是字符扩展(Character expansion)的⼀个例⼦,如果想正确的⽐较字符/串,那么这个代码点就必须先转化为其它的多个代码点,这⾥就是 U+00DF -> U+0073 + U+0073,也就是ß -> ss,记住,这只是⽤于⽐较,⽽不是展⽰。
字符代理
字符代理(char surrogates),和字符扩展正好相反。
字符扩展是指,⼀个字符代表了多个实际的字符;⽽字符代理呢,就是使⽤两个char的实例来表⽰⼀个实际的字符。
字符代理之所以存在,是因为它的范围太⼩了(0-65535),所以根本⽆法代表世界上这么多语⾔的字符。实际上Unicode的代码点是从0到1114111(0x10FFFF),所以16位的存储远远不够⽤。
正是因为这点,Unicode UTF16有⼀个可以表⽰所有字符的体系,就是使⽤两个连续的16位数值来表⽰,这就叫做代理对(surrogate pairs)。
在这两个连续的16位数值⾥,第⼀个数的范围是U+D800到U+DBFF(55296到56319),所以如果您在
解析字符/串的时候,解析出来的数值正好落在这个范围⾥,那么你就需要把这个char和它后边的char连在⼀起进⾏解析,才能得出真正要表⽰的字符。
从术语上讲,第⼀个16位数叫做High Surrogate(⾼代理项),第⼆个数叫做Low Surrogate(低代理项)。
例如:  它的Unicode 代码点是 U+1D11E,它包含⼀个High Surrogate:U+D834 和⼀个Low Surrogate:U+DD1E
合并字符
此外有⼀些代码点还会修改前⼀个字符,⽐如说 ä 这个字符,它可以⽤U+00E4来表⽰。
⽽我也可以使⽤ a +  (U+0061 + U+0308)的形式来表⽰该字符,在这⾥U+0308就表⽰两个点,它会修改前⼀个字符。
在Unicode的标准中,后边这个字符就叫做 Combining diaeresis(组合⽤分⾳符?)
⽽在实际中字符/串⽐较的时候,你需要把这两个字符合并当作U+00E4才可以。
其它
char有ToUpper()和ToLower()两个⽅法可以变换⼤⼩写,它们⾸先会遵循⽤户的locale(区域设置),但是这就有可能引起⼀个bug:char.ToUpper ('i') == 'I'
这个表达式在⼟⽿其语⾥⾯会返回false。
在⼟⽿其语⾥⾯ i 被 ToUpper()之后返回的是 İ (看起来像⼤写的I上⾯还有⼀个点),所以与⼤写的 I 不等。
⽽char也提供了不依赖⽤户区域的版本:
char.ToUpperInvariant ('i')
char.ToUpper ('i', CultureInfo.InvariantCulture)
这两种写法都可以。
另外⼀点需要注意的是,从整型转换到char类型后,很有可能变成⼀个超出了Unicode范围的字符,这样的字符就是不合理的。
为了验证字符是否合理,我们可以使⽤ char.GetUnicodeCategory()⽅法,如果结果是UnicodeCategory.OtherNotAssigned,那么该字符就不合理。unicode字符的种类有