我想在集合上创建自定义索引器。这是我的课程:
商务舱:
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。我该如何解决这个问题?
答案 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()(您可以在其中指定密钥)。