Приведите SynchronizedCollection <T>только для чтения SynchronizedReadOnlyCollection <T> - PullRequest
1 голос
/ 18 апреля 2019

Я использовал List<T>, использовал AsReadOnly() метод и сохранил результат в ReadOnlyCollection<T>. Теперь я работаю с потоками и мне нужно сделать то же самое, но с SynchronizedCollection<T> вместо List<T> и SynchronizedReadOnlyCollection<T> вместо ReadOnlyCollection<T>

Как это сделать?

Ответы [ 2 ]

1 голос
/ 18 апреля 2019

Поскольку SynchronizedCollection<T> : IEnumerable<T> вы можете инициализировать новый экземпляр SynchronizedReadOnlyCollection<T> на основе вашего существующего SynchronizedCollection<T> с помощью конструктора

var readOnlyCollection = new SynchronizedReadOnlyCollection(synchronizedCollection.SyncRoot,
                                                            syncronizedCollection);

Я также думаю о другом подходе,Разница в том, что при первом подходе у вас действительно есть снимок SynchronizedCollection<T>, но с этим у вас есть только оболочка только для чтения (если вы добавите что-то в исходную коллекцию, она обновит также коллекцию только для чтения)

public static class SynchronizedCollectionExtension
{
    public static IReadOnlyCollection<T> AsReadOnly<T>(this SynchronizedCollection<T> value)
    {
        lock (value.SyncRoot)
        {
            // this call is not expensive as it is just a thin wrapper around the IList<T>
            return new ReadOnlyCollection<T>(value);
        }
    }
}

IReadOnlyCollection<int> readOnlyCollection = collection.AsReadOnly();
1 голос
/ 18 апреля 2019

Если у вас есть данные перечислимого типа, просто передайте их в синхронизированные конструкторы классов:

List<T> data = new List<T>();

var syncRoot = new object();
var syncCollection = new SynchronizedCollection<T>(syncRoot, data);

var synchronizedReadOnlyCollection = new SynchronizedReadOnlyCollection<T>(syncRoot, data);
...