程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> 在Visual C# 2.0中創建優雅代碼

在Visual C# 2.0中創建優雅代碼

編輯:C#基礎知識
熱衷於C#語言的人會喜歡上Visual C# 2005。Visual Studio 2005為Visual C# 2005帶來了大量令人興奮的新功能,例如泛型、迭代器、局部類和匿名方法等。雖然泛型是人們最常談到的也是預期的功能,尤其是在熟悉模板的C++開發人員中間,但是其他的新功能同樣是對Microsoft .NET開發寶庫的重要補充。與C#的第一個版本相比,這些功能和語言附加將會提高整體的生產效率,從而使開發人員能夠以更快的速度寫出更加簡潔的代碼。

 迭代器

  在C# 1.1中,可以使用foreach循環來遍歷諸如數組、集合這樣的數據結構:

  

string[] cities = {"New York","Paris","London"};

        foreach(string city in cities)

        {
  
        Console.WriteLine(city);

        }

  實際上,可以在foreach循環中使用任何自定義數據集合,只要該集合類型實現了返回IEnumerator接口的GetEnumerator方法即可。通常,需要通過實現IEnumerable接口來完成這些工作:

  

public interface IEnumerable

        {
  
        IEnumerator GetEnumerator();

        }

        public interface IEnumerator

        {
  
        object Current{get;}
  
        bool MoveNext();
  
        void Reset();

        }

  在通常情況下,實現IEnumerable接口的類是作為要遍歷的集合類型的嵌套類來提供的。這樣,此種迭代器設計模式維持了迭代的狀態。將嵌套類作為枚舉器的好處是因為它可以訪問其包含類的所有私有成員,而且,對迭代客戶端隱藏了底層數據結構的實際實現細節,使得能夠在多種數據結構上使用相同的客戶端迭代邏輯,如圖1所示。

圖1 迭代器設計模式

  此外,由於每個迭代器都保持單獨的迭代狀態,所以多個客戶端可以執行單獨的並發迭代。通過實現IEnumerable接口,諸如數組和隊列這樣的數據結構可以支持這種非常規的迭代。在foreach循環中生成的代碼調用類的GetEnumerator方法可以簡單地獲得一個IEnumerator對象,然後將其用於while循環,接著,通過連續調用它的MoveNext方法來遍歷集合。如果您需要顯式地遍歷集合,您可以直接使用IEnumerator(無須使用foreach語句)。

  但是使用這種方法有一些問題。首先,如果集合包含值類型,則需要對它們進行裝箱和拆箱才能獲得項,因為IEnumerator.Current返回一個Object類的對象。這將導致潛在的性能降低 和托管堆上的壓力增大。即使集合包含引用類型,仍然會產生從對象向下強制類型轉換的不利結果。雖然大多數開發人員不熟悉這一特性,事實上在C# 1.0中,不必實現IEnumerator或IEnumerable接口就可以為每個循環實現迭代器模式。編譯器將選擇調用強類型化版本,以避免強制類型轉換和裝箱。結果是,即使在1.0版本中,也可能沒有導致性能損失。

  為了更好地闡明這個解決方案並使其易於實現,Microsoft .NET框架2.0在System.Collections.Generics命名空間中定義了類型安全的泛型IEnumerable<ItemType>和IEnumerator<ItemType>:

  

public interface IEnumerable

        {
  
        IEnumerator GetEnumerator();

        }

        public interface IEnumerator : IDisposable

        {
  
        ItemType Current{get;}
  
        bool MoveNext();

        }

  除了利用泛型之外,新的接口與其前身還略有差別。與IEnumerable不同,IEnumerator是從IDisposable派生而來的,並且沒有Reset方法。圖2中的代碼顯示了實現IEnumerable<string>的簡單city集合,而圖3顯示了編譯器展開foreach循環的代碼中如何使用該接口。圖2中的實現使用了名為MyEnumerator的嵌套類,它將一個引用作為構造參數返回給要枚舉的集合。MyEnumerator清楚地知道city集合(本例中的一個數組)的實現細節。此外,MyEnumerator類使用m_Current成員變量維持當前的迭代狀態,此成員變量用作數組的索引。

  

public class CityCollection : IEnumerable<string>

        {

          
        string[] m_Cities = {"New York","Paris","London"};

          
        public IEnumerator<string> GetEnumerator()
  
        {
    
        return new MyEnumerator(this);
  
        }
  
        //Nested class definition

          
        class MyEnumerator : IEnumerator<string>
  
        {
    
        CityCollection m_Collection;
    
        int m_Current;
    
        public MyEnumerator(CityCollection collection)
    
        {
      
        m_Collection = collection;
      
        m_Current = -1;
    
        }
    
        public bool MoveNext()
    
        {
      
        m_Current++;

              
        if(m_Current < m_Collection.m_Cities.Length)
        
        return true;
      
        else
        
        return false;
    
        }
    
        public string Current
    
        {
      
        get
      
        {
        
        if(m_Current == -1)
          
        throw new InvalidOperationException();
        
        return m_Collection.m_Cities[m_Current];
      
        }
    
        }
    
        public void Dispose(){}
  
        }

        }

  • 首頁
  • 上一頁
  • 1
  • 2
  • 3
  • 4
  • 5
  • 下一頁
  • 尾頁
  • 共8頁
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved