• 《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
    }
  • 相关阅读:
    五十四:CSS3之背景与渐变之渐变
    五十三:CSS3之背景与渐变之背景
    五十二:CSS3之圆角、边框、边界图片
    五十一:CSS3之基本选择器之伪元素
    五十:CSS3之基本选择器之CSS权重
    四十九:CSS3之基本选择器之伪类选择器之结构类之nth选择器
    四十八:CSS3之基本选择器之伪类选择器之UI元素状态伪类
    四十七:CSS3之基本选择器之伪类选择器之动态伪类
    四十六:CSS3之基本选择器新增加的属性选择器
    四十五:CSS3之基本选择器新增加的4种选择器
  • 原文地址:https://www.cnblogs.com/wang_yb/p/2220495.html
Copyright © 2020-2023  润新知