一、啥是C#插值字符串
C#插值字符串是个挺实用的功能,在以前,咱们拼接字符串可能得用加号,像这样:
// C# 技术栈示例
string name = "张三";
int age = 25;
string message = "我叫 " + name + ",今年 " + age + " 岁。";
Console.WriteLine(message);
这代码看着就乱,要是拼接的内容一多,更麻烦。后来有了插值字符串,代码就简洁多了,就像这样:
// C# 技术栈示例
string name = "张三";
int age = 25;
string message = $"我叫 {name},今年 {age} 岁。";
Console.WriteLine(message);
用$符号开头,把要插入的变量用{}包起来,多清晰啊。
二、性能分析
2.1 简单比较
咱先来看个简单的性能对比。以前的字符串拼接方式,每次拼接都会创建一个新的字符串对象,这会消耗不少内存和时间。而插值字符串在性能上就有提升。
// C# 技术栈示例
// 传统拼接方式
string str1 = "Hello";
string str2 = "World";
string result1 = str1 + " " + str2;
// 插值字符串方式
string result2 = $"{str1} {str2}";
在这个简单的例子里,可能感觉不出啥差别,但要是在循环里大量拼接字符串,差别就明显了。
2.2 循环测试
// C# 技术栈示例
using System.Diagnostics;
Stopwatch stopwatch = new Stopwatch();
// 传统拼接方式
stopwatch.Start();
string traditionalResult = "";
for (int i = 0; i < 10000; i++)
{
traditionalResult += i.ToString();
}
stopwatch.Stop();
Console.WriteLine($"传统拼接耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
// 插值字符串方式
stopwatch.Restart();
string interpolatedResult = "";
for (int i = 0; i < 10000; i++)
{
interpolatedResult = $"{interpolatedResult}{i}";
}
stopwatch.Stop();
Console.WriteLine($"插值字符串拼接耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
在这个循环测试中,传统拼接方式会频繁创建新的字符串对象,垃圾回收也得忙活,所以耗时会更多。而插值字符串在编译时会被优化,性能上会好一些。
三、格式化最佳实践
3.1 数字格式化
在插值字符串里,能很方便地对数字进行格式化。
// C# 技术栈示例
double price = 123.456;
// 保留两位小数
string formattedPrice = $"价格是: {price:F2} 元";
Console.WriteLine(formattedPrice);
int number = 12345;
// 用千分位分隔符
string formattedNumber = $"数字是: {number:N0}";
Console.WriteLine(formattedNumber);
3.2 日期格式化
日期格式化也不在话下。
// C# 技术栈示例
DateTime now = DateTime.Now;
// 格式化成年月日 时:分:秒
string formattedDate = $"现在时间是: {now:yyyy-MM-dd HH:mm:ss}";
Console.WriteLine(formattedDate);
// 只显示月份和日期
string shortDate = $"今天是: {now:MM-dd}";
Console.WriteLine(shortDate);
3.3 自定义格式化
要是现有的格式化方式满足不了需求,还能自定义格式化。
// C# 技术栈示例
class CustomFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
return null;
}
public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (format == "CUSTOM")
{
return arg.ToString().ToUpper();
}
return arg.ToString();
}
}
string text = "hello";
string customFormatted = $"自定义格式: {text:CUSTOM}", new CustomFormatter());
Console.WriteLine(customFormatted);
四、应用场景
4.1 日志记录
在记录日志的时候,经常要拼接一些信息,用插值字符串就很合适。
// C# 技术栈示例
int userId = 123;
string action = "登录";
DateTime loginTime = DateTime.Now;
string logMessage = $"用户 {userId} 于 {loginTime:yyyy-MM-dd HH:mm:ss} 进行了 {action} 操作。";
Console.WriteLine(logMessage);
4.2 生成SQL语句
在和数据库交互时,生成SQL语句也能用插值字符串。
// C# 技术栈示例
string tableName = "Users";
int id = 1;
string sql = $"SELECT * FROM {tableName} WHERE Id = {id}";
Console.WriteLine(sql);
不过要注意SQL注入的问题,后面会详细说。
4.3 生成HTML内容
在Web开发里,有时候要动态生成HTML内容,插值字符串也能派上用场。
// C# 技术栈示例
string userName = "李四";
string html = $"<p>欢迎 {userName} 访问我们的网站!</p>";
Console.WriteLine(html);
五、技术优缺点
5.1 优点
- 代码简洁:就像前面说的,比起传统的字符串拼接,插值字符串让代码可读性大大提高,一看就知道要干啥。
- 性能较好:在编译时会做优化,减少不必要的字符串对象创建,节省内存和时间。
- 格式化方便:能轻松实现数字、日期等的格式化,还可以自定义格式化。
5.2 缺点
- 不适合复杂拼接:要是拼接逻辑特别复杂,可能会让代码变得混乱,可读性反而降低。
- SQL注入风险:在生成SQL语句时,如果直接用插值字符串拼接用户输入的数据,容易受到SQL注入攻击。
六、注意事项
6.1 SQL注入问题
前面提到生成SQL语句用插值字符串可能有SQL注入风险,来看个例子。
// C# 技术栈示例
string input = "1 OR 1=1";
string tableName = "Users";
string sql = $"SELECT * FROM {tableName} WHERE Id = {input}";
Console.WriteLine(sql);
这个输入会让SQL语句的逻辑被篡改,可能导致数据泄露等问题。解决办法是用参数化查询。
// C# 技术栈示例
using System.Data.SqlClient;
string tableName = "Users";
int id = 1;
string sql = $"SELECT * FROM {tableName} WHERE Id = @Id";
using (SqlConnection connection = new SqlConnection("YourConnectionString"))
{
SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@Id", id);
connection.Open();
// 执行查询等操作
}
6.2 转义字符
在插值字符串里,如果要用到{}这些符号,得进行转义。
// C# 技术栈示例
string message = $"这是{{特殊符号}}的示例。";
Console.WriteLine(message);
七、文章总结
C#插值字符串是个很实用的功能,它让字符串拼接变得简单、高效,还能方便地进行格式化。在日志记录、生成SQL语句、生成HTML内容等场景下都能大显身手。不过它也有一些缺点,像不适合复杂拼接和存在SQL注入风险等,使用的时候要注意。通过合理运用插值字符串,能让咱们的代码更简洁、更易维护。
评论