Существует ли универсальный словарь только для чтения, доступный в.NET?

Чтобы изменить окно запуска, откройте App.xaml и замените "MainWindow.xaml" своим окном:

StartupUri="GetNameWindow.xaml">

Для того, что вы пытались сделать, вам необходимо удалить StartupUri="MainWindow.xaml" и вместо этого использовать Startup="App_Startup" и затем он будет вызывать ваш обработчик событий при запуске.

185
задан Rob Sobers 24 March 2009 в 07:21
поделиться

8 ответов

Вот простая реализация, которая обертывает словарь:

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

    public ReadOnlyDictionary()
    {
        _dictionary = new Dictionary<TKey, TValue>();
    }

    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
    {
        _dictionary = dictionary;
    }

    #region IDictionary<TKey,TValue> Members

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw ReadOnlyException();
    }

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

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

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw ReadOnlyException();
    }

    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]
    {
        get
        {
            return _dictionary[key];
        }
    }

    TValue IDictionary<TKey, TValue>.this[TKey key]
    {
        get
        {
            return this[key];
        }
        set
        {
            throw ReadOnlyException();
        }
    }

    #endregion

    #region ICollection<KeyValuePair<TKey,TValue>> Members

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw ReadOnlyException();
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw ReadOnlyException();
    }

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

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

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

    public bool IsReadOnly
    {
        get { return true; }
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw ReadOnlyException();
    }

    #endregion

    #region IEnumerable<KeyValuePair<TKey,TValue>> Members

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

    #endregion

    #region IEnumerable Members

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

    #endregion

    private static Exception ReadOnlyException()
    {
        return new NotSupportedException("This dictionary is read-only");
    }
}
156
ответ дан 23 November 2019 в 05:52
поделиться
public IEnumerable<KeyValuePair<string, string>> MyDictionary()
{
    foreach(KeyValuePair<string, string> item in _mydictionary)
        yield return item;
}
0
ответ дан Liam 23 November 2019 в 05:52
поделиться

Я не думаю, что существует простой способ сделать его..., если Ваш словарь является частью пользовательского класса, Вы могли бы достигнуть его с индексатором:

public class MyClass
{
  private Dictionary<string, string> _myDictionary;

  public string this[string index]
  {
    get { return _myDictionary[index]; }
  }
}
1
ответ дан Jonas 23 November 2019 в 05:52
поделиться

Ни одно доступное в BCL. Однако я опубликовал ReadOnlyDictionary (названный ImmutableMap) в моем Проекте Отдельно оплачиваемых предметов BCL

В дополнение к тому, чтобы быть полностью неизменным словарем это поддерживает создание объекта прокси, который реализует IDictionary и может использоваться в любом месте, где IDictionary взят. Это выдаст исключение каждый раз, когда одни из видоизменяющихся API называют

void Example() { 
  var map = ImmutableMap.Create<int,string>();
  map = map.Add(42,"foobar");
  IDictionary<int,string> dictionary = CollectionUtility.ToIDictionary(map);
}
3
ответ дан JaredPar 23 November 2019 в 05:52
поделиться

Вы могли создать класс, который только реализует частичную реализацию словаря и скрывает все добавлять/удалять/функции множества.

Используйте словарь внутренне, которому внешний класс передает все запросы.

Однако, так как Ваш словарь, вероятно, содержит ссылочные типы, нет никакого способа, которым Вы приблизительно мешаете пользователю установить значения на классах, сохраненных словарем (если те классы сами не только для чтения),

1
ответ дан Jason Coyne 23 November 2019 в 05:52
поделиться

.NET 4.5

Платформа.NET 4.5 BCL представляет ReadOnlyDictionary<TKey, TValue> (источник).

Поскольку Платформа.NET 4.5 BCL не включает AsReadOnly для словарей необходимо будет записать собственное (если Вы захотите это). Это было бы что-то как следующее, простота которого, возможно, выделяется, почему это не был приоритет для.NET 4.5.

public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(
    this IDictionary<TKey, TValue> dictionary)
{
    return new ReadOnlyDictionary<TKey, TValue>(dictionary);
}

.NET 4.0 и ниже

До.NET 4.5, нет никакого класса платформы.NET, который переносит a Dictionary<TKey, TValue> как ReadOnlyCollection переносит Список. Однако не трудно создать то.

Вот пример - существуют многие другие если Вы Google для ReadOnlyDictionary.

230
ответ дан Steven 23 November 2019 в 05:52
поделиться

Нет, но это было бы легко к самокрутке. IDictionary действительно определяет свойство IsReadOnly. Просто перенесите Словарь и бросьте NotSupportedException из соответствующих методов.

4
ответ дан wekempf 23 November 2019 в 05:52
поделиться

IsReadOnly на IDictionary унаследован от ICollection ( IDictionary расширяет ICollection как ICollection > ). Он никоим образом не используется и не реализуется (и фактически "скрыт" за счет использования явной реализации связанных членов ICollection ).

Я могу видеть как минимум 3 способа для решения проблемы:

  1. Реализуйте настраиваемое чтение только IDictionary и обернуть / делегировать внутреннему словарь, как было предложено
  2. Вернуть ICollection > только для чтения или IEnumerable > в зависимости от использования значение
  3. Клонировать словарь, используя копию конструктор .ctor (IDictionary ) и вернуть копию - это способ, которым пользователь может с этим справиться как им угодно и не влияние на состояние объекта размещение исходного словаря. Запись что если словарь ты клонирование содержит ссылочные типы ( не строки, как показано в примере ) вам нужно будет сделать копирование "вручную" и клонировать ссылку типы тоже.

В стороне; при раскрытии коллекций стремитесь предоставить минимально возможный интерфейс - в данном примере это должен быть IDictionary, поскольку это позволяет вам изменять базовую реализацию, не нарушая публичный контракт, предоставляемый типом.

11
ответ дан 23 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: