《CLR Via C# 第3版》笔记之(十六) - 字符串

简介:

.Net中的字符串是被谈论最多的话题,这里也进行一些总结,供以后参考。

主要内容:

  • 字符串的不可变性和字符串留用
  • 语言文化
  • 格式化器 

1. 字符串的不可变性和字符串留用

字符串(string)在.Net中是一个特殊的类。

.Net中的字符串是不可变的(immutable)。也就是说,字符串已经创建就不能更改,变长,变短,修改字符都不行。

对字符串进行的任何操作都不能改变原字符串,只会生成新的字符串。

由于String是不可变的,我们在使用大量的字符串拼接的时候不宜使用 【+】运算符,比如

1
"A"  + "B"  + "C"

而是可以使用StringBuilder这个类,

1
2
3
4
StringBuilder sb = new  StringBuilder();
sb.Append( "A" );
sb.Append( "B" );
sb.Append( "C" );

这样可以避免在内存中不断生成新的string对象。

StringBuilder的工作原理大致是这样的:

内部维护一个字符数组,并且有一个初始容量。

新的字符串都加入到这个数组中。

当加入的字符超过容量时,就重新new一个更大的数组,并将原先的数组内容拷入新数组中。

将原有的数组进行垃圾回收,新的字符串加入到使用新的字符数组中。

StringBuilder的ToString方法见字符数组转换为一个String输出。

 

为了提高字符串的性能,.Net中对已有的字符串进行了留用,使得再次使用相同的字符串时不用重新申请内存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using  System;
 
public  class  CLRviaCSharp_16
{
     static  void  Main( string [] args)
     {
         string  s1 = "Hello" ;
         string  s2 = "Hello" ;
         // 应该为 False
         Console.WriteLine( object .ReferenceEquals(s1, s2));
 
         s1 = String.Intern( "Hello" );
         s2 = String.Intern( "Hello" );
         // 显示 True
         Console.WriteLine( object .ReferenceEquals(s1, s2));
         
         Console.ReadKey( true );
     }
}

 

第一次的执行结果应该为False,但是CLR在编译时默认进行了留用,所以2次结果都是True

我们如果要使用字符串留用的话,一定要明确使用String.Intern,否则CLR版本变更后有可能不默认进行字符串留用。

那样,运行结果就变了。

 

2. 语言文化

字符串的语言文化在使用中很少涉及,但是如果不注意的话,可能会遇到意料之外的错误。

如以下中文和日语的比较,用不同的语言文化,比较结果就不同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using  System;
using  System.Globalization;
 
public  class  CLRviaCSharp_16
{
     static  void  Main( string [] args)
     {
         string  s1 = "中文" ;
         string  s2 = "日本語" ;
         CompareInfo compareInfo = CompareInfo.GetCompareInfo( "ja-JP" );
         Console.WriteLine(compareInfo.Compare(s1, s2));
         compareInfo = CompareInfo.GetCompareInfo( "zh-CN" );
         Console.WriteLine(compareInfo.Compare(s1, s2));
         
         Console.ReadKey( true );
     }
}

 

在不同语言之间进行字符串比较需要注意语言文化对结果的影响。

 

3. 格式化器

通过格式化器,可以将字符串按照一定的格式输出,在打印或者log输出上会很有用。

实现自定义的格式化器需要继承IFormatProvider, ICustomFormatter两个接口。

下面通过例子演示如何通过定制格式化器来调整打印输出的。

例子很简单,依次输出字符串,

如果字符串长度大于4,则截断尾部,只输出4个字符。

如果字符串长度小于4,则在尾部补充【*】,使长度达到4。

如果字符串长度等于4,则直接输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using  System;
 
public  class  CLRviaCSharp_16
{
     static  void  Main( string [] args)
     {
         string [] strs = new  string [] { "sadfasdf" , "dgdgfdsds" , "ggh" , "w" , "abcd"  };
 
         foreach  ( var  str in  strs)
         {
             Console.WriteLine( string .Format( new  FormatPrint(), "{0}" , str));
         }   
         Console.ReadKey( true );
     }
}
 
internal  class  FormatPrint : IFormatProvider, ICustomFormatter
{
     #region IFormatProvider Members
 
     public  object  GetFormat(Type formatType)
     {
         if  (formatType == typeof (ICustomFormatter))
             return  this ;
         else
             return  null ;
     }
 
     #endregion
 
     #region ICustomFormatter Members
 
     public  string  Format( string  format, object  arg, IFormatProvider formatProvider)
     {
         string  s;
 
         IFormattable formattable = arg as  IFormattable;
         if  (formattable == null )
             s = arg.ToString();
         else
             s = formattable.ToString(format, formatProvider);
 
         // 开始处理长度
         if  (s.Length > 4)
             return  s.Substring(0, 4);
         else  if  (s.Length == 4)
             return  s;
 
         for  ( int  i = s.Length; i < 4; i++)
             s += "*" ;
         return  s;
     }
 
     #endregion
}
标签:  CLR via C#笔记


本文转自wang_yb博客园博客,原文链接:http://www.cnblogs.com/wang_yb/archive/2011/10/21/2220495.html,如需转载请自行联系原作者

目录
相关文章
|
6月前
|
C#
C#的小例子和字符串(一)
C#的小例子和字符串(一)
144 0
|
6月前
|
C# 开发者
C# 10.0引入常量插值字符串:编译时确定性的新篇章
【1月更文挑战第22天】在C# 10.0中,微软为开发者带来了一项引人注目的新特性——常量插值字符串。这一功能允许在编译时处理和计算字符串插值表达式,从而得到可以在编译时确定的常量字符串。本文将深入探讨C# 10.0中常量插值字符串的概念、工作原理、使用场景及其对现有字符串处理方式的改进,旨在帮助读者更好地理解和应用这一强大的新特性。
|
6月前
|
C# Python
C# 笔记1 - 操作目录
C# 笔记1 - 操作目录
56 0
|
6月前
|
C#
C#有关字符串的分割,替换,截取
C#有关字符串的分割,替换,截取
|
6月前
|
编译器 C# 开发者
C# 10.0中插值字符串的改进:灵活性与性能的双重提升
【1月更文挑战第19天】C# 10.0带来了对插值字符串的显著改进,进一步增强了这一功能的灵活性和性能。插值字符串是C#中处理字符串格式化的一种强大方式,它允许开发者直接在字符串中嵌入变量和表达式。在C# 10.0中,插值字符串不仅获得了语法上的简化,还通过新的编译时优化提高了运行时性能。本文将详细探讨C# 10.0中插值字符串的改进内容,以及这些改进如何为开发者带来更加高效和便捷的编程体验。
|
1月前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
2月前
|
开发框架 .NET 程序员
C# 去掉字符串最后一个字符的 4 种方法
在实际业务中,我们经常会遇到在循环中拼接字符串的场景,循环结束之后拼接得到的字符串的最后一个字符往往需要去掉,看看 C# 提供了哪4种方法可以高效去掉字符串的最后一个字符
313 0
|
1月前
|
算法 安全 测试技术
C#——刘铁猛笔记
C#——刘铁猛笔记
48 0
|
2月前
|
前端开发 C#
C# 一分钟浅谈:字符串操作与正则表达式
本文详细介绍C#中的字符串操作与正则表达式应用,涵盖字符串拼接、分割、查找及替换等基础操作,并通过实例讲解正则表达式的模式匹配、文本替换与分组捕获技巧。同时,文章还探讨了性能优化、复杂度管理和安全性等问题及解决策略,助你提升编程效率,应对实际开发挑战。
77 0
|
4月前
|
SQL 开发框架 前端开发
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式