目录
[1. 字面量创建:最基础的字符串定义](#1. 字面量创建:最基础的字符串定义)
[4. 其他创建方式:构造函数与工具类](#4. 其他创建方式:构造函数与工具类)
[5.使用进行字符串插值,格式化](#5.使用进行字符串插值,格式化)
[2.string.IsNullOrEmpty(string value)(判断空或 null)](#2.string.IsNullOrEmpty(string value)(判断空或 null))
[3.string.IsNullOrWhiteSpace(string value)(判断空、null 或空白)](#3.string.IsNullOrWhiteSpace(string value)(判断空、null 或空白))
[2.null 和 Empty的区别](#2.null 和 Empty的区别)
一、字符串的创建
1. 字面量创建:最基础的字符串定义
通过双引号 "" 直接包裹文本,是C#中最常用的字符串创建方式,自动加入字符串池(内存复用优化)。
核心特点
不可变性:字符串内容创建后无法修改,修改会生成新字符串。
内存服用:相同字面量会指向字符串池中的同一内存地址(需开启字符串池,默认开启)。
示例:
string greeting = "Hello World"; // 字面量创建,存入字符串池
string sameGreeting = "Hello World"; // 复用池内地址,greeting == sameGreeting 为 true
2.字符串中的特殊符号:转义字
|------|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 转义字符 | 含义 | 示例 |
| \n | 换行 | "第一行\n第二行" |
| \t | 制表符(Tab) | "姓名\t年龄" |
| \r | 回车,控制光标位置(回车不换行) | Console.Write("123\r45"); // 输出:453("123"被"45"覆盖前两个字符) |
| \s | 空格,匹配任意空白字符 | string input = "Hello\tWorld\nC#"; // 匹配所有空白字符并替换为"-" string result = Regex.Replace(input, @"\s", "-"); Console.WriteLine(result); // 输出:Hello-World-C# |
| \0 | 空字符 | "A\0B"(输出为"A B") |
| \\ | 反斜杠(路径等) | "C:\\Program Files\\" |
| \" | 双引号(字符串内) | "他说:\"你好\" " |
3.使用@创建逐字字符串:忽略转义
在字符串前加 @,可禁用转义字符,保留原始格式(适合路径、正则表达式等场景)。
核心特点:
反斜杠 \ 不再是转义符,直接显示。
双引号需用两个 "" 表示(而非 \")。
示例:
string path = @"C:\Users\Alice\Documents"; // 无需转义反斜杠
string regex = @"^\d{3}-\d{8}$"; // 正则表达式无需转义
string quote = @"他说:""你好"""; // 双引号用""表示
4. 其他创建方式:构造函数与工具类
除字面量外,可通过string类的构造函数或静态方法创建字符串:
构造函数创建(从字符/字节数组):
char[] chars = { 'H', 'e', 'l', 'l', 'o' };
string fromChars = new string(chars); // 从字符数组创建 byte[]
bytes = Encoding.UTF8.GetBytes("Hello");
string fromBytes = Encoding.UTF8.GetString(bytes); // 从字节数组创建
工具类拼接(`String.Join`/`String.Concat`):
string[] parts = { "I", "love", "C#" };
string joined = string.Join(" ", parts); // 结果:"I love C#"
string concatenated = string.Concat("a", "b", "c"); // 结果:"abc"
5.使用$ 进行字符串插值,格式化
示例:
string name = "小天";
int age = 3;
// 基本变量插值
string greeting = $"你好,我是{name},今年{age}岁~";
Console.WriteLine(greeting); // 输出:你好,我是小天,今年3岁~
// 表达式插值(支持运算、方法调用等)
string calc = $"1+1={1+1},字符串长度:{name.Length}";
Console.WriteLine(calc); // 输出:1+1=2,字符串长度:2
二、字符串的属性
在 C# 中,字符串(string 类型)是不可变的引用类型 ,其属性和方法主要用于查询字符串状态 或转换字符串内容(所有修改操作都会返回新字符串,原字符串保持不变)。以下是最常用的核心属性:
实例属性
++1.Length(最常用)++
类型:int
用途:获取字符串的字符个数。(包括空格和符号)
示例:
string text = "Hello World!";
int length = text.Length; //结果:12(包含空格和感叹号)
++2.Chars(索引器)++
类型:char(通过索引访问)
用途:获取字符串中指定位置的字符。(索引从0开始)
示例:
string text = "Hello World!";
char firstChar = text[0]; // 'H'(第1个字符)
char lastChar = text[text.Length - 1]; // '!'(最后1个字符)
静态方法与属性(针对字符串类型本身)
这类属性/方法需通过string 类型名调用,用于处理通用字符串逻辑(如空值判断)。
++1.string.Empty(空字符串常量)++
类型:string
用途:表示空字符串 (""),比直接写 "" 更具可读性。
示例:
string emptyStr = string.Empty; // 等价于 "",但语义更清晰
++2.string.IsNullOrEmpty(string value)(判断空或 null)++
类型:bool**(静态方法,非属性)**
用途:检查字符串是否为**null** 或空字符串 ("")。
示例:
bool isEmpty = string.IsNullOrEmpty(""); // true
bool isNull = string.IsNullOrEmpty(null); // true
bool hasValue = string.IsNullOrEmpty("Hi"); // false
++3.string.IsNullOrWhiteSpace(string value)(判断空、null 或空白)++
类型:bool**(静态方法)**
用途:检查字符串是否为 null、空字符串,或仅包含空白字符 (空格、换行符 \n、制表符 \t 等)。
示例:
bool isWhiteSpace = string.IsNullOrWhiteSpace(" "); // true(全是空格)
bool isNewLine = string.IsNullOrWhiteSpace("\n"); // true(换行符)
关键注意点
++1.字串符不可变性++
所有属性(如 Length)和方法(如 Replace)都不会修改原字符串,而是返回新的字符串对象。
例如:
string oldStr = "Hello";
string newStr = oldStr.Replace("H", "J"); // newStr = "Jello",oldStr 仍为 "Hello"
++Replace()方法会在下文常用方法中讲解++
++2.null 和 Empty的区别++
定义与本质
-
null:表示变量未引用任何对象(无指向)。- 对于引用类型(如
string、List),null是默认值,意味着变量不指向内存中的任何地址。 - 对于值类型(如
int、DateTime),默认值不是null(需用可空类型int?等才能赋值null)。
- 对于引用类型(如
-
Empty:表示变量引用了一个"空内容"的有效对象(有指向,但内容为空)。- 常见于字符串(
string.Empty)或集合(如List<T>.Empty),指对象本身存在,但内部无数据。
- 常见于字符串(
三、字符串常用方法
static void Main(string[] args)
{
//字符串常用的方法
//1. 重点IndexOf() 获取字符在字符串当中的索引值 如果找到则返回索引值,找不到则返回值为-1
string str = "abcdefghabc";
Console.WriteLine(str.IndexOf("a"));//0
Console.WriteLine(str.IndexOf("c"));//2
Console.WriteLine(str.IndexOf("g"));//6
Console.WriteLine(str.IndexOf("c",4));//-1 从 参数2 地方开始搜索 参数1,超出索引界限返回-1
Console.WriteLine(str.IndexOf("f", 4));//5
//2. LastIndexOf() '从后往前'获取字符在字符串当中的索引值 获取第一个相匹配的字符
Console.WriteLine(str.LastIndexOf("b"));//9
//3. IndexOfAny() 从字符数组范围内获取任何一个相对应的索引值 顺序从前到后
Console.WriteLine(str.IndexOfAny(new char[] {'c','b','f'}));//1
//4. LastIndexOfAny() '从后往前'从字符数组范围内获取任何一个相对应的索引值
Console.WriteLine(str.LastIndexOfAny(new char[] { 'c', 'b', 'f' }));//10
//5. 重点Contains() 是否包含参数 包含为true 不包含为false
Console.WriteLine(str.Contains("fg"));//true
Console.WriteLine(str.Contains("fe"));//false
//6. 重点ToUpper() 把字符转成大写
Console.WriteLine(str.ToUpper());
//7. 重点ToLower() 把字符转成小写
Console.WriteLine(str.ToLower());
//8. StartsWith() 判断字符串是否以参数进行开头
Console.WriteLine(str.StartsWith("bc"));//false
Console.WriteLine(str.StartsWith("ab"));//true
//9. EndsWith() 判断字符串是否以参数进行结尾
Console.WriteLine(str.EndsWith("bc"));//true
Console.WriteLine(str.EndsWith("ab"));//false
//10.重点 IsNullOrEmpty() 判断字符串是否为null或者空字符串
string str1 = "";
Console.WriteLine(string.IsNullOrEmpty(str1)+"-----");//true
Console.WriteLine(string.IsNullOrEmpty(str)+"-----");//false
//11. Equals() 判断两个参数是否相等(参数为字符串)
Console.WriteLine(string.Equals(str, str1));//false
//12. Join() 把指定符号添加到多个字符串之间
Console.WriteLine(string.Join(" + ", "a", "b", "c")); //a + b + c
//13. 重点Substring() 截取字符串 从输入索引值开始截取 截取输入的第二个参数的长度
Console.WriteLine(str.Substring(2, 3));//cde
//14. 重点Split() 使用指定的符号分割字符串 分割后字符串内容为数组
string str2 = "2025/12/10"; // 可以按照/进行分割,分割成三部分,三部分放到一个数组里面
Console.WriteLine(str2);
string[] ss = str2.Split('/');//结果是一个数组
Console.WriteLine(ss[0]); //2025
Console.WriteLine(ss[1]); //12
Console.WriteLine(ss[2]);//10
//15. 重点Concat() 链接多个字符串
Console.WriteLine(string.Concat(str, str2)); //abcdefghabc2025/12/10
//16. CopyTo() 从原字符串的参数1索引值开始赋值 复制到参数2的char数组中,放到参数2数组中索引值为参数3的位置,复制参数个数为参数4
char[] c1 = new char[15];//定义一个字符数组长度为10
str.CopyTo(1, c1, 5, 6);
for (int i = 0; i < c1.Length; i++)
{
Console.WriteLine(c1[i] + "-----------");
}
//17. 重点Remove() 删除字符 从参数1开始删除,删除个数为参数2,返回结果为剩余内容
Console.WriteLine(str2.Remove(1, 4));
Console.WriteLine(str2.Remove(3));// 只写一个参数的删除到最后 剩余的字符
//18. Replace() 用参数2来替换参数1
Console.WriteLine(str2.Replace("2025", "2026"));
//19. Format() 字符串格式化
string name = "张三";
double gz = 10000;
Console.WriteLine(string.Format("姓名{0};工资{1}", name, gz));
Console.WriteLine(string.Format("{0:c4}", gz));//¥10,000.0000
//20. ToCharArray() 把字符串转换成一个字符数组
for (int i = 0; i < str2.ToCharArray().Length; i++)
{
Console.WriteLine(str2.ToCharArray()[i] + "--------");
}
}
四、示例
01.链接字符串
//封装一个连接字符串,参数为一个参数列表,可以传递任意个的字符串参数 例如Test1("t1","t2") 结果为输出:t1t2
static void Main(string[] args)
{
string[] s1 = new string[4];
Console.WriteLine(" 输入第一个字符串: ");
s1[0] = Convert.ToString(Console.ReadLine());
Console.WriteLine(" 输入第二个字符串: ");
s1[1] = Convert.ToString(Console.ReadLine());
Console.WriteLine(lianJie(s1));
}
public static string lianJie(params string[] str)
{
return string.Concat(str);
}
02.判断字符串开头
++//封装一个函数判断字符串是否以指定字符串开头 传递俩个参数一个是字符串,一个是以xx开头
例如Test1(string b,string v) 判断b是不是以v开头的++
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(" 输入要识别的字符串:");
string a = Convert.ToString(Console.ReadLine());
Console.WriteLine(" 输入要识别内容:(字符串)");
string b = Convert.ToString(Console.ReadLine());
Console.WriteLine(StartWith(a, b));
}
public static bool StartWith(string a,string b)
{
if (b.Length > a.Length) //当 b 的长度超过 a 的长度,直接不是以 b 开头
{
return false;
}
for (int i = 0; i < b.Length; i++) //如果b是多个字符 考虑比较很多次, 需要for循环,需要b长度次数
{
if (b[i] != a[i])//b[i] b其中一个字符 和 a一个字符进行对比 ,只要一个不一样了 return false
{
return false;
}
}
return true;
}
}