Как предотвратить изменения в IReadOnlyList‹T›?

Мне нужно использовать IReadOnlyList<T> в качестве возвращаемого параметра, так как он лучше всего соответствует моим потребностям, но, как вы можете видеть в приведенных ниже примерах, вы все равно можете изменить список, который он обертывает, если он не предназначен только для чтения.

using System.Collections.Generic;
using System.Collections.Immutable;

public class Test
{
    public Test()
    {
        // return an IReadOnlyList that wraps a List, we can modify content
        var list1 = GetList1();
        if (list1 is List<Section> sections1) // can be true
        {
            sections1.Clear();
        }

        // return an IReadOnlyList that wraps an ImmutableArray, we cannot modify content
        var list2 = GetList2();
        if (list2 is List<Section> sections2) // never true
        {
            sections2.Clear();
        }
    }

    public static IReadOnlyList<Section> GetList1()
    {
        return new List<Section> {new Section()};
    }

    public static IReadOnlyList<Section> GetList2()
    {
        return ImmutableArray.Create(new Section());
    }
}

public struct Section
{
}

Проблема:

ImmutableArray<T> выглядит великолепно, так как он действительно доступен только для чтения, единственное, что я не хочу/нужно публично возвращать этому полнофункциональный класс, допускающий изменения, которые создают копию.

Поэтому я придерживаюсь возврата IReadOnlyList<T>, поскольку его цель проста, но мне нужно исправить проблему с возможным модифицируемым списком.

Вопрос:

Является ли возврат ImmutableArray<T> в качестве IReadOnlyList<T> правильным подходом?

Если нет, то не могли бы вы подсказать, как это сделать?


person aybe    schedule 15.02.2019    source источник
comment
Помните, что IReadOnlyList ничего не упаковывает. Это все тот же объект списка. List реализует IReadOnlyList, и вот как вы к нему обращаетесь. Это все равно, что надеть на телефон чехол, который скрывает нижнюю половину экрана — это все тот же телефон. Я бы сказал, что ImmutableArray - правильный подход к этому, если вы хотите сделать больше, чем предотвратить случайное изменение списка людьми.   -  person Llama    schedule 15.02.2019
comment
Ладно, это не тот термин, который нужно использовать!   -  person aybe    schedule 15.02.2019
comment
Извините, я собираюсь отредактировать свой вопрос, потому что я забыл кое-что упомянуть.   -  person aybe    schedule 15.02.2019
comment
Если вы не предоставляете исходный список, вы можете использовать метод AsReadOnly, см. docs.microsoft.com/en-us/dotnet/api/, который создает оболочку, имеющую только методы сбора только для чтения.   -  person ckuri    schedule 15.02.2019
comment
@ckuri Взгляните на раздел примечаний в docs.microsoft.com/en-us/dotnet/api/   -  person aybe    schedule 15.02.2019
comment
@Aybe Вот почему я сказал, если вы не предоставите исходный список. Если вы сделаете new List<Section> { … }.AsReadOnly(), вы получите список только для чтения, который нельзя изменить каким-либо образом, потому что вы больше не можете получить исходный изменяемый список.   -  person ckuri    schedule 15.02.2019
comment
Правильно, это будет эффективно работать, спасибо!   -  person aybe    schedule 16.02.2019


Ответы (1)


IReadOnlyList работает не так

Интерфейс IReadOnlyList

IReadOnlyList<T> представляет собой список, в котором количество и порядок элементов списка доступны только для чтения. Не гарантируется, что содержимое элементов списка будет доступно только для чтения.

Если вы хотите Immutable Collection проверить

System.Collections.Immutable Namespace< /а>

Пространство имен System.Collections.Immutable содержит интерфейсы и классы, определяющие неизменяемые коллекции.

person TheGeneral    schedule 15.02.2019