как сделать аксессор для словаря таким образом, чтобы возвращаемый словарь не мог быть изменен C # / 2.0 - PullRequest
0 голосов
/ 07 апреля 2010

Я подумал о решении ниже, потому что коллекция очень, очень мала. Но что, если он был большим?

private Dictionary<string, OfTable> _folderData = new Dictionary<string, OfTable>();

public Dictionary<string, OfTable> FolderData
{
    get { return new Dictionary<string,OfTable>(_folderData); }
}

С помощью списка вы можете сделать:

public class MyClass
{
    private List<int> _items = new List<int>();

    public IList<int> Items
    {
        get { return _items.AsReadOnly(); }
    }
}

Это было бы неплохо!

Заранее спасибо, Cheers & BR - Matti

ТЕПЕРЬ, КОГДА Я ДУМАЮ, ЧТО ОБЪЕКТЫ В СБОРНИКЕ НАХОДЯТСЯ В КАРТЕ. ТАК МОЕ РЕШЕНИЕ НЕ ПРЕДОТВРАЩАЕТ ПОЗВОЛИТЕЛЬ, ЧТОБЫ ИЗМЕНИТЬ ИХ !!! ПРИЧИНА ОБОИХ СЛОВА В СЛОВАРЕ. ЭТО ОТНОСИТСЯ К ПРИМЕРУ ПЕРЕДАЧИ?

class OfTable
{
    private int _table;
    private List<int> _classes;
    private string _label;

    public OfTable()
    {
        _classes = new List<int>();
    }

    public int Table
    {
        get { return _table; }
        set { _table = value; }
    }

    public List<int> Classes
    {
        get { return _classes; }
        set { _classes = value; }
    }

    public string Label
    {
        get { return _label; }
        set { _label = value; }
    }
}

так как сделать это неизменным ??

Ответы [ 2 ]

4 голосов
/ 07 апреля 2010

Нетрудно накатить свой класс ReadOnlyDictionary<K,V>.Примерно так:

public sealed class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private readonly IDictionary<TKey, TValue> _dictionary;

    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        _dictionary = dictionary;
    }

    public bool ContainsKey(TKey key)
    {
        return _dictionary.ContainsKey(key);
    }

    public int Count
    {
        get { return _dictionary.Count; }
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return _dictionary.GetEnumerator();
    }

    public ICollection<TKey> Keys
    {
        get { return _dictionary.Keys; }
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return _dictionary.TryGetValue(key, out value);
    }

    public ICollection<TValue> Values
    {
        get { return _dictionary.Values; }
    }

    public TValue this[TKey key]    // Item
    {
        get { return _dictionary[key]; }
    }

    #region IDictionary<TKey, TValue> Explicit Interface Implementation

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw new NotSupportedException("Dictionary is read-only.");
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw new NotSupportedException("Dictionary is read-only.");
    }

    TValue IDictionary<TKey, TValue>.this[TKey key]    // Item
    {
        get { return _dictionary[key]; }
        set { throw new NotSupportedException("Dictionary is read-only."); }
    }

    #endregion

    #region ICollection<T> Explicit Interface Implementation

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
    {
        return _dictionary.Contains(item);
    }

    void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        _dictionary.CopyTo(array, arrayIndex);
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
    {
        get { return true; }
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    #endregion

    #region IEnumerable Explicit Interface Implementation

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable)_dictionary).GetEnumerator();
    }

    #endregion
}

Если вы используете C # 3 или более позднюю версию, вы можете также запустить соответствующий метод расширения AsReadOnly:

public static class ReadOnlyDictionaryHelper
{
    public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
    {
        var temp = dictionary as ReadOnlyDictionary<TKey, TValue>;
        return temp ?? new ReadOnlyDictionary<TKey, TValue>(dictionary);
    }
}

и затем вернутьОболочка только для чтения из вашей собственности:

// in C#2
return new ReadOnlyDictionary<string, OfTable>(_folderData);

// in C#3 or later
return _folderData.AsReadOnly();
1 голос
/ 07 апреля 2010

Использование ReadOnlyCollection<T> класса.

Экземпляр универсального класса ReadOnlyCollection всегда доступен только для чтения.Коллекция, доступная только для чтения, - это просто коллекция с оболочкой, которая предотвращает изменение коллекции;поэтому, если изменения сделаны в основной коллекции, коллекция только для чтения отражает эти изменения.См. Коллекцию для модифицируемой версии этого класса.

- EDIT -

Оформить тривиальную оболочку словаря здесьИ Общий словарь только для чтения Ричарда Карра.

...