.NET一些接口含義和應用

IEnumerable 接口
公開枚舉數,該枚舉數支持在集合上進行簡單迭代。
IEnumerable和IEnumerator 接口
實現IEnumerable接口的類型可以利用枚舉對象支持對其項目的只向前訪問,枚舉對象爲項目集提供只向前的只讀指針
IEnumerable接口有一個方法 GetEnumerator
public interface IEnumerable
{
   IEnumerator GetEnumerator();

這個方法每次調用時返回一個枚舉對象的新實例,返回的對象執行IEnumerator接口,這個方法可以用來順序訪問某個枚舉類型所擁有的System.Object類型集

<script Language="C#" runat="server">

void Page_Load(Object sender, EventArgs args ) {

  String[] authors = new String[] {"Richard","Alex","Dave","Rob","Brian","Karli"};

  IEnumerator e;
  e = authors.GetEnumerator();

  while (e.MoveNext() == true) {
    outResult.InnerHtml += e.Current + "<br />";
  }

}
</script>

所有的數組都可以執行IEnumerator接口,所以可以調用GetEnumerator方法,IEnumerator接口的Current屬性定義爲System.Object類型
在.NET Framework類庫中,其他所有的可枚舉類型均從IEnumerable接口繼承(其他的枚舉類型爲訪問他們自身所包含的項目提供了額外的成員,也使用
枚舉對象來支持只前向光標方法) 所有其他的Enumerator接口也都是從IEnumerable接口派生。

 

IComparer 接口
列表排序 IComparer 和 IComparable
像ArrayList 和 Array這樣的集合類使用System.Collections.IComparer 接口來確定類型實例的大小,該接口有一個方法
public int Compare(Object x,Object y)
公開一種比較兩個對象的方法。此接口與 Array.Sort 和 Array.BinarySearch 方法一起使用。它提供一種自定義集合排序順序的方法。

應用實例
using System;

namespace Collection
{
 /// <summary>
 /// Person 的摘要說明。
 /// </summary>
 ///
 public class Person
 {
  public int ID;
  public int Age; 

  public Person()
  {
   this.ID = 0;
   this.Age = 0;
  }
  public Person(int id,int age)
  {
   this.ID = id;
   this.Age = age;
  }
  
  public void Show()
  {
   System.Console.WriteLine("年齡={0},代號={1}",Age,ID);
  }

  public static void ShowPersons(Person[] persons)
  {
   foreach(Person person in persons)
   {
    System.Console.WriteLine("年齡={0},代號={1}",person.Age,person.ID);
   }
  }
 }

 public class PersonComparer:System.Collections.IComparer
 { 
  int System.Collections.IComparer.Compare(object x,object y)
  {
   if (x == null || y == null)
   {
    throw new  System.ArgumentException("參數不能爲空");
   }

   Person temp = new Person();
   if (!x.GetType().Equals(temp.GetType()) || !y.GetType().Equals(temp.GetType()))
   {
    throw new System.ArgumentException("類型不一致");
   }
   
   Person personX = (Person)x;
   Person personY = (Person)y;

   if (personX.ID > personY.ID)
    return 1;
   else if(personX.ID < personY.ID)
    return -1;
   else
    return 0;

  }
 }
 /// <summary>
 /// Class1 的摘要說明。
 /// </summary>
 class Class1
 {
  /// <summary>
  /// 應用程序的主入口點。
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
   Random rand=new Random();
   Person[] persons=new Person[6];
   Console.WriteLine("隨機產生的Person數組爲:");
   for(int i=0;i<persons.GetLength(0);i++)
   {
    persons[i] = new Person();
    persons[i].ID = rand.Next()%10;
    persons[i].Age = rand.Next()%50;
    persons[i].Show();
   }
   PersonComparer personComparer=new PersonComparer();
   Array.Sort(persons,personComparer);
   Console.WriteLine("排序後的結果:");
   Person.ShowPersons(persons);

   Person personToBeFind=new Person();
   Console.WriteLine("輸入ID");
   personToBeFind.ID=int.Parse(Console.ReadLine());
   Console.WriteLine("輸入Age");
   personToBeFind.Age=int .Parse(Console.ReadLine());

