博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《CLR Via C# 第3版》笔记之(十六) - 字符串
阅读量:7068 次
发布时间:2019-06-28

本文共 3173 字,大约阅读时间需要 10 分钟。

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

主要内容:

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

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

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

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

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

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

"A" + "B" + "C"

而是可以使用StringBuilder这个类,

StringBuilder sb = new StringBuilder();sb.Append("A");sb.Append("B");sb.Append("C");

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

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

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

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

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

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

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

 

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

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. 语言文化

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

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

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,则直接输出。

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}

转载于:https://www.cnblogs.com/wang_yb/archive/2011/10/21/2220495.html

你可能感兴趣的文章
「续集」Sass简易指南:多风格编译和运行以及文件注释
查看>>
JAVA导出EXCEL
查看>>
11.14/11.15 Apache和PHP结合 11.16/11.17 Apache默认虚拟主机
查看>>
TeeChart Pro VCL/FMX教程(六):使用系列(一)
查看>>
Dubbo分析之Cluster层
查看>>
Titan Framework MongoDB深入理解3
查看>>
iOS核心动画笔记2-寄宿图
查看>>
几种不同类型网站内容优化切入点
查看>>
SaltSack入门(三)Salt相关命令和Pillar应用
查看>>
文件上传相关内容
查看>>
Linux下Nodejs安装(完整详细)
查看>>
OSChina 周四乱弹 —— 想换行了怎么办,别说按回车键
查看>>
ubuntu11.04安装JDK7及配置环境
查看>>
SpringBoot+Logback+Sentry(日志监控平台)
查看>>
vmware10中开启Intel VT-x
查看>>
一般wsdl生成的类都比较大,IDEA类文件大小限制导致无法加载该类问题
查看>>
Android 垂直Tab
查看>>
Android DecorView与ViewRootImpl
查看>>
goroutine 相关知识7
查看>>
redis命令学习笔记
查看>>