C# 中的 bool、char 和 string 类型

上一篇(地址:https://www.vinanysoft.com/c-sharp-basics/data-types/fundamental-numeric-types/)只介绍了基本数值类型,本篇将介绍其他的一些类型: boolcharstring

布尔类型(bool

bool 关键字是 System.Boolean 的别名。 它用于声明变量来存储布尔值:truefalse

可将布尔值赋给 bool 变量。 也可以将计算结果为 bool 类型的表达式赋给 bool 变量。

public class BoolTest
{
    static void Main()
    {
        bool b = true;

        // WriteLine automatically converts the value of b to text.
        Console.WriteLine(b);

        int days = DateTime.Now.DayOfYear;


        // Assign the result of a boolean expression to b.
        b = (days % 2 == 0);

        // Branch depending on whether b is true or false.
        if (b)
        {
            Console.WriteLine("days is an even number");
        }
        else
        {
            Console.WriteLine("days is an odd number");
        }   
    }
}
/* Output:
  True
  days is an  number
*/

虽然理论上一个二进制位足以容纳一个布尔类型的值,但 bool 实际大小是一个字节。

字符类型(char

char 类型关键字是 System.Char 结构类型的别名,它表示 Unicode UTF-16 字符:

类型 范围 大小 .NET 类型
char U+0000 到 U+FFFF 16 位 System.Char

输入 char 字面量需要将字符放到一对单引号中,比如 'A'。所有键盘字符都可这样输入,包括字母、数字以及特殊符号。

有的字符不能直接插入源代码,需进行特殊处理。首先输入反斜杠(\)前缀,再跟随一个特殊字符代码。反斜杠和特殊字符代码统称为转义序列(escape sequence)。

例如,\n 代表换行符,而 \t 代表制表符。由于反斜杠标志转义序列开始,所以要用 \\ 表示反斜杠字符。

Console.Write("\'");    //输出单引号(')
Console.Write("\\");    //输出反斜杠(\)

char 类型字面量可以输入字符、十六进制转义序列或 Unicode 表示形式。 也可以将整型字面量强制转换为相应的 char 值。 在下面的示例中,使用相同的字符 Xchar 数组的四个元素进行初始化:

var chars = new char[4];

chars[0] = 'X';        // Character literal
chars[1] = '\x0058';   // Hexadecimal
chars[2] = (char)88;   // Cast from integral type
chars[3] = '\u0058';   // Unicode

Console.Write(string.Join(" ", chars));
// Output: X X X X

下表列出了字符串转义序列:

转义序列 字符名称 Unicode 编码
\' 单引号 0x0027
\" 双引号 0x0022
\\ 反斜杠 0x005C
\0 null 0x0000
\a 警报 0x0007
\b 退格 0x0008
\f 换页 0x000C
\n 换行 0x000A
\r 回车 0x000D
\t 水平制表符 0x0009
\v 垂直制表符 0x000B
\u Unicode 转义序列 (UTF-16) \uHHHH(范围:0000 - FFFF;示例:\u00E7 =“ç”)
\U Unicode 转义序列 (UTF-32) \U00HHHHHH(范围:000000 - 10FFFF;示例:\U0001F47D =“”)
\x 除长度可变外,Unicode 转义序列与“\u”类似 \xH[H][H][H](范围:0 - FFFF;示例:\x00E7、\x0E7 或 \xE7 =“ç”)

字符串

零个或多个 Unicode 字符的序列称为字符串,C# 的基本字符串类型是 stringstringSystem.String 在 .NET 中的别名。

字面量

为了将字面量字符串输入代码中,要将文本放入双引号(")内。字符串由字符构成,所以转义序列可嵌入字符串内。

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("这是一个字符串");
            Console.WriteLine("这里使用\\n来换行\n这是第二行");
        }
    }
}

输出

这是一个字符串
这里使用\n来换行
这是第二行

C# 允许在字符串前使用 @ 符号,指明转义序列不被处理。结果是一个逐字字符串字面量(verbatim string literal),它不仅将反斜杠当作普通字符,还会逐字解释所有空白字符。

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(@"开始
                                /\
                               /  \
                              /    \
                             /      \
                             --------
结束");
        }
    }
}

输出

开始
                                /\
                               /  \
                              /    \
                             /      \
                             --------
结束

字符串插值

