словарь const в c # - PullRequest
       49

словарь const в c #

8 голосов
/ 12 мая 2009

У меня есть класс в C #, который содержит словарь, который я хочу создать и ничего не гарантировать при добавлении, редактировании или удалении из этого словаря, пока существует класс, который его содержит.

readonly на самом деле не помогает, после того, как я проверил и увидел, что могу добавлять элементы после. Например, я создал пример:

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public void Add(int key, int value)
    {
        myDictionary.Add(key, value);
    }

}

Я хочу, чтобы метод Add не работал. Если возможно, я хочу, чтобы он даже не компилировался. Есть предложения?

На самом деле, я волнуюсь, потому что это код, который будет открыт для изменения многими людьми. Таким образом, даже если я скрою метод Add, для кого-то будет возможно «невинно» создать метод, который добавляет ключ, или удаляет другой. Я хочу, чтобы люди смотрели и знали, что они не должны менять словарь в любом случае. Как и у меня с константной переменной.

Ответы [ 9 ]

12 голосов
/ 12 мая 2009

В .NET Framework нет ничего, что могло бы вам здесь помочь, но в этом посте дает довольно хорошую реализацию универсального ReadOnlyDictionary в C #. Он реализует все интерфейсы, которые вы можете ожидать (IDictionary, ICollection, IEnumerable и т. Д.), И в качестве бонуса весь класс и его члены полностью комментируются XML.

(Я воздержался от публикации кода здесь, потому что он действительно довольно длинный со всеми комментариями XML.)

7 голосов
/ 12 мая 2009

Скрыть словарь полностью. Просто предоставьте метод get для класса DictContainer, который извлекает элементы из словаря.

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public this[int key]
    {
        return myDictionary[key];
    }
}
3 голосов
/ 12 мая 2009

Эх ... тогда не определяйте метод добавления ...

Держите переменную myDictionary в секрете и открывайте Getter / Indexer, чтобы ее можно было читать только из этого класса.

задается вопросом, полностью ли он упускает точку

1 голос
/ 12 мая 2009

Нет встроенного способа сделать это, рассмотрите возможность использования класса-оболочки.

0 голосов
/ 12 ноября 2014

К вашему сведению, теперь он встроен в .net 4.5.

http://msdn.microsoft.com/en-us/library/gg712875(v=vs.110).aspx

0 голосов
/ 30 октября 2010

Вот лучшая альтернатива, как я описал в:

http://www.softwarerockstar.com/2010/10/..

По сути, это гораздо более простое решение с подклассом ReadOnlyCollection, которое выполняет работу более элегантным образом.

0 голосов
/ 13 мая 2009

Мне понравилась ссылка из bruno-conde , которая была проще, но как только я не смогу пометить его комментарий как ответ, я отмечу Нолдорин ответь как официальный, потому что это аналогичный и удовлетворительный ответ.

Жаль, что нет способа предотвратить компиляцию кода :(. Спасибо, ребята

0 голосов
/ 12 мая 2009

а это другой способ

class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>
{
    private bool _locked = false;

    public new void Add(Key key, Value value)
    {
        if (!_locked)
        {
            base.Add(key, value);
        }
        else
        {
            throw new ReadOnlyException();
        }
    }
    public void Lock()
    {
        _locked = true;
    }
}
0 голосов
/ 12 мая 2009
interface IReadOnlyDic<Key, Value>
{
    void Add(Key key, Value value);
}
class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>, IReadOnlyDic<Key, Value>
{
    public new void Add(Key key, Value value)
    {
        //throw an exception or do nothing
    }
    #region IReadOnlyDic<Key,Value> Members

    void IReadOnlyDic<Key, Value>.Add(Key key, Value value)
    {
        base.Add(key, value);
    }

    #endregion
}

для добавления пользовательских элементов;

    IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
    if (dict != null)
        dict.Add(1, 155);
...