登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

学无止境

一点积累,与大家分享

 
 
 

日志

 
 

数组,集合,IEnumerable接口,迭代器  

2010-06-03 10:07:06|  分类: C#技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
数组-->集合-->泛型

(1)数组
1. 数组数据结构是System.Array类的一个实例.
2. System.Array类的语法为
[SerializableAttribute]
[ComVisibleAttribute(true)]
public abstract class Array : ICloneable, IList, ICollection, IEnumerable
3. 下面看一个使用数组的例子(我称之为隐式实现)
protected void Page_Load(object sender, EventArgs e)
{
    string[] strArrName = new string[3] { "Jim", "Andy", "Sun" };
    foreach (string strName in strArrName)
    {
        lblName.Text += strName + ",";
    }
}
或者这样写
protected void Page_Load(object sender, EventArgs e)
{
    string[] strArrName = new string[3];
    strArrName[0] = "Jim";
    strArrName[1] = "Andy";
    strArrName[2] = "Sun";
    foreach (string strName in strArrName)
    {
        lblName.Text += strName + ",";
    }
}
显示结果如下
Jim,Andy,Sun,
4. 下面看另一个使用数组的例子(我称之为显式实现)
protected void Page_Load(object sender, EventArgs e)
{
    Array myArray = Array.CreateInstance(typeof(string), 3);
    myArray.SetValue("Jim", 0);
    myArray.SetValue("Andy", 1);
    myArray.SetValue("Sun", 2);
    foreach (string strName in myArray)
    {
        lblName.Text += strName + ",";
    }
}
显示结果如下
Jim,Andy,Sun,
5. 优点:可以高效的访问给定下标的元素;System.Array类有自己的C#语法,使用它编程非常的直观.
6. 缺点:在实例化时必须指定数组的大小,以后也不能添加,插入,删除元素.

(2)集合
1. 针对数组数据结构的缺点,我们使用集合数据结构.
2. 集合数据结构中的类都位于System.Collections命名空间中.
3. 说到集合,我们必须先了解几个接口.想具体了解以下接口,可参考(3)集合接口
3.1 IEnumerable接口和IEnumerator接口
3.2 ICollection接口
public interface ICollection : IEnumerable
3.3 IList接口
public interface IList : ICollection, IEnumerable
3.4 IDictionary接口
public interface IDictionary : ICollection, IEnumerable
4. 说明一下:
4.1 ICollection接口是System.Collections命名空间中类的基接口.
4.2 ICollection接口扩展IEnumerable;IDictionary和IList则是扩展ICollection的更为专用的接口.IDictionary实现是键/值对的集合,如Hashtable类.IList实现是值的集合,其成员可通过索引访问,如ArrayList类.
4.3 某些集合(如Queue类和Stack类)限制对其元素的访问,它们直接实现ICollection接口.
4.4 如果IDictionary接口和IList接口都不能满足所需集合的要求,则从ICollection接口派生新集合类以提高灵活性.

(3)IEnumerable接口和IEnumerator接口
1. 我的理解:只有实现了IEnumerable接口的数据结构类才能使用foreach语句,下面给出例子
//Person类
public class Person
{
    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get { return _firstName; }
    }
    public string LastName
    {
        get { return _lastName; }
    }

    public Person(string strFirstName, string strLastName)
    {
        this._firstName = strFirstName;
        this._lastName = strLastName;
    }
}
//PersonList集合,实现IEnumerable接口
public class PersonList : IEnumerable
{
    private Person[] _arrPerson;

    public PersonList(Person[] myArrPerson)
    {
        _arrPerson = new Person[myArrPerson.Length];
        for (int i = 0; i < myArrPerson.Length; i++)
        {
            _arrPerson[i] = myArrPerson[i];
        }
    }

    public IEnumerator GetEnumerator()
    {
        return new PeopleEnumerator(_arrPerson);
    }
}
//实现IEnumerator接口
public class PeopleEnumerator : IEnumerator
{
    private int _position = -1;
    public Person[] _arrPerson;

    public object Current
    {
        get
        {
            try
            {
                return _arrPerson[_position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }

    public PeopleEnumerator(Person[] myArrPerson)
    {
        _arrPerson = myArrPerson;
    }

    public bool MoveNext()
    {
        _position++;
        return (_position < _arrPerson.Length);
    }

    public void Reset()
    {
        _position = -1;
    }
}
//集合的使用
protected void Page_Load(object sender, EventArgs e)
{
    Person[] myArrPerson = new Person[3]
    {
        new Person("John", "Smith"),
        new Person("Jim", "Johnson"),
        new Person("Sue", "Rabon"),
    };

    PersonList myPersonList = new PersonList(myArrPerson);
    foreach (Person myPerson in myPersonList)
    {
        lblName.Text += myPerson.FirstName + " " + myPerson.LastName + ",";
    }
}
6. 说明一下我的理解,定义了一个集合类,实现IEnumerable接口,则必须定义一个与之相应的实现IEnumerator接口的类,这样是不是很麻烦呢?

(4)迭代器
1. 使用迭代器可避免上述麻烦,修改代码,注意橙色部分
public class Person
{
    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get { return _firstName; }
    }
    public string LastName
    {
        get { return _lastName; }
    }

    public Person(string strFirstName, string strLastName)
    {
        this._firstName = strFirstName;
        this._lastName = strLastName;
    }
}

public class PersonList : IEnumerable
{
    private Person[] _arrPerson;

    public PersonList(Person[] myArrPerson)
    {
        _arrPerson = new Person[myArrPerson.Length];
        for (int i = 0; i < myArrPerson.Length; i++)
        {
            _arrPerson[i] = myArrPerson[i];
        }
    }

    public IEnumerator GetEnumerator()
    {
        //当编译器检测到迭代器时,它将自动生成IEnumerable或IEnumerable<T>接口的Current,MoveNext和Dispose方法.
        for (int i = 0; i < _arrPerson.Length; i++)
        {
            yield return _arrPerson[i];
        }
    }
}

例子
实现IEnumerable接口的类可以进行简单迭代,例如foreach语句


using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace IEnumerable接口
{
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            foreach (int? var in a)//当int值可能被赋空值时用?

            {
                Console.WriteLine(var);
                
            }

        }
    }
    class A : IEnumerable
    {
        int x = 1;
        int y = 2;
        int z = 3;
        public IEnumerator GetEnumerator()
        {
           // int i = -1;
            for (int i = 0; i <=3; i++)
            {


                if (i == x)
                {
                    yield return 1;
                }
                else if (i == y)
                {
                    yield return 2;

                }
                else if (i == z)
                {
                    yield return 3;

                }
                else
                {
                    yield return null;
                }
            }
        }
    }
}



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lixucpf/archive/2009/03/21/4011824.aspx
  评论这张
 
阅读(917)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018