Fork me on GitHub

自定义集合类型

很多时候我们去自定义一些类型,更有些时候我们会把这些自定义类型封装成集合,比如说现在有一个自定义类型User

/// <summary>

    /// 用户

    /// </summary>

    class User

    {

        /// <summary>

        /// 用户ID

        /// </summary>

        public int ID

        {

            get;

            set;

        }

        /// <summary>

        /// 用户名

        /// </summary>

        public string UserName

        {

            get;

            set;

        }

        /// <summary>

        /// 用户这密码

        /// </summary>

        public string PassWord

        {

            get;

            set;

        }

    }

一般情况下,我们封装集合时,是用泛型的List<>去封装,比如

List<User> users = new List<User>();

如果从技术角度考虑,这样的封装没有什么问题,如果是从业务和面向对象的角度考虑,现在的users不是纯粹一组用户,确切的理解是把用户放到了一个List的集合中,List的很多方法,对于这组用户来说是没有业务含意的,如果我们想得到纯粹的一组用户,那就得定义一个用户组类了。定义如下:

    /// <summary>

    /// 用户组

    /// </summary>

class Users

{

         /// <summary>

        /// 用户集合

        /// </summary>

        List<User> users = new List<User>();

}

 在内部,还是用List<User>来存放多个用户,但这个集合是私有的,被Users类型封装了起来。现在的Users就代表一个用户的集合了,当然,还要实现这个集合的添加用户,删除用户,包括获取用户的总数,代码如下:

/// <summary>

        /// 添加用户

        /// </summary>

        /// <param name="user">用户</param>

        public void AddUser(User user)

        {

            users.Add(user);

        }

        /// <summary>

        /// 移除用户

        /// </summary>

        /// <param name="user">用户</param>

        public void RemoveUser(User user)

        {

            users.Remove(user);

        }

        /// <summary>

        /// 获得用户数量

        /// </summary>

        public int Count

        {

            get

            {

                return users.Count;

            }

        }

不但有添加,删除用户,还要对用户组中的用户进行修改和查询,当然我们去构建方法是没有问题的,

       /// <summary>

        /// 修改用户

        /// </summary>

        /// <param name="user">用户</param>

        public void ModifyUser(User user)

        {

            for (int i = 0; i < users.Count;i++ )

            {

                if (users[i].ID == user.ID)

                {

                    users[i] = user;

                }

            }       

        }

        /// <summary>

        /// 查询用户

        /// </summary>

        /// <param name="ID">用户ID</param>

        /// <returns></returns>

        public User QueryUser(int ID)

        {

            foreach (User user in users)

            {

                if (user.ID == ID)

                {

                    return user;

                }

            }

            return null;

        }

这样可能实现修改和查询,但有修改和查询我们可以根据List<User>集合的特点(主要是引用类型的特点)来达到修改和查询,不防用索引器来试一下:

        /// <summary>

        /// 用户

        /// </summary>

        /// <param name="i">用户ID</param>

        /// <returns></returns>

        public User this[int ID]

        {

            get

            {

                foreach (User user in users)

                {

                    if (user.ID == ID)

                    {

                        return user;

                    }

                }

                return null;

            }

            set

            {

                for (int i = 0; i < users.Count; i++)

                {

                    if (users[i].ID == value.ID)

                    {

                        users[i] = value;

                    }

                }

            }

        }

用索引器的好处是把用户组对象当集合来使用,用户ID当索引值:

            Users users = new Users();

            User user = users[1];

            users[0].UserName = "张三";

既然Users代表一个集合,那应该能对它进行遍历,为了实现对Usersforeach遍历,必须实现IEnumerable接口的实现,代码如下:

class Users : IListSource, IEnumerable

{

……

/// <summary>

        /// 实现对usersforeach遍历

        /// </summary>

        /// <returns></returns>

        public IEnumerator GetEnumerator()

        {

            for (int i = 0; i < users.Count; i++)

            {

                yield return users[i];

            }

        }

……

}

WinForm中或在ASP.NET中,框架中提供了一些数据库的绑定控制,如果使我们的用户组具有绑定能力,就更加完美了。

通常状况下,为了绑定到控件的DataSource的属性下,要实现以下接口,

IList 接口,包括一维数组。

IListSource 接口

IBindingList 接口

IBindingListView 接口

我们来实现IListSource接口,这个接口需要实现两个成员,一个是ContainsListCollection属性,一个是GetList方法

  class Users : IListSource, IEnumerable

{

……

       /// <summary>

        /// 是否包含List

        /// </summary>

        public bool ContainsListCollection

        {

            get { return true; }

        }

        /// <summary>

        /// 返回集合

        /// </summary>

        /// <returns></returns>

        public System.Collections.IList GetList()

        {

            return users;

        }

……

}

下面是整体类图:

posted @ 2011-04-04 10:14  桂素伟  阅读(2139)  评论(6编辑  收藏  举报