91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

深入淺析c#中的字段

發布時間:2020-11-19 14:31:43 來源:億速云 閱讀:183 作者:Leah 欄目:開發技術

本篇文章給大家分享的是有關深入淺析c#中的字段,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

1、不要為抽象類提供公開的構造方法

  抽象類可以有構造方法,但是抽象類不能實例化。如果編程人員沒有制定構造方法,編譯器會自動生成一個默認的protected構造方法。下面是一個標準的簡單抽象類:

abstract class MyAbstractClass
{
  protected MyAbstractClass( ) { }
}

  抽象類的構造方法不應該是public或internal的。抽象類設計的本意是只能讓子類繼承,而不是用于生成實例對象。如果抽象類是public或者internal的,它對于其他類型來說就是可見的,而這是不必要的,多余的。抽象類只需對子類可見即可。

2、可見字段應該重構為屬性

  字段與屬性有本質的區別,屬性是方法。如下面的Person類型:

class Person
{
  public string Name { get; set; }
}

  編譯器針對屬性Name編譯后,會生成一個字段和兩個方法。

  屬性相對于字段有如下優勢:

    1)可以為屬性添加代碼。屬性是方法,所以可以在方法內對設置或獲取屬性的過程進行編寫代碼控制。如事件支持等。

    2)可以讓屬性支持線程安全。要讓屬性變成線程安全的,可以讓類型自身去實現。如果讓字段支持線程安全,就只有依靠調用者本身實現。

    3)屬性得到VS編譯器支持,能實現自動屬性的功能。自動屬性的特點在LINQ中應用十分廣泛,在匿名類型中,它只能實現只讀的自動屬性,但字段不支持。

    4)從設計的角度(面向對象),公開的字段也應該使用屬性。改變字段的狀態,類型不會被通知到;而改變屬性的值,類型支持則會被通知。

  綜上,如果一個類型存在一個可見字段,那么它應該被重構為屬性。如果某個屬性只對內部可見,但不涉及上面4點,則建議使用字段。

3、區別對待override和new

  override和new使類型體系因為繼承而呈現出多態性。多態是“面向對象語言”的三個重要特性之一。多態要求子類具有與基類方法同名的方法,而override和new的有如下作用:

    1)如果子類中的方法前面帶有new關鍵字,則該方法被定義為獨立于基類的方法。

    2)如果子類中的方法前面帶有override關鍵字,則子類的對象將調用該方法,而不是調用基類的方法。

  如果,對于父類的方法在子類中使用了new關鍵字,則兩個方法相互獨立。此時,使用子類類型的對象調用方法時,程序執行的將是子類類型new的方法代碼;而如果將子類類型轉換為父類類型后,對象調用方法時將執行的是父類的方法代碼。

  如果使用了override關鍵字重寫方法,那么不論子類類型的對象是否轉換為父類類型,調用方法時都將執行的是子類的代碼。

  如果對于子類中,聲明與父類相同函數名稱的方法,但并不使用關鍵字new和override。編譯器在編譯后會提出警告,但不影響程序運行。此時,編譯器會默認為是new的效果,所以輸出和顯示設置與new的效果一樣。

4、避免在構造方法中調用虛成員

  在構造方法中調用虛成員會出現意想不到的錯誤。

class Program
 {
   static void Main(string[] args)
   {
     Chinese chinese = new Chinese();
   }
 }

 class Person
 {
   public Person()
   {
     InitSkin();
   }

   protected virtual void InitSkin()
   {
     //省略
   }
 }

 class Chinese:Person
 {
   Rece Rece;

   public Chinese():base()
   {
     Rece = new Rece() { Name = "趙銘" };
   }

   protected override void InitSkin( )
   {
     Console.WriteLine(Rece.Name);
   }
 }

 class Rece
 {
   public string Name { get; set; }
 }

  運行該示例,會出現NullReferenceException:未將對象引用設置到對象的實例。

  在調用代碼中,需要創建一個Chinese的實例對象chinese。由于Chinese類型有基類Person,所以運行時首先調用基類的構造方法。在基類的構造方法中,構造函數會調用InitSkin虛方法。在程序運行時,調用的是子類的InitSkin方法。在子類的InitSkin方法中又在使用子類的Rece變量。但這個時候,子類的構造函數還沒調用,因此Rece變量未實例化,但是InitSkin方法又在使用Rece變量,導致錯誤。

5、成員應優先考慮公開的基類型或接口

  類型成員在優先考慮公開基類型或接口,會使得類型支持更多的應用場合。

  FCL中的集合類型根據功能劃分有List<T>、Dictionary<TKey, TValue>、HashSet<T>等。例如,需要清空集合中的元素,返回空集合的方法Empty,如果不返回基類型或者接口的情況下,就要求我們為每個集合類型都實現該方法。但是,在FCL中實現了一個靜態類型Enumerable,代碼如下:

 public static IEnumerable<TResult> Empty<TResult>()
 {
   return EmptyEnumerable<TResult>.Instance;
 }

  使用了泛型接口IEnumerable,所以所有集合子類都可以不實現自己的Empty方法,做到項目的靈活應用。

6、重寫時不應使用子類參數

  重寫時,如果使用了子類參數,可能會偏離設計者的預期目標。

  如存在以下繼承體系:

class Employee
{
}

class Manager:Employee
{
}

class Salary
{
  public void SetSalary(Employee e)
  {
    Console.WriteLine("職員被設置了薪水。");
  }
}    

class ManagerSalary:Salary
{
  public void SetSalary(Manager e)
  {
    Console.WriteLine("經理被設置了薪水。");
  }
}

  類型ManagerSalary中的SetSalary方法重寫了Salary中的相同方法,但是參數采用了一個子類的參數。現在在程序中調用代碼如下:

public static void Main()
{
  ManagerSalary m = new ManagerSalary();
  m.SetSalary(new Employee());
}

  設計者的本意時為經理設置對應的薪水,但是實際調用的代碼卻設置了員工的薪水。因此,在重寫時使用子類參數有一定的風險。正確的方法時仍舊使用Employee類型參數,讓編譯器提醒我們要使用關鍵字new。

以上就是深入淺析c#中的字段,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湖州市| 达孜县| 婺源县| 新民市| 泰兴市| 永清县| 张掖市| 洛川县| 巨野县| 阜城县| 黎平县| 宁都县| 噶尔县| 无锡市| 凯里市| 大庆市| 临武县| 灵台县| 阿荣旗| 固始县| 凤凰县| 海原县| 新竹县| 金湖县| 嵊泗县| 黑龙江省| 兖州市| 满城县| 兴安盟| 扎兰屯市| 云霄县| 乌兰察布市| 沁源县| 舟曲县| 平塘县| 全椒县| 凉城县| 南充市| 将乐县| 张掖市| 淮滨县|