博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IEnumerable和IEnumerable<T>接口
阅读量:6910 次
发布时间:2019-06-27

本文共 5424 字,大约阅读时间需要 18 分钟。

IEnumerableIEnumerable<T>接口

IEnumerableIEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,IEnumerableIEnumerable<T>接口是.NET Framework中最基本的集合访问器,这两个接口对于LINQ的理解是非常重要的。

在面向对象的开发过程中,常常需要创建若干对象,并进行对象的操作和查询,在创建对象前,首先需要声明一个类为对象提供描述,示例代码如下所示。

using System;

using System.Collections.Generic;

using System.Linq;                                                                                                //使用LINQ命名控件

using System.Text;

namespace IEnumeratorSample

{

    class Person                                                                                                   //定义一个Person

    {

        public string Name;                                                                               //定义Person的名字

        public string Age;                                                                                   //定义Person的年龄

        public Person(string name, string age)                                                       //Person初始化(构造函数)

        {

            Name = name;                                                                               //配置Name

            Age = age;                                                                                       //配置Age

        }

    }

上述代码定义了一个Person类并抽象一个Person类的属性,这些属性包括NameAgeNameAge属性分别用于描述Person的名字和年龄,用于数据初始化。初始化之后的数据就需要创建一系列Person对象,通过这些对象的相应属性能够进行对象的访问和遍历,示例代码如下所示。

    class Program

    {

        static void Main(string[] args)

        {

            Person[] per = new Person[2]                                                      //创建并初始化2Person对象

            {

                new Person("guojing","21"),                                                 //通过构造函数构造对象

                new Person("muqing","21"),                                                //通过构造函数构造对象

            };

            foreach (Person p in per)                                                             //遍历对象

                Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);

            Console.ReadKey();

        }

    }

}

上述代码创建并初始化了2Person对象,并通过foreach语法进行对象的遍历。但是上述代码是在数组中进行查询的,就是说如果要创建多个对象,则必须创建一个对象的数组,如上述代码中的Per变量,而如果需要直接对对象的集合进行查询,却不能够实现查询功能。例如增加一个构造函数,该构造函数用户构造一组Person对象,示例代码如下所示。

        private Person[] per;

        public Person(Person[] array)                                                    //重载构造函数,迭代对象

        {

            per = new Person[array.Length];                                       //创建对象

            for (int i = 0; i < array.Length; i++)                                               //遍历初始化对象

            {

                per[i] = array[i];                                                               //数组赋值

            }

        }

上述构造函数动态的构造了一组People类的对象,那么应该也能够使用foreach语句进行遍历,示例代码如下所示。

            Person personlist = new Person(per);                              //创建对象

            foreach (Person p in personlist)                                        //遍历对象

            {

                Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);

            }

在上述代码的foreach语句中,直接在Person类的集合中进行查询,系统则会报错“ConsoleApplication1.Person”不包含“GetEnumerator”的公共定义,因此foreach语句不能作用于“ConsoleApplication1.Person”类型的变量,因为Person类并不支持foreach语句进行遍历。为了让相应的类能够支持foreach语句执行遍历操作,则需要实现派生自类IEnumerable并实现IEnumerable接口,示例代码如下所示。

public IEnumerator GetEnumerator()                                                                //实现接口

    {

        return new GetEnum(_people);

    }

为了让自定义类型能够支持foreach语句,则必须对Person类的构造函数进行编写并实现接口,示例代码如下所示。

    class Person:IEnumerable                                                                 //派生自IEnumerable,同样定义一个Personl

    {

        public string Name;                                                             //创建字段

        public string Age;                                                                 //创建字段

        public Person(string name, string age)                                    //字段初始化

        {

            Name = name;                                                             //配置Name

            Age = age;                                                                    //配置Age

        }

        public IEnumerator GetEnumerator()                              //实现接口

        {

            return new PersonEnum(per);                                  //返回方法

        }

}

