程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 泛型--約束(1)

泛型--約束(1)

編輯:關於C語言

9.5 約束

有的時候,您必須確保添加進泛型列表中的元素擁有某些約束(例如,它們從一個給定的基類繼承或它們實現了指定的接口)。在下面的例子中,我們實現了一個簡單的可排序的單鏈表。鏈表由多個Node組成,每個Node必須保證添加進去的元素實現了IComparer接口。您可以這樣聲明:

public class Node<T> : IComparable<Node<T>> where T : IComparable<T>

這句代碼定義了一個泛型Node,它操作類型T。Node中的T實現了IComparable<T>接口,這意味著兩個Node的T可以進行對比。Node類通過約束(where T : IComparable<T>)來操作那些實現了IComparable接口的類型。因此您可以使用任何類型來替代T,只要那種類型實現了IComparable接口

例9-12舉例說明了完整的接口實現,並進行分析如下。

例9-12 使用約束

using System;
using System.Collections.Generic;
namespace UsingConstraints
{
  public class Employee : IComparable<Employee>
  {
    private string name;
    public Employee(string name)
    {
      this.name = name;
    }
    public override string ToString()
    {
      return this.name;
    }
    //實現接口
    public int CompareTo(Employee rhs)
    {
      return this.name.CompareTo(rhs.name);
    }
    public bool Equals(Employee rhs)
    {
      return this.name == rhs.name;
    }
  }
  //節點必須實現Node<T>的IComparable接口。
  //通過where關鍵字約束Node只接收實現了IComparable接口的項
  public class Node<T> : IComparable<Node<T>> where T : IComparable<T>
  {
    //成員變量
    private T data;
    private Node<T> next = null; //下一個節點
    private Node<T> prev = null; //前一個節點
    //構造方法
    public Node(T data)
    {
      this.data = data;
    }
    //屬性
    public T Data
    {
      get { return this.data; }
    }
    public Node<T> Next
    {
      get { return this.next; }
    }
    public int CompareTo(Node<T> rhs)
    {  //這樣使用是因為約束
      return data.CompareTo(rhs.data);
    }
    public bool Equals(Node<T> rhs)
    {
      return this.data.Equals(rhs.data);
    }
    //方法
    public Node<T> Add(Node<T> newNode)
    {  //下面的“我”代表類的當前實例
      if (this.CompareTo(newNode) > 0) //小於我則放在我前面
      {
        newNode.next = this; //新節點的下一節點指向我
        //如果我有前一個節點,則新節點的前一個節點指向它
        //新節點做為它的下一個節點
        if (this.prev != null)
        {
          this.prev.next = newNode;
          newNode.prev = this.prev;
        }
        //設置我的前一個節點為新節點
        this.prev = newNode;
        //從下面的LinkedList<T>代碼可以得知,添加都是從
        //頭節點開始判斷,只有新節點為頭節點時才返回它
        return newNode;
      }
      else //大於等於我則放在我後面
      {
        //如果我有下一個,則跟下一個進行對比
        //這裡使用了遞歸,直到新節點找到比它大的節點為止
        if (this.next != null)
        {
          this.next.Add(newNode);
        }
        //如果我沒有下一個節點,則設置新節點為我的下一個
        //節點,並把它的上一個節點指向我
        else
        {
          this.next = newNode;
          newNode.prev = this;
        }
        return this;
      }
    }
    public override string ToString()
    {
      string output = data.ToString();
      if (next != null)
      {  //這裡也使用了遞歸打印鏈表上的所有元素
        output += ", " + next.ToString();
      }
      return output;
    }
  }
  public class LinkedList<T> where T : IComparable<T>
  {
    //成員變量
    private Node<T> headNode = null;
    //索引器
    public T this[int index]
    {
      get
      {  //由於是鏈表,這裡需要從頭遍歷
        int ctr = 0;
        Node<T> node = headNode;
        while (node != null && ctr <= index)
        {
          if (ctr == index)
          {
            return node.Data;
          }
          else
          {
            node = node.Next;
          }
          ++ctr;
        }
        throw new ArgumentOutOfRangeException();
      }
    }
    //默認構造方法
    public LinkedList()
    {
    }
    //方法
    public void Add(T data)
    {
      if (headNode == null)
      {
        headNode = new Node<T>(data);
      }
      else
      {
        headNode = headNode.Add(new Node<T>(data));
      }
    }
    public override string ToString()
    {
      if (this.headNode != null)
      {
        return this.headNode.ToString();
      }
      else
      {
        return string.Empty;
      }
    }
  }
  //測試類
  class Test
  {
    static void Main()
    {  //創建一個實例來進行方法
      Test t = new Test();
      t.Run();
    }
    public void Run()
    {
      LinkedList<int> myLinkedList = new LinkedList<int>();
      Random rand = new Random();
      Console.Write("Adding: ");
      for (int i = 0; i < 10; i++)
      {
        int nextInt = rand.Next(10);
        Console.Write("{0} ", nextInt);
        myLinkedList.Add(nextInt);
      }
      LinkedList<Employee> employees = new LinkedList<Employee>();
      employees.Add(new Employee("John"));
      employees.Add(new Employee("Paul"));
      employees.Add(new Employee("George"));
      employees.Add(new Employee("Ringo"));
      Console.WriteLine("\nRetrIEving collections");
      Console.WriteLine("Integers: " + myLinkedList);
      Console.WriteLine("Employees: " + employees);
    }
  }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved