天天看點

IEnumerable接口

IEnumerable接口,其中隻有一個傳回IEnumerator類型的方法

public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }      
public interface IEnumerator
    {//擷取集合中的目前元素。
        object Current { get; }//将枚舉數推進到集合的下一個元素。
        bool MoveNext();//将枚舉數設定為其初始位置,該位置位于集合中第一個元素之前。
        void Reset();
    }      

一種類型的資料,如果想要通過foreach來進行疊代,那麼就必須實作IEnumerable接口。例如:ArrayList、Hashtable等都實作了它,才得以使用foreach來進行周遊。

  關系

      IEnumerable

             :ICollection

                   :IDictionary    (實作是鍵/值對的集合:Hashtable,Dictionary)

                   :IList             (實作是值的集合,其成員可通過索引通路:ArrayList,Array)

                   :某些集合(如 Queue 類和 Stack 類)限制對其元素的通路,它們直接實作 ICollection 接口。

                                      ----以上都在System.Collections命名空間中

              泛型

            :IEnumerable<T>

                    :ICollection<T>  

                            :IDictionary<TKey, TValue> 實作是鍵/值對的集合,如 Dictionary<TKey, TValue> 類

                            :IList<T>   IList<T> 實作是值的集合,并且可以按索引通路它的成員,如 List<T> 類 

                                     ----以上泛型在System.Collections.Generic命名空間中

用執行個體說話:

  定義一個類

class User
    {
        public User(string fName, string lName)
        {
            this.firstName = fName;
            this.lastName = lName;
        }
        public string firstName;
        public string lastName;
    }      

  運作一、

static void Main(string[] args)
        {
            User[] user = new User[] {
                new User("John", "Smith"),
                new User("Jim", "Johnson"),
                new User("Sue", "Rabon"),
            };
            foreach (User u in user)
            {
                Console.WriteLine(u.firstName);
            }

            Console.ReadKey();
        }
//此處之是以可以用foreach循環,是因為定義的類型其實是一個數組類型,因為數組類型已經實作了IEnumerable接口,并對其進行了實作.
MSDN中的例子,其實就是對數組重寫了http://msdn.microsoft.com/zh-cn/library/vstudio/system.collections.ienumerable.aspx
      

  運作二、

static void Main(string[] args)
        {
            User use = new User("dddd","ffff");
            foreach (string s in use)
            {
                Console.WriteLine(s);
            }
            Console.ReadKey();
        }
//這裡會提示錯誤:User不包含GetEnumerator的公共定義,是以foreach語句不能作用與User類型的變量      

補充一、由模型綁定中,綁定泛型類型時學習到泛型相關的知識!

//調用1
    ExtraGenericInterface(typeof(List<User>),typeof(IEnumerable<>))
    //調用2
    ExtraGenericInterface(typeof(IEnumerable<User>),typeof(IEnumerable<>))

    public Type ExtraGenericInterface(Type queryType, Type interfaceType)
        {
            //目前類型queryType是否是泛型
            bool b = queryType.IsGenericType;
            //傳回可以構造目前泛型類型的一個泛型類型,即:由IEnumerable<User>得到 IEnumerable<>
            Type tt = queryType.GetGenericTypeDefinition();

            bool ttt = tt == interfaceType ? true : false;

            Func<Type, bool> predicate = t => t.IsGenericType && (t.GetGenericTypeDefinition() == interfaceType);
            //Func<Type, bool> predicate = delegate(Type queryType2){return false;};
            //如果目前類型是泛型,并且該發行是由interfaceType類型構造的。
            if (predicate(queryType))
            {
                return queryType;
            }
            else
            {
                //擷取目前類實作的所有類和接口
                Type[] types = queryType.GetInterfaces();
                //在數組中找,并傳回滿足 predicate 條件的第一個元素
                //也就是在所有父類或實作的接口中找到是泛型并且構造此泛型的類型是interfaceType類型的第一個元素
         //FirstOrDefault<Type>中Type是後面委托predicate的參數類型 
                Type tttt = types.FirstOrDefault<Type>(predicate);

                return queryType.GetInterfaces().FirstOrDefault<Type>(predicate);
            }
            
        }      
IEnumerable接口

作者:武沛齊

出處:http://www.cnblogs.com/wupeiqi/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接。