亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#不可變類型深入解析

2020-01-24 02:32:08
字體:
來源:轉載
供稿:網友

學過C#的人都知道string類型,但是string作為一種特殊的引用類型還有一個重要的特征就是恒定性,或者叫不可變性,即Immutable。作為不可變類型,最主要的特性表現是:一旦創建,只要修改,就會在托管堆上創建一個新的對象實例,而且和上一個對象實例是相鄰的,在托管堆上分配到一塊連續的內存空間。

那么為什么需要不可變類型呢?

在多線程情況下,一個線程,由于種種原因(比如異常)只修改了一個變量所代表類型的部分成員的值,這時候,另一個進程進來,也訪問這個變量,第二個進程訪問到的變量成員,一部分成員還是原來的值,另一部分成員的值是第一個線程修改的值,這樣就出現了"數據不一致"。而不可變類型就是為了解決在多線程條件下的"數據不一致"的問題。

當然,字符串的不可變性或恒定性,不僅解決了"數據不一致"的問題,還為字符串的"駐留"提供了前提,這樣才可以把不同的字符串以及托管堆上的內存地址以鍵值對的形式放到全局哈希表中。

一、親眼目睹"數據不一致":

對Student的Score屬性,在賦值的時候加上檢測,檢測是否是2位數整數。

  public struct Student  {    private string name;    private string score;     public string Name    {      get { return name; }      set { name = value; }    }     public string Score    {      get { return score; }      set      {        CheckScore(value);        score = value;      }    }     //檢測分數是否是2位數整數    private void CheckScore(string value)    {      string pattern = @"/d{2}";      if (!Regex.IsMatch(value, pattern))      {        throw new Exception("不是有效分數!");      }    }     public override string ToString()    {      return String.Format("姓名:{0},分數:{1}", name, score);    }  } 

在主程序中故意制造出一個異常,目的是只對一個變量所代表類型的某些成員賦值。

    static void Main(string[] args)    {      Student student = new Student();      student.Name = "張三";      student.Score = "80";      Console.WriteLine(student.ToString());       try      {        student.Name = "李四";        student.Score = "8";      }      catch (Exception)      {                throw;      }      Console.WriteLine(student.ToString());      Console.ReadKey();    } 

打斷點,運行,發現Student類型的student變量,在第二次賦值的時候,把student的Name屬性值改了過來,而student的Score屬性,由于發生了異常,沒有修改過來。這就是"數據不一致"。

如下圖所示:

二、動手設計不可變類型

1.不可變類型的2個特性:

①對象的原子性:要么不改,要改就把所有成員都改,從而創建新的對象。
②對象的常量性:對象一旦創建,就不能改變狀態,即不能改變對象的屬性,只能創建新的對象。

2.遵循以上不可變類型的2個特征

①在構造函數中對所有字段賦值。
②將屬性中的set訪問器刪除。

  class Program  {    static void Main(string[] args)    {      Student student = new Student("張三", "90");      student = new Student("李四","80");      Console.WriteLine(student.ToString());      Console.ReadKey();    }  }   public struct Student  {    private readonly string name;    private readonly string score;     public Student(string name, string score)    {      this.name = name;      this.score = score;    }     public string Name    {      get { return name; }    }     public string Score    {      get { return score; }    }     public override string ToString()    {      return String.Format("姓名:{0},分數:{1}", name, score);    }  } 

運行結果如下圖所示:

由此可見,我們無法修改Student的其中某一個成員,只能通過構造函數創建一個新對象,滿足"對象的原子性"。
而且也無法修改Student對象實例的某個屬性值,符合"對象的常量性"。

3.如果有引用類型字段和屬性,如何做到"不可變性"?

  class Program  {    static void Main(string[] args)    {      string[] classes = {"語文", "數學"};      Student student = new Student("張三", "85", classes);      Console.WriteLine("==修改之前==");      Console.WriteLine(student.ToString());       string[] tempArray = student.Classes;      tempArray[0] = "英語";      Console.WriteLine("==修改之后==");      Console.WriteLine(student.ToString());      Console.ReadKey();    }  }   public struct Student  {    private readonly string name;    private readonly string score;    private readonly string[] classes;     public Student(string name, string score, string[] classes)    {      this.name = name;      this.score = score;      this.classes = classes;    }     public string Name    {      get { return name; }    }     public string Score    {      get { return score; }    }     public string[] Classes    {      get { return classes; }    }     public override string ToString()    {      string temp = string.Empty;      foreach (string item in classes)      {        temp += item + ",";      }       return String.Format("姓名:{0},總分:{1},參加的課程有:{2}", name, score,temp.Substring(0, temp.Length -1));    }  } 

結果如下圖所示:

由此可見,還是可以對對象的屬性間接修改賦值,不滿足不可變類型的"常量性"特點。

4.通過在構造函數和屬性的get訪問器中復制的方式來滿足不可變性

  class Program  {    static void Main(string[] args)    {      string[] classes = {"語文", "數學"};      Student student = new Student("張三", "85", classes);      Console.WriteLine("==修改之前==");      Console.WriteLine(student.ToString());       string[] tempArray = student.Classes;      tempArray[0] = "英語";      Console.WriteLine("==修改之后==");      Console.WriteLine(student.ToString());      Console.ReadKey();    }  }   public struct Student  {    private readonly string name;    private readonly string score;    private readonly string[] classes;     public Student(string name, string score, string[] classes)    {      this.name = name;      this.score = score;      this.classes = new string[classes.Length];      classes.CopyTo(this.classes, 0);      CheckScore(score);    }     public string Name    {      get { return name; }    }     public string Score    {      get { return score; }    }     public string[] Classes    {      get      {        string[] result = new string[classes.Length];        classes.CopyTo(result,0);        return result;      }    }     //檢測分數是否是2位數整數    private void CheckScore(string value)    {      string pattern = @"/d{2}";      if (!Regex.IsMatch(value, pattern))      {        throw new Exception("不是有效分數!");      }    }     public override string ToString()    {      string temp = string.Empty;      foreach (string item in classes)      {        temp += item + ",";      }       return String.Format("姓名:{0},總分:{1},參加的課程有:{2}", name, score,temp.Substring(0, temp.Length -1));    }  } 

運行結果如下圖所示:

此外,如果讓分數不滿足條件,Student student = new Student("張三", "8", classes),就會報錯:

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品最新在线观看| 日韩中文字幕国产| 国产欧美日韩精品在线观看| 欧洲成人免费aa| 亚洲精品国产综合区久久久久久久| 一区二区三区视频在线| 狠狠色狠狠色综合日日五| 国产香蕉精品视频一区二区三区| 亚洲最大的成人网| 欧美日韩ab片| 97在线视频免费播放| 欧美日韩国产999| 欧美激情亚洲另类| 亚洲视频在线免费观看| 亚洲精品久久久久中文字幕二区| 91社区国产高清| 日本欧美精品在线| 日韩在线观看免费全集电视剧网站| 久久亚洲一区二区三区四区五区高| 久久久久久亚洲精品不卡| 欧美激情极品视频| 欧美在线影院在线视频| 亚洲国产精品久久久久秋霞蜜臀| 欧美激情免费观看| 成人h片在线播放免费网站| 欧美丝袜一区二区三区| 久久精品国产96久久久香蕉| 久久在线免费视频| 亚洲一区二区福利| 美女精品视频一区| 中文字幕久久久av一区| 日韩电影免费在线观看中文字幕| 亚洲激情第一页| 蜜月aⅴ免费一区二区三区| 91人成网站www| 国模gogo一区二区大胆私拍| 欧美性videos高清精品| 日韩欧美aⅴ综合网站发布| 精品视频久久久久久久| 日韩在线观看高清| 亚洲福利视频网站| 狠狠躁夜夜躁人人躁婷婷91| 中文字幕免费精品一区高清| 日韩在线视频观看| 欧美午夜丰满在线18影院| 国产午夜精品一区二区三区| 亚洲国产中文字幕久久网| 国产一区二区三区在线播放免费观看| 欧美激情免费视频| 亚洲国产精品va| 亚洲品质视频自拍网| 国产午夜精品视频| 欧美一级视频免费在线观看| 久久久女人电视剧免费播放下载| 欧美日韩精品在线观看| 日韩精品中文字幕在线观看| 91精品国产九九九久久久亚洲| 91伊人影院在线播放| 在线不卡国产精品| 国产精品一二三在线| 姬川优奈aav一区二区| 欧美专区福利在线| 久久色在线播放| 97国产成人精品视频| 欧美日韩国产123| 久久999免费视频| 国内精品免费午夜毛片| 亚洲男人天堂视频| 国产精品av在线| 国产视频久久久久| 欧美激情一区二区三区在线视频观看| 日韩免费视频在线观看| 91精品综合久久久久久五月天| 色综合久久久久久中文网| 精品美女永久免费视频| 国产成人福利夜色影视| 91亚洲精品久久久久久久久久久久| 中文字幕亚洲图片| 欧美又大又粗又长| 国产精品久久久久久久一区探花| 中日韩美女免费视频网站在线观看| 欧美精品手机在线| 色青青草原桃花久久综合| 精品久久国产精品| 欧美大学生性色视频| 国产69精品久久久久久| 国产丝袜精品第一页| 日韩av在线免费播放| 青青草精品毛片| 国产在线观看一区二区三区| 亚洲自拍偷拍第一页| 2019中文字幕免费视频| 久久精品国产综合| 国产精品午夜一区二区欲梦| 亚洲欧洲高清在线| 92福利视频午夜1000合集在线观看| 欧美激情精品在线| 亚洲第一男人天堂| 91精品久久久久久久久青青| 亚洲色图25p| www亚洲精品| 国产香蕉一区二区三区在线视频| 国产午夜一区二区| 国产精品高清在线观看| 久久久国产一区| 欧美成人精品在线视频| 国模精品视频一区二区三区| 亚洲成人中文字幕| 亚洲欧洲视频在线| 欧美日韩国产精品一区二区三区四区| 国产精品视频网站| 自拍偷拍亚洲在线| 精品日韩中文字幕| 亚洲自拍高清视频网站| 国产精品久久久久久久久借妻| www.欧美精品| 成人深夜直播免费观看| 久久97久久97精品免视看| 欧美成人第一页| 色樱桃影院亚洲精品影院| 欧美xxxx18性欧美| 俺也去精品视频在线观看| 欧美性感美女h网站在线观看免费| 国产成人精品日本亚洲| 91国语精品自产拍在线观看性色| 最近2019中文字幕第三页视频| 日韩日本欧美亚洲| 成人黄色免费网站在线观看| 亚洲一区二区三区乱码aⅴ| 国产精品自产拍在线观看中文| 久久精品中文字幕电影| 91wwwcom在线观看| 国产专区精品视频| 亚洲免费伊人电影在线观看av| 欧美日韩亚洲国产一区| 日韩精品一二三四区| 亚洲激情成人网| 亚洲白虎美女被爆操| 中文在线不卡视频| 91av中文字幕| 欧美午夜影院在线视频| 一区二区三区国产视频| 亚洲最新在线视频| 久久久久久久久网站| 一区二区在线免费视频| 欧美色播在线播放| 国产精品羞羞答答| 黑人巨大精品欧美一区二区| 亚洲高清久久久久久| 国产精品福利在线观看网址| 亚洲欧洲高清在线| 日韩精品在线观看视频| 国产一区二区欧美日韩| 亚洲奶大毛多的老太婆| 成人xvideos免费视频| 最近中文字幕2019免费| 91av视频在线观看| 国产一区二区三区在线免费观看| 社区色欧美激情 | 久久久久久美女| 日韩在线精品视频| 久久97久久97精品免视看| 亚洲va欧美va国产综合剧情| 怡红院精品视频|