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
: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); } }