自定义集合类型
时间:2011-04-04 来源:桂素伟
很多时候我们去自定义一些类型,更有些时候我们会把这些自定义类型封装成集合,比如说现在有一个自定义类型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代表一个集合,那应该能对它进行遍历,为了实现对Users的foreach遍历,必须实现IEnumerable接口的实现,代码如下:
class Users : IListSource, IEnumerable
{
……
/// <summary>
/// 实现对users的foreach遍历
/// </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;
}
……
}
下面是整体类图: