Оболочка только для чтения из LinkedList. Как? - PullRequest
4 голосов
/ 19 ноября 2009

.NET v2

Когда в List есть очень полезный (4 мне) метод AsReadOnly () LinkedList не имеет такого метода.

Существует ли способ "быстрого" интерфейса внутреннего LinkedList только для чтения из внешнего кода?

Ответы [ 4 ]

9 голосов
/ 19 ноября 2009

Почему бы просто не вернуть IEnumerable<T>? Если вы просто хотите позволить пользователям перечислять список без его изменения *, IEnumerable является очевидным выбором.

Если вы хотите иметь доступный только для чтения интерфейс интерфейса LinkedList, вы можете обернуть LinkedList, перенаправить методы только для чтения в свернутый список и отрицать любые изменения.

*) Имейте в виду, что ни ReadOnlyCollection, ни IEnumerable не позволят вызывающим сторонам изменять состояние объектов в случае набора ссылочных типов. Если объекты должны быть только для чтения, вам нужно реализовать это как часть их типа.

4 голосов
/ 19 ноября 2009

ReadOnlyCollection<T> принимает IList<T> в качестве аргумента для конструктора. LinkedList<T> не реализует этот интерфейс. List<T> имеет перегрузку конструктора, которая принимает IEnumerable<T> в качестве аргумента, а LinkedList<T> реализует этот интерфейс. Поэтому должно работать следующее:

LinkedList<int> linked = new LinkedList<int>();
// populate the list

ReadOnlyCollection<int> readOnly = new ReadOnlyCollection<int>(
    new List<int>(linked));

Он использует экземпляр List<T> для переноса элементов в конструктор ReadOnlyCollection<T>.

0 голосов
/ 13 августа 2018

# 1 Исправить связанный список

class FixedLinkedList<T> : LinkedList<T>, IList<T>
{
    public T this[int index]
    {
        get
        {
            return GetAt(index).Value;
        }
        set
        {
            GetAt(index).Value = value;
        }
    }

    public int IndexOf(T item)
    {
        int i = 0;
        var node = First;
        while (node!= null && !node.Value.Equals(item))
        {
            i++;
            node = node.Next;
        }

        if (node == null)
        {
            return -1;
        }

        return i;
    }

    public void Insert(int index, T item)
    {
        AddBefore(GetAt(index), new LinkedListNode<T>(item));
    }


    public void RemoveAt(int index)
    {
        Remove(GetAt(index));
    }

    private LinkedListNode<T> GetAt(int index)
    {
        CheckIndex(index);
        int i = 0;
        var node = First;
        while (i < index)
        {
            i++;
            node = node.Next;
        }

        return node;
    }

    private void CheckIndex(int index)
    {
        if (index < 0)
        {
            throw new ArgumentOutOfRangeException(
                nameof(index),
                "Parameter must be greater or equal to 0.");
        }

        if (index >= Count)
        {
            throw new ArgumentOutOfRangeException(
                nameof(index),
                "Parameter must be lower than the list item Count.");
        }
    }
}

# 2 Переносит свои экземпляры в коллекцию ReadOnlyCollection

0 голосов
/ 19 ноября 2009

LinkedList<T> не реализует IList Короче говоря, нет способа быстро это сделать. Если вы приведете свой LinkedList к списку, вы, вероятно, потеряете требуемую функциональность.

LinkedList<T> не предлагает вам ничего для подклассов, поэтому вам нужно написать свой собственный. Я полагаю, что следующий запрос: «Можете ли вы показать мне, как это сделать»

...