欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

區(qū)分C# 中的 Struct 和 Class

 更新時(shí)間:2020年09月14日 08:48:59   作者:技術(shù)譯站  
這篇文章主要介紹了如何區(qū)分C# 中的 Struct 和 Class,幫助大家更好的理解和學(xué)習(xí)c#編程,感興趣的朋友可以了解下

翻譯自 Manju lata Yadav 2019年6月2日 的博文 《Difference Between Struct And Class In C#》,補(bǔ)充了一些內(nèi)容和示例。

結(jié)構(gòu)體(struct)是類(lèi)(class)的輕量級(jí)版本。結(jié)構(gòu)體是值類(lèi)型,可用于創(chuàng)建行為類(lèi)似于內(nèi)置類(lèi)型的對(duì)象。

比較

結(jié)構(gòu)體和類(lèi)共享許多特性,但與類(lèi)相比有以下局限性。

  • 結(jié)構(gòu)體不能有默認(rèn)構(gòu)造函數(shù)(無(wú)參構(gòu)造函數(shù))或析構(gòu)函數(shù),構(gòu)造函數(shù)中必須給所有字段賦值。
 public struct Coords
 {
   public double x;
   public double y;
  
   public Coords() //錯(cuò)誤,不允許無(wú)參構(gòu)造函數(shù)
   {
     this.x = 3;
     this.y = 4;
   }
    
   public Coords(double x) //錯(cuò)誤,構(gòu)造函數(shù)中必須給所有字段賦值
   {
     this.x = x;
   }
    
   public Coords(double x) //這個(gè)是正確的
   {
     this.x = x;
     this.y = 4;
   }
  
   public Coords(double x, double y) //這個(gè)是正確的
   {
     this.x = x;
     this.y = y;
   }
 }
  • 結(jié)構(gòu)體是值類(lèi)型,在賦值時(shí)進(jìn)行復(fù)制。
  • 結(jié)構(gòu)體是值類(lèi)型,而類(lèi)是引用類(lèi)型。
  • 結(jié)構(gòu)體可以在不使用 new 操作符的情況下實(shí)例化。 例如:
 public struct Coords
 {
   public double x;
   public double y;
 }
  
 static void Main()
 {
   Coords p;
   p.x = 3;
   p.y = 4;
   Console.WriteLine($"({p.x}, {p.y})"); // 輸出: (3, 4)
 }
  • 結(jié)構(gòu)體不能繼承于另一個(gè)結(jié)構(gòu)體或者類(lèi),類(lèi)也不能繼承結(jié)構(gòu)體。所有結(jié)構(gòu)體都直接繼承于抽象類(lèi) System.ValueType,System.ValueType 又繼承于 System.Object。
  • 結(jié)構(gòu)體不能是基類(lèi),因此,結(jié)構(gòu)體不能是 abstract 的,且總是隱式密封的(sealed)。
  • 不允許對(duì)結(jié)構(gòu)體使用抽象(abstract)和密封(sealed)修飾符,也不允許對(duì)結(jié)構(gòu)體成員使用 protectedprotected internal 修飾符。
  • 結(jié)構(gòu)體中的函數(shù)成員不能是抽象的(abstract)或虛的(virtual),重寫(xiě)(override)修飾符只允許重寫(xiě)從 System.ValueType 繼承的方法。
  • 結(jié)構(gòu)體中不允許實(shí)例屬性或字段包含初始值設(shè)定項(xiàng)。但是,結(jié)構(gòu)體允許靜態(tài)屬性或字段包含初始值設(shè)定項(xiàng)。 例如:
 public struct Coords
 {
   public double x = 4; //錯(cuò)誤, 結(jié)構(gòu)體中初始化器不允許實(shí)例字段設(shè)定初始值
   public static double y = 5; // 正確
   public static double z { get; set; } = 6; // 正確
 }
  • 結(jié)構(gòu)體可以實(shí)現(xiàn)接口。
  • 結(jié)構(gòu)體可以用作 nullable type(即:Nullable<T> 中的 T),對(duì)其賦值 null 值,參考【Nullable<T> Struct】

什么時(shí)候使用結(jié)構(gòu)體或類(lèi)?

要回答這個(gè)問(wèn)題,我們應(yīng)該很好地理解它們的差異。