   // BinarySearch 對半查找
   int index=Array.BinarySearch(persons,personToBeFind,personComparer);
   if(index>=0)
    Console.WriteLine("待查找的元素是數組的第{0}個元素",index+1);
   else
    Console.WriteLine("對不起,沒有所找的元素");
   Console.ReadLine();
  }
 }
}

 

ICollection 接口 定義所有集合的大小、枚舉數和同步方法,是 System.Collections 命名空間中類的基接口。
IDictionary 和 IList 是基於 ICollection 接口的更專用的接口。
IDictionary 實現是鍵/值對的集合,如 Hashtable 類。IList 實現是可被排序且可按照索引訪問其成員的值的集合,如 ArrayList 類。

某些集合(如 Queue 類和 Stack 類)限制對其成員的訪問,它們直接實現 ICollection 接口。

如果 IDictionary 接口和 IList 接口都不能滿足所需集合的要求,則從 ICollection 接口派生新集合類以提高靈活性。
在一個集合中進行順序枚舉時常見的任務
int index;
index = Array.IndexOf(authors,"Richard");
if (index != -1)
{
   Response.Write("<p>"+authors[index]+"is in the author list);
}

Array和IList
內置的Array類型執行IList接口 但僅實現該接口的 IndexOf Clear Contains方法以及一個屬性item,如果想調用其他IList成員 就會產生
NotSupportedException IList的其他成員定義爲外部接口成員 必須通過IList接口纔可以訪問

例如
void Page_Load(Object sender, EventArgs args ) {

  String[] authors = new String[] {"Richard","Alex",
                      "Dave","Rob","Brian","Karli"};

  int index;
  index = Array.IndexOf(authors,"Richard");
  if (index != -1) {
    outResult.InnerHtml = authors[index] + " is in the author list<br />";
  }

  IList list;

  list = (IList) authors;
  if (list.Contains("Richard")) {
    index = list.IndexOf("Richard");
    outResult.InnerHtml += list[index] + " is in the author list";
  }

}

ArrayList類執行IList接口,它可以實現和使用所有的IList方法 ArrayList類可以隱式地把IList接口成員作爲公用接口
<script runat="server">

ArrayList movieList = new ArrayList();

void Page_Load(Object Sender, EventArgs Args) {
  if (IsPostBack == true) {
    movieList = (ArrayList) ViewState["movies"];
  }
  else {
    movieList = new ArrayList();
    movieList.Add("Pulp Fiction");
    movieList.Add("Aliens");
    movieList.Add("The Good, the Bad and the Ugly");
    ViewState["movies"] = movieList;
    ShowList();
  }
}

void ShowList() {
  if (movieList.Count > 0) {
    foreach (String Movie in movieList) {
      outList.InnerHtml += Movie + "<br />";
    }
  }
  else {
    outList.InnerHtml = "There are no movies in the list.";
  }
}

// add an item to the list
void OnAddMovie(Object Sender, EventArgs Args) {
  movieList.Add(MovieName.Text);
  ShowList();
}

// delete an item from the list
void OnDeleteMovie(Object Sender, EventArgs Args) {
  if (movieList.IndexOf(MovieName.Text) == -1) {
    status.InnerHtml = "Movie not found in list";
  }
  else {
    movieList.Remove(MovieName.Text);
  }
  ShowList();
}

// sort the list
void OnSortList(Object Sender, EventArgs Args) {
  movieList.Sort();
  ShowList();
}

// class that implements the comparison logic for the sort
class MyComparer : IComparer
{
  public int Compare( object x, object y )
  {
    IComparable ic;
    int compareResult;
    ic = (IComparable) x;
    compareResult = ic.CompareTo( y );
    if ( compareResult != 0 )
      compareResult = compareResult * -1;
    return compareResult;
  }
}

// custom sort using MyComparer
void OnCustomSortList(Object Sender, EventArgs Args) {
  IComparer custom = new MyComparer();
  movieList.Sort(custom);
  ShowList();
}

</script>

特別提醒:在ArrayList 中添加項目時 內部數組的大小會根據需要自動擴展 默認大小是16,如果知道列表中項目的數目,就應該優化列表初始的容量
否則 當列表尺寸增大時 多次所內存分配和項目複製操作就會佔用比較的多的系統資源
ArrayList list = new ArrayList()
list.Capacity = 128;
一旦列表填充了項目 就可以調用 TrimToSize()方法來釋放未使用的存取空間

 


IDictionary 實現是鍵/值對的集合,如 Hashtable 類。
Hashtable類 表示相關關鍵字和值的一個字段 顯示爲散列表 可以使用關鍵字值的散列有效的存儲和檢索值

例如
void Page_Load(Object sender, EventArgs args ) {

  Hashtable ourSession = new Hashtable();
  ourSession["value1"] = "Wrox";
  ourSession["value2"] = "Wiley";
  String value;
  foreach (String key in ourSession.Keys) {
    outResult.InnerHtml += "Key:" + key + " Value:" + ourSession[key] + "<br />";
  }
  outResult.InnerHtml += "<p />";

  if (ourSession.ContainsKey("value1") == true) {
    outResult.InnerHtml += "The key 'value1' is in the Hashtable<br />";
  }
  if (ourSession.ContainsValue("Wrox") == true) {
    outResult.InnerHtml += "The value 'Wrox' is in the Hashtable";
  }
}

Hashtable類執行IEnumerable 所以可以枚舉所有被包含的關鍵字和項目 調用Hashtable的IEnumerable.GetEnumerator方法 會返回一個枚舉對象
該枚舉對象可以使用值類型的Systme.Collecion.DictionaryEntry來顯示被包含的項目
foreach(DictionaryEntry entry in table)
{
   Reponse.Write(entry.Key+entry.Value);
}

Hashtable對象的公用GetEnumerator方法返回一個IDictionaryEnumerator接口,此枚舉對象包含了IEnumerator所有的方法和屬性 還有三個額外的屬性
用來顯示當前項目的Key Value DictionaryEntry 在不使用foreach時 使用這些額外的屬性返回自定義枚舉可以減少類型轉換 因爲CLR必須堅持類型轉換是否安全
而類型轉換又會導致性能開銷

例如
IDictionaryEnumerator e;
e = table.GetEnumerator();
while(e.MoveNext())
{
    Response.Write("<Br/>Key" + e.Key +"Value:"+e.Value);
}

IDidtionary接口 該接口定義了一些屬性和方法 可用來處理關鍵字和與之相關的值的未排序集合,在IDidtionary接口中 關鍵字和值都定義爲
System.Object了類型,此接口繼承於ICollction

Case Sensitivity in Hashcode Generation

void Page_Load(Object sender, EventArgs args ) {

  String name1, name2;

  name1 = "Richard";
  name2 = "RICHARD";

  outResult1.InnerHtml = "Hash code for '" + name1 + "' is " + name1.GetHashCode();
  outResult1.InnerHtml += "<br />Hash code for '" + name2 + "' is " + name2.GetHashCode();

  IHashCodeProvider hcp;
  hcp = CaseInsensitiveHashCodeProvider.Default;

  outResult2.InnerHtml = "Hash code for '" + name1 + "' is " + hcp.GetHashCode(name1);
  outResult2.InnerHtml += "<br />Hash code for '" + name2 + "' is " + hcp.GetHashCode(name2);

}

A Sorted View of an Existing Collection

void Page_Load(Object sender, EventArgs args ) {

  Hashtable names = new Hashtable();
  names.Add("RA", "Richard Anderson");
  names.Add("DS", "David Sussman");
  names.Add("RH", "Rob Howard");
  names.Add("AH", "Alex Homer");
  names.Add("KW", "Karli Watson");
  names.Add("BF", "Brian Francis");

  foreach (DictionaryEntry name in names) {
    outResult1.InnerHtml += "Key:" + name.Key + " - Value:" + name.Value + "<br />";
  }

  SortedList sortedNameList = new SortedList(names);

  foreach (DictionaryEntry name in sortedNameList) {
    outResult2.InnerHtml += "Key:" + name.Key + " - Value:" + name.Value + "<br />";
  }

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章