《隨筆二十六》——C#中的 “ string 字符串、可空類型 ”

 

c# 預定義的類型 string 表示 .Net類 System.String。關於字符串,需要知道的最重要的事情是:

  • 字符串是Unicode字符的數組。
  • string 中的字符串是不能被修改的

點擊這裏進入官網瞭解更多 string 類的成員

注意: 上面的操作不會改變 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);
        }      
    } 
}

 

發佈了209 篇原創文章 · 獲贊 73 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章