在集合上实现自定义索引器

时间:2012-03-30 18:42:54

标签: c# c#-4.0

我想在集合上创建自定义索引器。这是我的课程:

商务舱:

public class UserCollection : Collection<User>
{
    public new User this[int index]
    {
        get
        {
            return this.FirstOrDefault(x => x.UserID == index);
        }
    }

}

BL API方法:

public static Collection<User> GetUser()
{
    return new UserCollection
               {
                   new User {UserID = 2},
                   new User {UserID = 4}
               };
}

用法:

  Collection<User> users = GetUser();
    User user = users[2];

    }

用户类有很少的列,如UserID,UserName等。我想通过索引从集合中获取用户,这里索引将是用户ID。但是上面的使用代码没有这样做,它正在考虑父级Collection类的索引器。我希望我的自定义索引器能够发挥作用。我可以通过将UserCollection作为GetUser方法的返回类型公开来实现它,然后解决方案就是使用像这样的代码

UserCollection users = GetUser();

但是我想从BL方法返回最常用的类型,这是Collection。我该如何解决这个问题?

5 个答案:

答案 0 :(得分:4)

阅读Collection<T>的文档,仔细密切关注“对继承人的说明”部分。它将链接到另一个页面,该页面为您提供了执行您要执行的操作的示例。

您可能还想查看KeyedCollection<TKey, TItem>课程,这可能会让您感觉更轻松。您的自定义类将变为:

public class UserCollection: KeyedCollection<int, User>
{

    public UserCollection() : base() {}

    protected override int GetKeyForItem(User user)
    {
        return user.UserID;
    }
}

答案 1 :(得分:2)

为什么您希望UserCollection扩展Collection<User>?您的UserCollection显然不是Collection<User>,因为它的索引(集合的基本内容之一)是不同的!

我建议您将Collection<User>作为UserCollection的字段并在索引器中访问它。

答案 2 :(得分:0)

您的索引器不是虚拟方法;当您为子类定义索引器时,您正在隐藏父实现,而不是覆盖它,因此每当项目被转换为它的父类型时,它将使用索引器的父定义(如果有的话)。如果对象被强制转换为子类型,它将使用子对象的索引器(在本例中为自定义索引器)。

如果Collection是您的自定义集合,则可以将其定义为虚拟,并在子类中使用override而不是new,然后它将按预期工作。如果没有,你就是SOL。

答案 3 :(得分:0)

您可以使用字典吗?

Dictionary<UserID,Users>

然后你可以按ID查找键/值。

答案 4 :(得分:0)

您可以返回ICollection而不是Collection。这会使您的索引器变为虚拟。

public class UserCollection : ICollection<User>
{
    public User this[int index]
    {
        get
        {
            return this.FirstOrDefault(x => x.UserID == index);
        }
    }

    // all the other ICollection methods

}

public static ICollection<User> GetUser()
{
    return new UserCollection
               {
                   new User {UserID = 2},
                   new User {UserID = 4}
               };
}

但我同意弗拉德,这不是一个真正的收藏品。我觉得它更像是一本字典。考虑IDictionary。甚至来自可枚举扩展的ToDictionary()(您可以在其中指定密钥)。