《随笔二十六》——C#中的 “ string 字符串、可空类型 ”

 

c# 预定义的类型 string 表示 .Net类 System.String。关于字符串,需要知道的最重要的事情是:

  • 字符串是Unicode字符的数组。
  • string 中的字符串是不能被修改的

点击这里进入官网了解更多 string 类的成员

《随笔二十六》——C#中的 “ string 字符串、可空类型 ”_第1张图片

注意: 上面的操作不会改变 string, 而是返回一个新的副本(该副本也是不能被修改的)。

namespace HelloWorld_Console
{
    class Program
    {    
        static void Main(string []args)
        {
            string s = "Hi there.";
            Console.WriteLine("{0}", s.ToUpper()); // Print uppercase copy
            Console.WriteLine("{0}", s); // String is unchanged
        }      
    } 
}

使用 split 方法


该方法将一个字符串分割为若干个字符串, 然后并将它们以数组的形式返回。

  static void Main(string[] args)
        {
            string s1 = "hi there! this, is: a string.";
            char[] delimiters = { ' ', '!', ',', ':', '.' };
            string[] words = s1.Split(delimiters);
          
            foreach (string s in words)
                Console.WriteLine("{0}", s);
        }

该方法有很多重载的方法, 这里演示的是最简单的。

上面的程序是以 delimiters 中的字符 为参照标准, 然后以此标准分隔 s1 中的字符。


String.Concat (是一个静态方法):

连接 String 的一个或多个对象,或 String 的一个或多个对象值的 Object 表示形式。

 static void Main(string []args)
        {
            string s = "huang";
            string ss = "cheng";
          string tt1 = String.Concat(ss,s);
            WriteLine(tt1);

            string tt2 = String.Concat("huang", "cheng", "tao");
            WriteLine(tt2);

            string[] sss = { "hello ", "and ", "welcome ", "to ","this ", "demo! " };
            Console.WriteLine(string.Concat(sss));

            WriteLine();
            WriteLine(s + ss);
            WriteLine(s+"huangchengtao");
        }         

String.CompareTo Method:

public int CompareTo (string strB);
  • 返回一个整数,该整数指示 该对象是比 strB 大、还是小、还是相等。
  • 注意: 如果两个 string 对象 在某些对应的位置上不一致, 则 string 对象比较的结果其实是  string 对象中第一对相异 字符比较的结果。 而且比较是大小写敏感的, 同个字符小写形式要比大写形式的大。
条件
小于零 此对象 是  小于 strB
此对象 与 strB 相等
大于零 此对象 是  大于 strB
 string s1 = "huang";
            string s2 = "iuang";
            var tt = s1.CompareTo(s2);  /* 现在是 s1 跟 s2 比较,返回三个数
                                                如果s1 和 s2 每个位置的字符相同并且大小也相同,返回0
                                                如果 s1 中的某个字符 比 s2 对应的某个字符大,返回1
                                                如果 s1 中的某个字符 比 s2 对应的某个字符小,返回 -1 */
            WriteLine(tt);
            // 注意  “s1 跟 s2 比较 ” 和  “s2 跟 s1 比较” 返回的比较结果可能不一致
            // 比如上面的 代码返回的是 -1 , 如果调换位置,  返回的是1

 首先是 s1 中的字符h 跟 s2 中的 i 进行比较,  由于 i  在字典中比 h 大。  所以 s1 小于 s2. 则返回 -1。

返回1 表示 s1 确实 比s2大, 就相当于布尔值 true

返回 -1 表示 s1 没有比 s2 大,  就相当于布尔值 false。

返回0, 就表示它们的 字符并且大小相等

注意 : CompareTo方法主要用于排序或字母排序操作。当主要目的是确定两个字符串是否相等时,不应该使用它。要确定两个字符串是否相等,请调用Equals方法。

String.Replace

public string Replace (char oldChar, char newChar);
  • 返回一个 string 对象 ,该操作是 把 某对象中的  oldChar 字符替换成 newChar 字符。 如果在当前对象中找不到 oldChar,此方法返回未更改对象。
  • 该操作也是 区分大小写的。
  • 此方法是不会修改的当前对象的值, 而是返回一个当前对象的一个副本。
 static void Main(string []args)
        {
            String str = "1 2 3 4 5 6 7 8 9";
            Console.WriteLine("Original string: \"{0}\"", str);
            Console.WriteLine("CSV string:      \"{0}\"", str.Replace(' ', ','));
           
            // This example produces the following output:
            // Original string: "1 2 3 4 5 6 7 8 9"
            // CSV string:      "1,2,3,4,5,6,7,8,9"
           
        }

