• C# 基础知识系列- 9 字符串的更多用法(二)


    0. 前言

    上一篇文章介绍了字符串自身的一些方法,就是对象方法。在字符串体系中,还有一些是string类提供的静态方法。这两部分构成了字符串体系,当然还有一些三方库为字符串提供了扩展方法。
    这里简单的介绍一下string类的静态方法。

    1. 玩转创建字符串

    1.1 Create一个字符串

    通过调用string.Create方法可以生成一个字符串。该方法的声明是

    public static string Create<TState> (int length, TState state, System.Buffers.SpanAction<char,TState> action);
    

    简单的来讲就是生成一个长度为length的字符串,基本元素是 TState类型的state,具体的填充过程交由action来进行处理。值得注意的是action是一个委托,也就是它可以用lambda表达式直接使用,具体声明如下:

    public delegate void SpanAction<T,in TArg>(Span<T> span, TArg arg);
    

    因为方法中指定了Span参数为char,那么 action 的写法应该如下:

    (span, state)=>//span 的类型是 Span<char>,state的类型是 TState
    {
    // 注意,没有返回值
    }
    

    示例:

    string str = "12320kz,zxcqweqwkuqwiqewpqwwe";
    Console.WriteLine(string.Create(10,str, (span, c) =>
    {
        span.Fill(c[0]);
    }));
    

    span的方法Fill的参数是char,所以这个方法就是按照一定逻辑将 state参数转换成char然后填充给字符串,在action中多次调用Fill只会生效最后一次填充。

    1.2 连接多个元素

    字符串的连接有两个方法,一个是string.Concat,一个是string.Join

    首先介绍Concat,这个方法最基本的功能就是将多个字符串收尾连接成一个字符串,继续引申,连接任意个对象形成一个字符串,最后将一个集合的元素拼接成字符串。所以,这个方法的声明就有以下内容:

    public static string Concat (string str0, string str1);
    public static string Concat (object arg0, object arg1);
    public static string Concat (params string[] values);
    public static string Concat (params object[] args);
    public static string Concat (System.Collections.Generic.IEnumerable<string> values);
    public static string Concat<T> (System.Collections.Generic.IEnumerable<T> values);
    

    以上只是几个具有代表性的方法,介绍到这里有没有觉得它的实现很眼熟?

    没错,字符串的‘加法’运算就是基于这个方法实现的。

    Join在行为上与Concat很相似,但是这个方法是用一个分割符(可以是字符串)将一组对象连接起来,所以它的声明就是如下内容:

    public static string Join (char separator, params object[] values);
    public static string Join<T> (char separator, System.Collections.Generic.IEnumerable<T> values);
    public static string Join (string separator, params object[] values);
    public static string Join<T> (string separator, System.Collections.Generic.IEnumerable<T> values);
    

    这两个方法出镜率非常高,不过Concat更多的是用‘加法’形式,而Join在多个元素快速生成字符串中非常常见。

    这里简单介绍一下Join的使用:

    var list = new List<int>();
    for (var i = 0; i < 10; i++)
    {
        list.Add(i);// 生成一个列表,元素是0到9这十个数字
    }
    string str = string.Join(",", list);//0,1,2,3,4,5,6,7,8,9
    

    2. 快来比一比

    2.1 我们是不是同一个

    因为字符串机制的问题,所以一般字符串的相等性比较分为了两种,字面相等性和引用相等性。在C#中默认的相等性比较是字面值相等性。示例:

    string str1 = "123";
    string str2 = "123";
    string str3 = new string("123");
    bool eq1 = str1 == str2;// true
    bool eq2 = str2 == str3;// true
    bool eq3 = str1 == str3;// true
    

    那么如何判断是否是同一个引用呢?通过object.ReferenceEquals来判断是否是同一个引用。继续上面的例子:

    bool req1 = object.ReferenceEquals(str1, str2);// true
    bool req1 = object.ReferenceEquals(str2, str3);// false
    bool req3 = object.ReferenceEquals(str1, str3);// false
    

    在C#中,编译器会将一样字面值的字符串指向同一个地址,这个地址是在字符串的常量池中。而使用new等方法创建的字符串,是在程序运行后才会确认字符串具体的值,所以这个地址是后分配的。所以上述两种判断方式会出现不同的结果。

    string类提供了一个静态方法Equals,方法声明如下:

    public static bool Equals (string a, string b);
    public static bool Equals (string a, string b, StringComparison comparisonType);
    

    该方法返回两个字符串是否是相等的,也就是与字符串默认的==判断是一致的。

    2.2 来比一比高矮

    在我们开发的过程中经常会遇到对字符串进行排序的需求,那么字符串排序的逻辑是什么呢?

    对于数字、字母来说是按照ASCII码进行排序的,也就是数字、小写、大写字母这样进行排序。当加入中文后,中文排最后,同种字符按字典顺序进行排序。对于一些跨语言的排序会因为语言不同而导致排序结果不一样。这里有兴趣的可以查看一下微软的官方文档。

    介绍一下字符串排序的基本方法:Compare

    这个方法有一个对象的相似方法是CompareTo,这个方法是IComparable接口定义的方法,与这个方法行为一致。该方法常用的有如下几个定义:

    public static int Compare (string strA, string strB);
    public static int Compare (string strA, string strB, StringComparison comparisonType);
    

    这个方法返回一个整型,可以理解为两个字符串之间的距离,正的表示A在B的后面,负的表示A在B的前面。值的绝对值越大,两个字符串之间的距离也越大,但是值本身不具备意义。如果值为0,则表示这两个字符串相等。

    有一个重载版本里有个参数类型是StringComparison,这是一个枚举类型,用来定义在比较两个字符串时的一些行为,后续有机会详细介绍这一部分。

    示例:

    string str1 = "123a";
    string str2 = "132a";
    int position1 = string.Compare(str1, str2);// -1
    str1 = "你好";
    str2 = "我们";
    int position2 = string.Compare(str1, str2);// -1
    

    可以明显看出,排序规则基本就是字典顺序。

    3. 补充

    补充三个上一篇文章遗漏的方法,插入、删除、获取一个子串。

    3.1 插入到某个位置

    public string Insert (int startIndex, string value);
    

    在源字符串指定的位置插入一个字符串并返回插入的结果。

    3.2 删除

    //从startIndex开始,后面的所有元素都删除,包括startIndex,返回剩下的字符
    public string Remove (int startIndex);
    //从startIndex开始,删除 count个元素,返回剩下的字符
    public string Remove (int startIndex, int count);
    

    3.3 获取一个子串

    // 返回从startIndex开始,剩下的的元素,包括startIndex
    public string Substring (int startIndex);
    // 返回从startIndex开始,一共count个元素的字符串,包括startIndex
    public string Substring (int startIndex, int length);
    

    这一部分的方法比较简单,就不做示例演示了。不过需要注意的是 所有参数都应该是大于0的,且不能大于字符串的长度,包括 startIndex+count。

    4. 总结

    目前为止,字符串的常规使用已经完成了,但是字符串的使用却并没有结束,后续会继续介绍C#其他内容,其中有几个内容是与字符串有很大的关联的,这里先容我卖个关子。

    更多内容烦请关注我的博客

    file

  • 相关阅读:
    需求变更的种类及应对方式
    SQL Server中连接远程表、查询其它服务器的数据、导入或导出到其它Sql Server服务器数据
    在IE9中MSWC.BrowserType组件无法识别Cookie的问题
    优秀软件的几个重要标准
    对待代码的态度反应着对待自己的态度
    应对企业不断变化的系统
    在SQL中插入®特殊字符
    如何让领导认识到测试的重要性,在沟通时要注意的几点
    男人要补肾,强肾健脑对能持久做程序
    你可能不知道的Visual Studio 2010使用技巧(VS2010的秘密)
  • 原文地址:https://www.cnblogs.com/c7jie/p/12716596.html
Copyright © 2020-2023  润新知