序號(hào) 結(jié)構(gòu)體(struct) 類(lèi)(class)
1 結(jié)構(gòu)體是值類(lèi)型,可以在棧(stack)上分配,也可以在包含類(lèi)型中內(nèi)聯(lián)分配。 類(lèi)是引用類(lèi)型,在堆(heap)上分配并垃圾回收。
2 值類(lèi)型的分配和釋放通常比引用類(lèi)型的分配和釋放更節(jié)約成本。 大的引用類(lèi)型的賦值比大的值類(lèi)型的賦值成本更低。
3 在結(jié)構(gòu)體中,每個(gè)變量都包含自己的數(shù)據(jù)副本(ref 和 out 參數(shù)變量除外),對(duì)一個(gè)變量的操作不會(huì)影響另一個(gè)變量。 在類(lèi)中,兩個(gè)變量可以包含同一對(duì)象的引用,對(duì)一個(gè)變量的任何操作都會(huì)影響另一個(gè)變量。

這樣,結(jié)構(gòu)體(struct)只能在確定以下情形時(shí)使用:

  • 它在邏輯上表示單個(gè)值,比如基本類(lèi)型(int, double,等等)。
  • 它是不可變的(immutable)。
  • 它不會(huì)頻繁地裝箱和拆箱。

在所有其他情形,應(yīng)該將類(lèi)型定義為類(lèi)(class)。

結(jié)構(gòu)體示例:

struct Location
{
  public int x, y;
  public Location(int x, int y)
  {
    this.x = x;
    this.y = y;
  }
}

static void Main()
{
  Location a = new Location(20, 20);
  Location b = a;
  a.x = 100;
  Console.WriteLine(b.x);
}

輸出將是 20?!癰” 的值是 “a” 的副本,因此 “b” 不受 “a.x” 更改的影響。但是在類(lèi)中,輸出將是 100,因?yàn)樽兞?“a” 和 “b” 引用同一個(gè)對(duì)象。

以下為譯者補(bǔ)充

結(jié)構(gòu)體實(shí)例與類(lèi)實(shí)例

結(jié)構(gòu)體實(shí)例的內(nèi)存在棧(stack)上進(jìn)行分配,所占用的內(nèi)存隨聲明它的類(lèi)型或方法一起回收。 這就是在賦值時(shí)要復(fù)制結(jié)構(gòu)體的一個(gè)原因。 相比之下,類(lèi)實(shí)例的內(nèi)存在堆(heap)上進(jìn)行分配,當(dāng)對(duì)類(lèi)實(shí)例的所有引用都超出范圍時(shí),為該類(lèi)實(shí)例分配的內(nèi)存將由公共語(yǔ)言運(yùn)行時(shí)自動(dòng)回收(垃圾回收)。

結(jié)構(gòu)體實(shí)例的值相等性

兩個(gè)結(jié)構(gòu)體實(shí)例的比較是基于值的比較,而類(lèi)實(shí)例的比較則是對(duì)其引用的比較。

若要確定兩個(gè)結(jié)構(gòu)體實(shí)例中的實(shí)例字段是否具有相同的值,可使用 ValueType.Equals 方法。 由于所有結(jié)構(gòu)都隱式繼承自 System.ValueType,因此可以直接在其對(duì)象上調(diào)用該方法,如以下示例所示:

public struct Person
{
  public string Name;
  public int Age;
  public Person(string name, int age)
  {
    Name = name;
    Age = age;
  }
}

static void Main()
{
  Person p1 = new Person("技術(shù)譯站", 100);
  Person p2;
  p2.Name = "技術(shù)譯站";
  p2.Age = 100;

  if (p2.Equals(p1))
    Console.WriteLine("p2 和 p1 有相同的值。");

  Console.ReadKey();
}
// 輸出: p2 和 p1 有相同的值。

System.ValueType 是值類(lèi)型的隱式基類(lèi), 它的 Equals 使用反射實(shí)現(xiàn),因?yàn)樗仨毮軌虼_定任何結(jié)構(gòu)體中有哪些字段。 在創(chuàng)建自己的結(jié)構(gòu)體時(shí),重寫(xiě) Equals 方法可以提供特定于你的類(lèi)型的高效求等算法。

“基于值的相等”這一點(diǎn)和 C# 9.0 中新增的記錄(record) 類(lèi)型具有相似之處

作者 : Manju lata Yadav

譯者 : 技術(shù)譯民

出品 : 技術(shù)譯站

鏈接 : 英文原文

以上就是區(qū)分C# 中的 Struct 和 Class的詳細(xì)內(nèi)容,更多關(guān)于C# 中 Struct 和 Class的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論