当前位置: 首页 > news >正文

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

.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

相关文章:

  • JSTL 自定义
  • WIN7下使用Outlook访问 Exange2010 无法对外发送邮件的问题
  • linux下终止用户会话二法
  • REST与SOA两种架构下WCF的异同比较(含源码)
  • jquery特殊符号含意
  • Unix/Linux常用的一些命令--转贴我注明
  • 辅助域控制器删除报错“目标服务器无法分配标识符”
  • .NET Project Open Day(2011.11.13)
  • H3C交换机以太网端口类型
  • 遇事处理方式
  • phpweb解析不当加上传漏洞
  • 读书笔记10:外观模式
  • How Many Times We'll Say Goodbye---歌词
  • myeclipse注册类
  • 爱创课堂每日一题第六十天- 创建ajax的过程
  • 时间复杂度分析经典问题——最大子序列和
  • 《Java编程思想》读书笔记-对象导论
  • 【React系列】如何构建React应用程序
  • 30天自制操作系统-2
  • Angular 4.x 动态创建组件
  • Apache Spark Streaming 使用实例
  • JAVA并发编程--1.基础概念
  • MySQL数据库运维之数据恢复
  • node.js
  • 搞机器学习要哪些技能
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 使用 QuickBI 搭建酷炫可视化分析
  • 使用common-codec进行md5加密
  • 使用parted解决大于2T的磁盘分区
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (LeetCode C++)盛最多水的容器
  • (Oracle)SQL优化技巧(一):分页查询
  • (补)B+树一些思想
  • (二)hibernate配置管理
  • (三)mysql_MYSQL(三)
  • (三)模仿学习-Action数据的模仿
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (四)图像的%2线性拉伸
  • (原創) 未来三学期想要修的课 (日記)
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET Project Open Day(2011.11.13)
  • .NET/C# 使用反射注册事件
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • /var/lib/dpkg/lock 锁定问题
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [Angularjs]ng-select和ng-options
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)