Как получить ReadOnlyCollection <T> Ключей в Словаре <T, S>

Конечно, есть. Вы можете легко разместить свой собственный сервер socket.io. tlaverdure / laravel-echo-server является отличным примером этого.

Уже через несколько месяцев для поддержки веб-сокетов существует пакет Laravel на основе php:

7
задан Nic Foster 8 May 2015 в 00:17
поделиться

5 ответов

Если Вы действительно хотите использовать ReadOnlyCollection <T>, проблема - то, что конструктор ReadOnlyCollection <T> берет IList <T>, в то время как KeyCollection Словаря является только ICollection <T>.

Таким образом, если Вы хотите перенести KeyCollection в ReadOnlyCollection, необходимо будет создать адаптер (или обертка) тип, реализовывая IList <T>, перенося KeyCollection. Таким образом, это было бы похоже:

var dictionary = ...;
var readonly_keys = new ReadOnlyCollection<T> (new CollectionListWrapper<T> (dictionary.Keys)
);

Не очень изящный, хотя, тем более, что KeyCollection уже является набором только для чтения, и что Вы могли просто раздать его как ICollection <T> :)

5
ответ дан 6 December 2019 в 15:36
поделиться

DrJokepu заявил, что могло бы быть трудно реализовать обертку для Набора Ключей. Но в данном случае я думаю, что реализация не является столь трудной, потому что, как мы знаем, это - обертка только для чтения.

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

Вот быстрая реализация обертки для Словаря. KeyCollection:

class MyListWrapper<T, TValue> : IList<T>
{
    private Dictionary<T, TValue>.KeyCollection keys;

    public MyListWrapper(Dictionary<T, TValue>.KeyCollection keys)
    {
        this.keys = keys;
    }

    #region IList<T> Members

    public int IndexOf(T item)
    {
        if (item == null)
            throw new ArgumentNullException();
        IEnumerator<T> e = keys.GetEnumerator();
        int i = 0;
        while (e.MoveNext())
        {
            if (e.Current.Equals(item))
                return i;
            i++;
        }
        throw new Exception("Item not found!");
    }

    public void Insert(int index, T item)
    {
        throw new NotImplementedException();
    }

    public void RemoveAt(int index)
    {
        throw new NotImplementedException();
    }

    public T this[int index]
    {
        get
        {
            IEnumerator<T> e = keys.GetEnumerator();
            if (index < 0 || index > keys.Count)
                throw new IndexOutOfRangeException();
            int i = 0;
            while (e.MoveNext() && i != index)
            {
                i++;
            }
            return e.Current;
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    #endregion

    #region ICollection<T> Members

    public void Add(T item)
    {
        throw new NotImplementedException();
    }

    public void Clear()
    {
        throw new NotImplementedException();
    }

    public bool Contains(T item)
    {
        return keys.Contains(item);
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        keys.CopyTo(array, arrayIndex);
    }

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

    public bool IsReadOnly
    {
        get { return true; }
    }

    public bool Remove(T item)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region IEnumerable<T> Members

    public IEnumerator<T> GetEnumerator()
    {
        return keys.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return keys.GetEnumerator();
    }

    #endregion
}

Это не могло бы быть лучшей реализацией для этих методов :) но это было только для доказательства, что это могло бы быть сделано.

5
ответ дан 6 December 2019 в 15:36
поделиться

Принятие Вас использует C# 3.0, и Вы имеете:

Словарь <T, S> d;

Затем

ReadOnlyCollection <T> r = новый ReadOnlyCollection <T> (d. Ключи. ToList ());

Необходимо будет также импортировать Систему. Пространство имен Linq.

1
ответ дан 6 December 2019 в 15:36
поделиться

К сожалению, Вы не можете к этому direcly насколько я знаю как KeyCollection<T> не выставляет ничего, что позволило бы Вам делать это легко.

Вы могли, однако, разделить на подклассы ReadOnlyCollection<T> так, чтобы его конструктор получил сам словарь, и переопределите соответствующие методы так, чтобы он выставил объекты Словаря, как будто они были его собственными объектами.

1
ответ дан 6 December 2019 в 15:36
поделиться

Это ужасно, но это сделает это

Dictionary<int,string> dict = new Dictionary<int, string>();
...
ReadOnlyCollection<int> roc = new ReadOnlyCollection<int>((new List<int>((IEnumerable<int>)dict.Keys)));
0
ответ дан 6 December 2019 в 15:36
поделиться
Другие вопросы по тегам:

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