亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

帶你了解c# 泛型類的功能

發布時間:2020-11-02 15:36:28 來源:億速云 閱讀:187 作者:Leah 欄目:開發技術

帶你了解c# 泛型類的功能?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

  在泛型類中,由于不知道泛型參數T是什么類型,可能是引用類型,也可能是值類型,因此不能將null等賦予泛型類型。如何對泛型對象賦初值、如何保證泛型的正確性等,以使用泛型文檔管理器為例:

  文檔管理器用于從隊列中讀寫文檔。首先創建一個泛型管理器AddDocument()方法添加一個文檔到隊列中,IsDocumentAvailabe只讀屬性指示隊列中是否還有文檔。

public class DocumentManager<T>
{
  private readonly Queue<T> documentQueue = new Queue<T>();

  public void AddDocument(T doc)
  {
    lock (this)
    {
      documentQueue.Enqueue(doc);
    }
  }

  public bool IsDocumentAvailable
  {
    get { return documentQueue.Count > 0; }
  }
}

1、默認值

  給DocumentManager<T>類添加一個GetDocument()方法,該方法以返回隊列中的一個文檔。如果隊列中存在文檔,則返回一個文檔;如果隊列中已沒有文檔,則返回默認值。但是,對于泛型T,不能將null賦予T的對象,因為無法確定它是引用類型還是值類型。在C#中,為我們提供了一個default關鍵字,泛型T的對象賦予默認值,如:引用類型為null、值類型int等為0……

public T GetDocument()
{
  T doc = default(T);
  lock (this)
  {
    if (documentQueue.Count > 0)
    {
      doc = documentQueue.Dequeue();
    }
  }
  return doc;
}

2、約束

  如果泛型類需要調用泛型類型中的方法,那么必須對泛型添加約束。否則,不能確保聲明的泛型類型實現了對應的類型,具有相關方法。創建文檔類Document,其實現了接口IDocument:

public interface IDocument
{
  string Title { get; set; }
  string Content { get; set; }
}

public class Document : IDocument
{
  public Document()
  {
  }

  public Document(string title, string content)
  {
    this.Title = title;
    this.Content = content;
  }

  public string Title { get; set; }
  public string Content { get; set; }
}

  給泛型文檔管理器DocumentManager<T>添加方法DisplayAllDocuments(),使得隊列中所有文檔的標題能展示出。在展示文檔標題前,將類型T強制轉換為IDocumnet接口,以顯示標題:

public void DisplayAllDocuments()
{
  foreach (T doc in documentQueue)
  {
    Console.WriteLine((doc as IDocument).Title);//強制轉換
  }
}

  但是,如果類型T沒有實現接口IDocument,在對類型進行強制轉換時就會出現一個異常。如果對方法添加rty……catch處理,將非常損耗性能。同樣的,即使類型實現了接口IDocument,在進行轉換時也會出現性能的損耗。

  那么,如果能對泛型TDocument進行約束,使得泛型類型必須實現接口IDocument,則不會出現對類型進行強制轉換時的異常。甚至不需要強制轉換,性能也將得到優化。因此,前面的泛型文檔管理器改寫為(前面的T,改寫為TDocument,以此暗示是文檔類型):

public class DocumentManager<TDocument>
  where TDocument : IDocument
{
   //……   
}

  對于實現了約束的泛型文檔管理器,可以處理任何實現了IDocument接口的類。其DisplayAllDocuments()方法改寫為:

public void DisplayAllDocuments()
{
  foreach (TDocument doc in documentQueue)
  {
    Console.WriteLine(doc.Title);
  }
}

  在其他地方調用時,可以用Document類型實例化泛型類型DocumentManager<TDocument>。因為Document實現了接口IDocument:

static void Main()
{
  var dm = new DocumentManager<Document>();
  dm.AddDocument(new Document("Title A", "Sample A"));
  dm.AddDocument(new Document("Title B", "Sample B"));

  dm.DisplayAllDocuments();

  if (dm.IsDocumentAvailable)
  {
    Document d = dm.GetDocument();
    Console.WriteLine(d.Content);
  }
}

  泛型類型支持的幾種約束:struct(結構約束,類型T必須是值類型)、class(類約束,類型T必須是引用類型)、IFoo(類型T必須實現接口IFoo)、new()(構造函數約束,類型T必須有一個無參構造函數)、TOther(類型T派生自TOther,也稱“裸類型約束”)。

  泛型約束中:

  • 只能為無參構造函數定義構造約束,不能為有任何參數的構造函數定義構造函數約束。
  • 泛型可以有多個約束。如:public class DocumentManager<TDocument> where TDocument : IDocument,new()。
  • where不能定義必須由泛型類型實現的運算符
     

3、繼承

  泛型類也可以實現繼承,如Queue<T>里,繼承實現了接口IEnumerable<T>接口。泛型類型可以實現泛型接口,也可以派生自一個類。泛型類型可以派生自泛型基類:

class Base<T>
{
  //...............
}

class Derived<T>:Base<T>
{
  //...............
}

  派生類可以是泛型類,也可以是非泛型類型:

abstract class Calc<T>
{
  public abstract T Add(T x, T y);
  public abstract T Sub(T x, T y);
}

class IncCalc: Calc<int>
{
  public override int Add(int x, int y)
  {
    return x + y;
  }
  public override int Sub(int x, int y)
  {
    return x - y;
  }
}
class DoubleCalc : Calc<double>
{
  public override double Add(double x, double y)
  {
    return x + y;
  }
  public override double Sub(double x, double y)
  {
    return x - y;
  }
}

4、靜態成員

  泛型類的靜態成員只能在一個實例中共享:

class StaticDemo<T>
{
  public static string Type;
}

static void Main()
{
  StaticDemo<int>.Type = "int類型";
  StaticDemo<object>.Type = "Object類型";
  Console.WriteLine(StaticDemo<int>.Type);//輸出:int類型
}

  實際上,每當用一個類型去代替泛型中的T時,都是在創造一個實例類型。因此,泛型類型中的靜態字段,會在不同的類型替代泛型T的實例中重新生成。這樣設計也有好處,可以為程序提供一個“泛型緩存”的概念,使用泛型的靜態成員,使它存放在緩存中,方便調用。

關于帶你了解c# 泛型類的功能問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

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

AI

黎平县| 哈密市| 通山县| 左贡县| 西吉县| 遂溪县| 和顺县| 宝应县| 锦屏县| 博客| 拉孜县| 土默特右旗| 磴口县| 乌拉特前旗| 萨嘎县| 前郭尔| 定日县| 辽宁省| 大新县| 乐业县| 沙河市| 额尔古纳市| 漠河县| 松溪县| 库尔勒市| 吴旗县| 郁南县| 黄陵县| 南昌市| 竹溪县| 屏东县| 广西| 武平县| 廊坊市| 玉林市| 五河县| 离岛区| 从化市| 阜南县| 临江市| 孟州市|