从 C# 6 开始,可以使用 $ 特殊字符将字符串文本标识为内插字符串。内插字符串是可能包含内插表达式的字符串文本。将内插字符串解析为结果字符串时,带有内插表达式的项会替换为表达式结果的字符串表示形式。

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            string name = "Mark";
            var date = DateTime.Now;
            
            Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
        }
    }
}

输出

Hello, Mark! Today is Monday, it's 10:33 now.

字符串插值内部工作原理

字符串插值是调用 string.Format() 方法的语法糖。例如以下语句:

Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");

会被转换成以下形式的 C# 代码:

object[] args = { name, date, time };
Console.WriteLine(string.Format("Hello, {0}! Today is {1}, it's {2} now.", args));

字符串格式化

无论使用 string.Format() 还是 C# 6.0 字符串插值来构造复杂格式的字符串,都可通过一组覆盖面广和复杂的格式化模式来显示数字、日期、时间、时间段等。例如,给定 decimal 类型的 price 变量,则 string.Format("{ 0,20:C2}",price) 或等价的插值字符串 $"{ price,20:C2}" 都使用默认的货币格式化规则将 decimal 值转换成字符串。

即添加本地货币符号,小数点后四舍五入保留两位,整个字符串在 20 个字符的宽度内右对齐(要左对齐就为 20 添加负号。另外,宽度不够只好超出)。

因篇幅有限,无法详细讨论所有可能的格式字符串,请在 MSDN 文档中查阅 string.Format() 获取格式字符串的完整列表。

string.Format() 的链接地址:https://docs.microsoft.com/zh-cn/dotnet/api/system.string.format?view=netcore-3.0

换行符

输出换行所需的字符由操作系统决定。Microsoft Windows 的换行符是 \r\n 这两个字符的组合,UNIX 则是单个 \n。 为消除平台之间的不一致,一个办法是使用 System.Console.WriteLine() 自动输出空行。

为确保跨平台兼容性,可用 System.Environment.NewLine 代表换行符。换言之,System.Console.WriteLine("Hello World")System.Console.Write("Hello World"+ System.Environment.NewLine) 等价。

注意在 Windows 上,System.WriteLine()System.Console.Write(System.Environment.NewLine) 等价于 System.Console.Write("\r\n") 而非 System.Console.Write("\n")

总之,要依赖 System.WriteLine()System.Environment.NewLine 而不是 \n 来确保跨平台兼容。

字符串不可变

string 类型的一个关键特征是它不可变(immutable)。可为 string 变量赋一个全新的值,但出于性能考虑,没有提供修改现有字符串内容的机制。

所以,不可能在同一个内存位置将字符串中的字母全部转换为大写。只能在其他内存位置新建字符串,让它成为旧字符串大写字母版本,旧字符串在这个过程中不会被修改,如果没人引用它,会被垃圾回收。

public static void Main()
{
    string text="abcdefg";

    //UNEXPECTED: Does not convert text to uppercase
    text.ToUpper();

    System.Console.WriteLine(text);
}

输出

abcdefg

从表面上看,text.ToUpper() 似乎应该将 text 中的字符转换成大写。但由于 string 类型不可变,所以 text.ToUpper() 不会进行这样的修改。

相反,text.ToUpper() 会返回新字符串,它需要保存到变量中,或直接传给 System.Console.WriteLine()

正确的字符串处理:

public static void Main()
{
    string text="abcdefg";

    // Return a new string in uppercase
    string uppercase = text.ToUpper();

    System.Console.WriteLine(uppercase);
}

输出

ABCDEFG

System.Text.StringBuilder

如有大量字符串需要修改,比如要经历多个步骤来构造一个长字符串,可考虑使用 System.Text.StringBuilder 类型而不是 string

StringBuilder 包含 Append()AppendFormat()Insert()Remove()Replace() 等方法。虽然 string 也提供了其中一些方法,但两者关键的区别在于,在 StringBuilder 上,这些方法会修改 StringBuilder 本身中的数据,而不是返回新字符串。

总结

bool 类型在条件语句和表达式中表示。允许的值是 truefalse

char 类型表示值介于 0 到 65535 之间的 16 位无符号整数。char 类型的值对应于 Unicode 字符集。

零个或多个字符的有限序列称为字符串。允许使用逐字前缀 @ 指明转义序列不被处理,允许用 $ 前缀进行字符串插值。 最后, string 是一种“不可变” 类型。

你可能感兴趣的:(C# 中的 bool、char 和 string 类型)