Реализация пользовательского индексатора в коллекции - PullRequest
4 голосов
/ 30 марта 2012

Я хочу сделать пользовательский индексатор для коллекции.Вот мои классы:

Бизнес-класс:

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 и т. д. Я хочу получить пользователя из коллекции через индекс, и здесь index будет идентификатором пользователя.Но приведенный выше код использования не делает этого, и он рассматривает индексатор родительского класса Collection.Я хочу, чтобы мой пользовательский индексатор вступил в игру.Я могу сделать это, выставив UserCollection в качестве возвращаемого типа метода GetUser, и тогда решение будет состоять в том, чтобы использовать код, подобный этому

UserCollection users = GetUser();

Но я думаю вернуть здесь наиболее общий тип из метода BL, которыйэто коллекция.Как я могу решить эту проблему?

Ответы [ 5 ]

5 голосов
/ 30 марта 2012

Прочтите документацию по Collection<T>, внимательно следя за разделом «Примечания для наследников». Он будет ссылаться на другую страницу, которая даст вам пример того, что вы пытаетесь сделать.

Возможно, вы также захотите проверить класс KeyedCollection<TKey, TItem>, который может немного облегчить вам задачу. Ваш пользовательский класс просто станет:

public class UserCollection: KeyedCollection<int, User>
{

    public UserCollection() : base() {}

    protected override int GetKeyForItem(User user)
    {
        return user.UserID;
    }
}
2 голосов
/ 30 марта 2012

Почему вы хотите UserCollection продлить Collection<User>? Ваш UserCollection явно не является Collection<User>, поскольку его индексация (одна из базовых вещей для коллекции) отличается!

Я бы предложил просто включить Collection<User> в качестве поля UserCollection и получить к нему доступ в индексаторе.

0 голосов
/ 30 марта 2012

Вы можете вернуть ICollection, а не коллекцию.Это сделало бы ваш индексатор виртуальным.

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 () из Enumerable расширений (где вы можете указать свой ключ).

0 голосов
/ 30 марта 2012

Можете ли вы использовать словарь вместо этого?

Dictionary<UserID,Users>

Тогда вы можете просто посмотреть ключ / значения по ID.

0 голосов
/ 30 марта 2012

Ваши индексаторы не являются виртуальными методами;когда вы определяете свой индексатор для подкласса, вы скрываете родительскую реализацию, не переопределяя ее, поэтому всякий раз, когда элемент приводится в качестве родительского типа, он будет использовать родительское определение индексатора (если оно есть).Если объект приведен как дочерний тип, он будет использовать индексатор дочернего (в данном случае ваш пользовательский).

Если Collection - ваша собственная коллекция, вы можете определить ее как виртуальную,и используйте override вместо new в дочернем классе, и тогда он будет работать как положено.Если нет, то вы SOL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...