一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C#中如何正確的使用字符串String

C#中如何正確的使用字符串String

2022-03-06 13:30Fode C#

這篇文章主要給大家介紹了關于在C#中如何正確的使用字符串String的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

C#中提供了比較全面的字符串處理方法,很多函數都進行了封裝為我們的編程工作提供了很大的便利。System.String是最常用的字符串操作類,可以幫助開發者完成絕大部分的字符串操作功能,使用方便。

字符串作為所有編程語言中使用最頻繁的一種基礎數據類型。如果使用不慎,將會造成不必要的內存開銷,為此而付出代價。

而要優化此類型,從以下兩點入手:

1、盡量少的裝箱

2、避免分配額外的內存空間

先從第一點裝箱的操作說起,查看如下代碼:

?
1
2
//發生裝箱的代碼
String boxOperate = "test" + 4.5f;

其中間語言IL代碼為如下:

?
1
2
3
4
5
6
7
8
9
IL_0000: nop
IL_0001: ldstr "test"
IL_0006: ldc.r4 4.5
IL_000b: box [mscorlib]System.Single
IL_0010: call string [mscorlib]System.String::Concat(object, object)
IL_0015: stloc.0
IL_0016: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_001b: pop
IL_001c: ret

不難看出,上述代碼發生了裝箱的操作(IL代碼中的box).裝箱之所以會發生性能損耗,因為它要完成如下三個步驟:

1、首先,會為值類型在托管堆中分配內存。除了值類型本身所分配的內存外,內存總量還要加上類型對象指針和同步塊索引所占用的內存,

2、將值類型的值復制到新分配的堆內存中。

3、返回已經成為引用類型的對象的地址。

在來看以下代碼:

?
1
2
//沒有發生裝箱的代碼
 String boxOperate = "test" + 4.ToString();

其中間IL代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
IL_0000: nop
IL_0001: ldstr "test"
IL_0006: ldc.r4 4
IL_000b: stloc.1
IL_000c: ldloca.s 1
IL_000e: call instance string [mscorlib]System.Single::ToString()
IL_0013: call string [mscorlib]System.String::Concat(string, string)
IL_0018: stloc.0
IL_0019: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_001e: pop
IL_001f: ret

如上,并沒有發生任何裝箱操作,但是達到的結果卻是我們想要的。原因是 4.ToString() 這行代碼并沒有發生裝箱行為,是實際調用的是整數型的ToString()方法,其原型如下:

?
1
2
3
public override string ToString(){
 return Number.FormatInt32(m_value, null, NumberFormat.CurrentInfo);
}

可能有人會問,是不是原型中的 Number.Format_XXX方法會發生裝箱行為呢?實際上,Number.Format_XXX方法是一個非托管的方法,其原型如下:

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
public statuc extern string FormatInt32(int value, string format,NumberFormatInfo info);

它是通過直接操作內存來完成 Int32 到 String 的轉換,效率要比裝箱高得多。所以,在使用其他值引用類型到字符串得轉換比完成拼接時,應當避免使用操作符 “+” 來我完成,而應該使用值引用類型提供得ToString方法。

也許有人會問:即使FCL提供得方法沒有發生裝箱行為,但在其他情況下,FCL方法內部會不會含有裝箱的行為?也許會存在,所以,本人推薦:編寫代碼中,應當盡量避免發生不必要的裝箱代碼。

 

第二個方面:避免分配額外的空間。對于CLR來說,String對象(字符串對象)是個很特殊的對象,它一旦被賦值就不可改變(在內存中)。在運行時調用System.String類中的任何方法或進行任何運算('=‘賦值,'+‘拼接等),都會在內存中創建一個新的字符串對象,這也意味著要為該新對象分配新的內存空間。如以下代碼會帶來額外開銷。

?
1
2
3
4
5
private static void Test(){
   String str1 = "aa";
  str1 = str1 + "123" + "345";
   //以上代碼創建了3個String對象,并執行了一次String.Contact方法。
}

而在以下代碼中,字符串不會在運行時拼接字符串,而是會在編譯時直接生成一個字符串。

?
1
2
3
4
5
6
7
8
9
10
11
12
private static void Test()
{
String str= "aa" + "123" + "345";//等效 String str= "aa123345";
}
 
private static void Test2()
{
const String str = "aa";
String newStr = "123" + str;
//因為str是一個常量,所以該代碼等效于 String newStr = "123" + “aa”;
//最終等效于 String newStr = "123aa”;
}

由于使用System.String類會在某些場合帶來明顯的性能損耗,所以微軟另外提供了一個類型StringBuilder來彌補String的不足。

StringBuilder并不會重新創建一個String對象,它的效率源于預先以非托管的方式分配內存。如果StringBuilder沒有先定義長度,則默認分配的長度為16。當StringBuilder的長度大于16小于32時,StringBuild又會重新分配內存,使之成為16的倍數。StringBuilder重新分配內存時按照上次的容量加倍進行分配的。注意:StringBuilder指定的長度要合適,太小了,需要頻繁分配內存;太大了,浪費內存空間。

以下是例子舉例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private static String Test3()
  {
   String a = "t";
   a += "e";
   a += "s";
   a += "t";
   return a;
  }
  private static String Test4()
  {
   String a = "t";
   String b = "e";
   String c = "s";
   String d = "t";
   return a + b + c + d;
  }
  //以上兩種效率都不高效。不要以為前者比后者創建的字符串對象更少,事實上,兩者創建的字符串對象相等
  //且前者進行了3次的String.Contact方法調用,比后者還多了兩次。

要完成上圖的運行時的字符串拼接(注意:是運行時),更佳的做法是使用StringBuilder類型,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private static String Test5()
  {
   String a = "t";
   String b = "e";
   String c = "s";
   String d = "t";
   StringBuilder sb = new StringBuilder(a);
   sb.Append(b);
   sb.Append(c);
   sb.Append(d);
   return sb.ToString();
   //因為說的是運行時,所以沒必要使用以下代碼
   //StringBuilder sb = new StringBuilder("t");
   //sb.Append("e");
   //sb.Append("s");
   //sb.Append("t");
   //return sb.ToString();
  }

微軟還提供了另外一個來簡化這種操作,即使用String.Format 方法。String.Format方法在內部使用StringBuilder 進行字符串格式化,如下圖代碼:

?
1
2
3
4
5
6
7
8
9
private static String Test6()
{
  //為演示,定義4個變量
  String a = "t";
  String b = "e";
  String c = "s";
  String d = "t";
  return String.Format("{0}{1}{2}{3}", a, b, c, d);
}

總結:

在使用String字符串時,應該盡量避免裝箱操作和“+”連接操作。

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/fode/p/10061233.html

延伸 · 閱讀

精彩推薦
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
主站蜘蛛池模板: 免费91麻豆精品国产自产在线观看 | 欧美另类老女人 | 不良研究所地址一 | 国内精品久久久久久不卡影院 | 国产成人v爽在线免播放观看 | 久久久久激情免费观看 | 91精品国产亚一区二区三区 | 亚洲区精品 | www.四虎com| 幻女free性zoz0交 | 欧美夜夜精品一级爽 | 我们中文在线观看免费完整版 | 国语自产自拍秒拍在线视频 | 天天干天天色综合网 | 春意影院午夜爽爽爽免费 | 久久免费看少妇高潮A片2012 | 国产一区二区精品 | 99小视频 | 国产在线精品香蕉综合网一区 | 男人猛激烈吃奶gif动态图 | julia ann多人乱战 | 午夜一级影院 | 午夜五月天 | 精品无码国产污污污免费网站2 | 4438全国免费观看 | 国产成人理在线观看视频 | 国产不卡视频 | 喜欢老头吃我奶躁我的动图 | 天天操夜夜操狠狠操 | 91精品国产高清久久久久久 | 天美影视文化传媒mv免费 | 逼123| 国产精品女主播自在线拍 | 惊弦45集免费看 | 乌克兰粉嫩摘花第一次 | 美女被到爽流动漫 | 手机在线观看精品国产片 | 韩国最新三级网站在线播放 | 蜜桃成熟时1997在线看免费看 | 午夜熟女插插XX免费视频 | kkkk4444在线看片|