上述代码重构了Person类并实现了接口,接口实现的具体方法如下所示。

    class PersonEnum : IEnumerator                                            //实现foreach语句内部,并派生

    {

    public Person[] _per;                                                                   //实现数组

    int position = -1;                                                                           //设置“指针”

    public PersonEnum(Person[] list)

    {

        _per = list;                                                                             //实现list

    }

    public bool MoveNext()                                                              //实现向前移动

    {

        position++;                                                                            //位置增加

        return (position < _per.Length);                                        //返回布尔值

    }

    public void Reset()                                                                      //位置重置

    {

        position = -1;                                                                         //重置指针为-1

    public object Current                                                                  //实现接口方法

    {

        get

        {

            try

            {

                return _per[position];                                           //返回对象

            }

            catch (IndexOutOfRangeException)                        //捕获异常

            {

                throw new InvalidOperationException();                  //抛出异常信息

            }

        }

    }

    }

上述代码实现了foreach语句的功能,当开发Person类初始化后就可以直接使用Personal类对象的集合进行LINQ查询,示例代码如下所示。

        static void Main(string[] args)

        {

            Person[] per = new Person[2]                                    //同样初始化并定义2Person对象

            {

                new Person("guojing","21"),                              //构造创建新的对象

                new Person("muqing","21"),                              //构造创建新的对象

            };

            Person personlist = new Person(per);                     //初始化对象集合

            foreach (Person p in personlist)                               //使用foreach语句

                Console.WriteLine("Name is " + p.Name + " and Age is " + p.Age);

            Console.ReadKey();

        }

从上述代码中可以看出,初始化Person对象时初始化的是一个对象的集合,在该对象的集合中可以通过LINQ直接进行对象的操作,这样做即封装了Person对象也能够让编码更加易读。在.NET Framework 3.5中,LINQ支持数组的查询,开发人员不必自己手动创建IEnumerableIEnumerable<T>接口以支持某个类型的foreach编程方法,但是IEnumerableIEnumerable<T>LINQ中非常重要的接口,在LINQ中也大量的使用IEnumerableIEnumerable<T>进行封装,示例代码如下所示。

public static IEnumerable<TSource> Where<TSource>

(this IEnumerable<TSource> source,Func<TSource, Boolean> predicate)                 //内部实现

        {

            foreach (TSource element in source)                                                 //内部遍历传递的集合

            {

                if (predicate(element))

                    yield return element;                                                               //返回集合信息

            }

        }

上述代码为LINQ内部的封装,从代码中可以看到,在LINQ内部也大量的使用了IEnumerableIEnumerable<T>接口实现LINQ查询。IEnumerable原本就是.NET Framework中最基本的集合访问器,而LINQ是面向关系(有序N元组集合)的,自然也就是面向IEnumerable<T>的,所以了解IEnumerableIEnumerable<T>LINQ的理解是有一定帮助的

实例:

using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Collections;
namespace
IEnumeratorSample
{
 
    
class
Person : IEnumerable
    
{
        
public
string
Name;
//定义Person的名字
        
public
string
Age;
//定义Person的年龄
        
public
Person(
string
name,
string
age)
//为Person初始化(构造函数)
        
{
            
Name = name;
//配置Name值
            
Age = age;
 
        
}
        
private
Person[] per;
        
public
Person(Person[] array)
//重载构造函数,迭代对象
        
{
            
per =
new
Person[array.Length];
//创建对象
            
for
(
int
i = 0; i < array.Length; i++)
//遍历初始化对象
            
{
                
per[i] = array[i];
//数组赋值
            
}
        
}
        
public
IEnumerator GetEnumerator()
//实现接口
        
{
            
return
new
PersonEnum(per);
        
}
    
}
    
class
PersonEnum : IEnumerator
//实现foreach语句内部,并派生
    
{
        
public
Person[] _per;
//实现数组
        
int
position = -1;
//设置“指针”
        
public
PersonEnum(Person[] list)
        
{
            
_per = list;
//实现list
        
}
        
public
bool
MoveNext()
//实现向前移动
        
{
            
position++;
//位置增加
            
return
(position < _per.Length);
//返回布尔值
        
}
 
        
public
void
Reset()
//位置重置
        
{
 
            
position = -1;
//重置指针为-1
        
}
        
public
object
Current
//实现接口方法
        
{
            
get
            
{
                
try
                
{
                    
return
_per[position];
//返回对象
                
}
                
catch
(IndexOutOfRangeException)
//捕获异常
                
{
                    
throw
new
InvalidOperationException();
//抛出异常信息
                
}
            
}
        
}
    
}
 
 
    
class
Program
    
{
 
        
static
void
Main(
string
[] args)
        
{
            
Person[] per =
new
Person[2]
            
{
                
new
Person(
"guojing"
,
"21"
),
                
new
Person(
"muqing"
,
"21"
),
            
};
            
Person personlist =
new
Person(per);
            
foreach
(Person p
in
personlist)
//遍历对象
            
{
 
                
Console.WriteLine(
"Name is "
+ p.Name +
" and Age is "
+ p.Age);
 
            
}
            
Console.ReadKey();
        
}
    
}
}

转载于:https://www.cnblogs.com/ry123/archive/2011/12/12/2285082.html

你可能感兴趣的文章
Oracle 11g数据库随系统自动启动与关闭的设置方法
查看>>
redhat 桥接配置
查看>>
比肩微信小程序的快应用联盟
查看>>
天猫与九大快递合作 价格热战之后的冷静竞争
查看>>
git pull force
查看>>
scons用户手册
查看>>
使用new操作符来调用一个构造函数的时候发生了什么
查看>>
element-ui之el-scrollbar源码解析学习
查看>>
ceph 的pg诊断
查看>>
交换机配置vlan 访问控制列表
查看>>
我的友情链接
查看>>
12个时间管理妙招
查看>>
2014阿里巴巴校园招聘研发工程师笔试题(北邮站)
查看>>
ViewPager的onPageChangeListener里面的一些方法参数:
查看>>
solr搜索引擎使用
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Python面向对象之类的成员
查看>>
[一文一命令]more命令详解
查看>>
mapreduce运行机制
查看>>