上述程序就是把 str 中的 ‘  ’  空字符 替换成了 逗号。从输出结果可以看出

   static void Main(string []args)
        {
            String s = new String('a', 3);
            Console.WriteLine("The initial string: '{0}'", s);

            s = s.Replace('a', 'b').Replace('b', 'c').Replace('c', 'd');

            Console.WriteLine("The final string: '{0}'", s);
          //  The initial string: 'aaa'
         // The final string: 'ddd'
        }
public string Replace (string oldValue, string newValue);
  • 返回一个新 String,将当前对象中 oldValue 替换为newValue.  
  •  如果在当前对象中找不到 oldChar,此方法返回未更改对象。
  static void Main(string []args)
        {
            string errString = "docment,huang,docment,huangchengtao,docment";
            string correctString = errString.Replace("docment", "TAOTAO");
            Console.WriteLine("输出结果为:{0}", correctString);
        }

String.Substring

public string Substring (int startIndex);
public string Substring (int startIndex, int length);
  • 从当前的 string 对象的 第 startIndex 位置开始截取子字符串 
  • 从当前的 string 对象的 第 startIndex 位置开始截取 length长度的子字符串 , length 只能是 0 <= length <=  startIndex + length
  • 如果 startIndex 等于该 string对象的长度, 返回的是一个空串。
 static void Main(string[] args)
        {
            string s1 = "hi there! this, is: a string.";
                  
            string s2 = s1.Substring(4); // 从第4个位置开始(包括第四个位置的字符) 截取子字符串,直到末尾
            WriteLine(s2);

            string s3 = s1.Substring(4, 3); // 从第4个位置开始(包括第四个位置的字符) 截取后面3个子字符串
            WriteLine(s3);

            /*  输出:
             here! this, is: a string.
             her */
        }

String.Trim:

public string Trim ();

删除对象首尾的空白,返回一个被修改的字符串副本。 如果从当前实例无法删除字符,此方法返回未更改的当前实例。

static void Main(string[] args)
        {
            string s1 = "   hi there! this, is: a string.   ";
            WriteLine(s1.Trim()); // 输出 hi there! this, is: a string. ,  原字符串的首尾的空白都被已删除
        }

 如果当前字符串等于Empty 或当前实例中的所有字符由空白字符都组成,该方法返回Empty。

public string Trim (params char[] trimChars);

返回从当前字符串的开头移除所出现的所有 trimChars 参数中的字符后剩余的字符串。 如果 trimChars 为 null或空数组,则改为移除空白字符。 如果从当前实例无法删除字符,此方法返回未更改的当前实例。

 static void Main(string[] args)
        {
            char[] charsToTrim = { '*', ' '};
            string banner = "***   Much Ado About Nothing   ***";
            string result = banner.Trim(charsToTrim); // 删除首尾的 * 和 空字符
            Console.WriteLine(result); // 输出:Much Ado About Nothing
        }
    }

String.Copy:

public static string Copy (string str);
  • str : 要复制的字符串。
  • 返回一个新的 string值,它是与 str 相同的新字符串。
  • 如果 str 如果为 null。发生 ArgumentNullException 异常
  •  该函数是一个静态方法。
 static void Main(string[] args)
        {
            string str1 = "abc";
            string str2 = String.Copy(str1); // 输出 abc
            WriteLine(str2);
            WriteLine(str2.ToUpper());
            WriteLine(str1);
            /*输出:
             abc
            ABC
            abc*/
        }

Copy方法返回一个String对象,该对象具有与原始字符串相同的值,但表示不同的对象引用。 它与赋值操作不同,赋值操作将现有字符串引用分配给其他对象变量。 该示例演示了差异。

String.IndexOf:

该操作有很多重载形式 

public int IndexOf (string value);
  • 看 value 是否在 string 对象中,如果存在, 返回 value 在 string 对象中第一个字符的索引。
  • 如果未找到该字符串,则为 -1。 如果 value 为 空字符串,则返回值为 0。
  • 如果 value 为 null。 抛出 ArgumentNullException  异常
 static void Main(string[] args)
        {
            String str = "animal";
            String toFind = "n";

            int index = str.IndexOf("n"); // 返回索引1
            Console.WriteLine(index);
        }

 String.Insert:

public string Insert (int startIndex, string value);
  • 返回一个新的字符串,在此实例中的 startIndex 索引位置插入指定 value 字符串。
  • 如果 startIndex 等于此实例的长度,那么value 会追加到此实例的末尾。
  • 如果 参数 value 为 null。抛出 ArgumentNullException 异常
  • 如果 参数 startIndex 为负数或大于此对象的长度。抛出 ArgumentOutOfRangeException  异常。

        static void Main(string[] args)
        {
            String original = "aaabbb";
            Console.WriteLine(original);

            String modified = original.Insert(3, " ");
            Console.WriteLine(modified);
            /*s输出:
             aaabbb
            aaa bbb
            */
        }

 String.Remove:

public string Remove (int startIndex);
  • 从 startIndex 指定的下标位置开始删除,直到该字符串的末尾。返回的是一个新的字符串实例
  • 如果 startIndex 小于零 或者 指定不在此字符串中的下标位置。 抛出 ArgumentOutOfRangeException 异常
 static void Main(string[] args)
        {
            string s = "abc---def";                
            Console.WriteLine( s.Remove(3)); // 输出 abc
          // 从索引3 的字符开始,删除之后的所有字符
        }
public string Remove (int startIndex, int count);

 从 startIndex 指定的下标位置开始删除,删除 count 个字符数。返回的是一个新的字符串实例

 static void Main(string[] args)
        {
            string name = "huangchengtao";
            string temp = name.Remove(5, 5); // 输出 huangtao
            WriteLine(temp);
        }
  • 如果 startIndex 或 count 小于零。
  • 如果  startIndex + count 超过了 该对象的长度
  • 都将 抛出 ArgumentOutOfRangeException 异常。

 String.Contains:

public bool Contains (string value);
  • 返回一个布尔值,该值表示 value 是否出现在该 string对象中。 
  • 如果 value 出现在此字符串中,或者如果value为空字符串(""),则为true。否则,为 false。
  • 如果 参数 value 为 null。抛出 ArgumentNullException 异常。
 static void Main(string[] args)
        {
            string s1 = "The quick brownfox jumps over the lazy dog";
            string s2 = "fox";
            bool b = s1.Contains(s2);
            Console.WriteLine(b); // 返回 true
        }

使用 Parse 和 TryParse 把字符串转换为 实际值 (502P)


namespace HelloWorld_Console
{
    class Program
    {    
        static void Main(string []args)
        {
            string s1 = "25.873";
            string s2 = "36.240";
            double d1 = double.Parse(s1); 把 s1 转换为 double类型
            double d2 = double.Parse(s2);
            double total = d1 + d2;
            Console.WriteLine("Total: {0}", total);
        }      
    } 
}
  • 上面的代码使用 Parse 方法把一个表示值的字符串,然后把它转换为对应的实际值。
  • 注意: 所有 预定义的简单类型(比如说double、int,不是引用类型) 都有一个 Parse 的静态方法, 该方法接受一个表示该类型的字符串值,然后把它转换为对应的实际值。
  • Parse方法的缺点是如果不能把 string 成功转换为目标类型的话会抛出一个异常。

如果不想在转换的过程中出现异常, 可以使用 TryParse 方法。有关该方法需要注意的有:

  • 所有 预定义的简单类型(比如说double、int,不是引用类型) 也有一个 TryParse 的静态方法
  • TryParse方法接受两个参数并且返回一个bool值。
  • 第二个参数是对目标类型变量的引用的out参数
  • 如果TryParse成功,返回true,否则返回false。
namespace HelloWorld_Console
{
    class Program
    {    
        static void Main(string []args)
        {
           
            string stringFirst = "28";
            int intFirst;

            bool success = int.TryParse(stringFirst, out intFirst);
          string  parseResultSummary = success? "was successfully parsed" : "was not successfully parsed";

            Console.WriteLine("String {0} {1}", stringFirst, parseResultSummary);

            string stringSecond = "vt750";
            int intSecond;

            success = int.TryParse(stringSecond, out intSecond);
            parseResultSummary = success  ? "was successfully parsed": "was not successfully parsed";
            Console.WriteLine("String {0} {1}", stringSecond, parseResultSummary);
        }      
    } 
}

可空类型


有时候我们希望表示某个变量目前未保存一个有效的值,这对于引用类型很简单,把变量设置为 null。  但是在定义值类型的变量时, 不管它有没有被初始化或赋值, 其内存都会进行分配。

那么可空类型允许创建可以标记为有效或 无效的值类型, 这样就可以在使用它之前确定值的有效性。

可空类型总是基于另一种类型,即已声明的底层类型。需要了解的有:

  • 可以从任何值类型(包括预定义的简单类型)创建可空类型。
  • 不能从引用类型或其他可空类型创建可空类型
  • 在代码中不能显式声明可空类型。相反,只能声明一个可空类型的变量。编译器隐式地为您创建可空类型。

使用可空类型几乎与使用任何其他类型的变量相同。读取可空类型的变量将返回其值。但是,您必须确保变量不是null。试图读取null变量的值会产生异常。

  • 与任何变量一样,要获取它的值,只需使用它的名称。
  • 要检查可空类型是否有值,可以将其与null进行比较,或者检查其HasValue属性。
    namespace HelloWorld_Console
    {
        class Program
        {    
            static void Main(string []args)
            {
                int? myInt = 15;
                if(myInt!=null)
                {
                    WriteLine(myInt);
                }
            }      
        } 
    }
    

    可空类型中有几个重要的属性:

  • HasValue 属性是bool类型, 并且指示值是否有效;

  • Value 属性与基础类型的类型相同,如果变量有效,则返回变量的值。

可以轻松地在可空类型与其对应的非空类型之间进行转换。关于可空类型转换,您需要了解的重要内容如下:

  • 非可空类型和相应的可空版本之间的转换是隐式的,也就是说,不需要强制转换;
  • 可空类型和相应的可空版本之间的转换是显式的。
    namespace HelloWorld_Console
    {
        class Program
        {    
            static void Main(string []args)
            {
                int? myInt1 = 15; // 隐式地将int转换为int?
                int regInt = (int)myInt1; // 将int? 显式转换为 int
            }      
        } 
    }
    

为可空类型赋值 (505P)


可以为可空类型的变量赋值三种类型的值:

  • 基础类型的值
  • 具有相同可空类型的值
  • Null 值
namespace HelloWorld_Console
{
    class Program
    {    
        static void Main(string []args)
        {
            int? myInt1 = 15; // 可以用基础类型的值为可空类型赋值
            int? myInt2 = 20;
            myInt1 = myInt2; // 可以用另一个相同可空类型的值为其赋值
            myInt2 = null;
            WriteLine($"{myInt1},{myInt2}");
        }      
    } 
}

使用 空接合运算符 (505P)


namespace HelloWorld_Console
{
    class Program
    {    
        static void Main(string []args)
        {
            int? myInt1 = null;

            WriteLine($"{myInt1 ?? -1}");

            myInt1 = 14;
            WriteLine($"{myInt1 ?? -1}");
        }      
    } 
}

空接合运算符由两个连续的问号组成,它有两个操作数:

  • 第一个操作数是可空类型的变量。
  • 第二个是相同基础类型的不可空值。
  • 如果在运行时,第一个操作数(可空操作数)的计算结果为null,则非空操作数作为表达式的结果返回。 否则,返回第一个 可空类型变量的值。  如上述程序。

namespace HelloWorld_Console
{
    class Program
    {    
        static void Main(string []args)
        {
            int? i1 = null, i2 = null; 
            if (i1 == i2) 
                Console.WriteLine("Equal");
        }      
    } 
}

当比较相同两个可空类型的值,且两个值都为null时,相等比较操作符(==和!=)认为它们相等。


为  struct 值类型定义可空类型 (506P)


namespace HelloWorld_Console
{
    struct MyStruct 
    {
        public int X; 
        public int Y; // Field
        public MyStruct(int xVal, int yVal) 
        { X = xVal; Y = yVal; }
    }
    class Program
    {    
        static void Main(string []args)
        {
            MyStruct mSStruct = new MyStruct(6, 11); // 结构变量
            MyStruct? mSNull = new MyStruct(5, 10); // 可空类型的变量

            // 用结构的实例访问
            Console.WriteLine("mSStruct.X: {0}", mSStruct.X);
            Console.WriteLine("mSStruct.Y: {0}", mSStruct.Y);
            // 用结构的可空类型的实例访问
            Console.WriteLine("mSNull.X: {0}", mSNull.Value.X);
            Console.WriteLine("mSNull.Y: {0}", mSNull.Value.Y);
        }      
    } 
}

 

你可能感兴趣的:(C#中的随笔)