Существует ли тип, который хранит данные, индексированные строковым ключом или целочисленным индексом?

Я думаю, что ответ на этот вопрос зависит от того, как вы тестируете свои ошибки.

  • Используете ли вы инструмент автоматического тестирования (например, платформы xUnit, Fit / Fitnesse и т. Д.)?
  • Используете ли вы автоматизированный процесс сборки?
  • Этот автоматизированный процесс сборки вызывает тесты и записывает результаты?

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

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

Для моего проекта мы используем subversion для контроля исходного кода, Jira для управления активностью, Hudson для сборки, Fitnesse и MSTest для тестирования. Все они связаны друг с другом с помощью непрерывной интеграции. Fitnesse проводит приемочные тесты и MSTest модульное тестирование, и они запускаются автоматически каждый раз, когда выполняется сборка, чтобы дать нам количественный показатель того, насколько «хороша» сборка.

5
задан Mehrdad Afshari 10 June 2009 в 20:26
поделиться

9 ответов

Если ваши «имена» легко определяются по вашему «T», я предлагаю KeyedCollection .

Он работает как Список , в котором вы можете искать элементы по индексу. Но он также работает как словарь, поскольку он использует словарь внутри для сопоставления имен (ключей) с соответствующим индексом и предоставляет индексатор для вашего типа ключа.


Вы спросили, откуда он знает, что использовать для ключа. KeyedCollection - это абстрактный класс, который вы должны унаследовать. К счастью, это легко сделать. Единственный метод, который вам нужно перегрузить, - это GetKeyForItem () . Этот метод - ответ на ваш вопрос. Например, возьмем этот простой класс:

Public Class MyClass
    Public UniqueID As Guid
    Public OtherData As String
End Class

Вы можете реализовать KeyedCollection следующим образом:

Public Class MyClassCollection
    Inherits KeyedCollection(Of Guid, MyClass)

    Public Overrides Function GetKeyForItem(ByVal item As MyClass) As Guid
        Return item.UniqueID
    End Function
End Class

Вот и все. Теперь у вас есть коллекция, которая будет работать как словарь или список. Это еще более эффективно, когда вы можете использовать универсальные шаблоны или другие интерфейсы, чтобы избежать привязки класса к определенному типу.

5
ответ дан 18 December 2019 в 14:50
поделиться

Похоже, вам нужна мульти-карта, но, к сожалению, в BCL нет универсальной реализации этого. Как упоминалось в другом ответе, System.Collections.Specialized.OrderedDictionary - это конкретная реализация, которая может удовлетворить ваши потребности, хотя и не использует дженерики.

0
ответ дан 18 December 2019 в 14:50
поделиться

Это то, что я сейчас тестирую, большая часть функций была автоматически заполнена для меня, когда я реализовал IDictionary

Public Class bDictionary(Of TKey, TVAlue)
Implements IDictionary(Of TKey, TVAlue)

Private dictionary As New Dictionary(Of TKey, TVAlue)
Private list As List(Of TKey)

Default Public Property Item(ByVal which As TKey) As TVAlue Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).Item
    Get
        Return dictionary(which)
    End Get
    Set(ByVal value As TVAlue)
        dictionary(which) = value
    End Set
End Property

Default Public Property Item(ByVal index As Integer) As TVAlue
    Get
        Return dictionary(list(index))
    End Get
    Set(ByVal value As TVAlue)
        dictionary(list(index)) = value
    End Set
End Property

Public Sub Add(ByVal key As TKey, ByVal value As TVAlue) Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).Add
    dictionary.Add(key, value)
    list.Add(key)
End Sub

Public Sub Add(ByVal item As System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)) Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).Add
    Add(item.Key, item.Value)
End Sub

Public Sub Clear() Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).Clear
    dictionary.Clear()
    list.Clear()
End Sub

Public Function Contains(ByVal item As System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)) As Boolean Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).Contains
    If dictionary.ContainsKey(item.Key) AndAlso dictionary(item.Key).Equals(item.Value) Then
        Return True
    Else
        Return False
    End If

End Function


Public ReadOnly Property Count() As Integer Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).Count
    Get
        Return list.Count
    End Get
End Property

Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).IsReadOnly
    Get
        Return False
    End Get
End Property

Public Function Remove(ByVal item As System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)) As Boolean Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).Remove
    Return Remove(item.Key)
End Function

Public Function ContainsKey(ByVal key As TKey) As Boolean Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).ContainsKey
    Return list.Contains(key)
End Function

Public ReadOnly Property Keys() As System.Collections.Generic.ICollection(Of TKey) Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).Keys
    Get
        Return dictionary.Keys
    End Get
End Property

Public Function Remove(ByVal key As TKey) As Boolean Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).Remove
    If list.Contains(key) Then
        list.Remove(key)
        dictionary.Remove(key)
        Return True
    Else
        Return False
    End If
End Function

Public Function TryGetValue(ByVal key As TKey, ByRef value As TVAlue) As Boolean Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).TryGetValue
    Return dictionary.TryGetValue(key, value)
End Function

Public ReadOnly Property Values() As System.Collections.Generic.ICollection(Of TVAlue) Implements System.Collections.Generic.IDictionary(Of TKey, TVAlue).Values
    Get
        Return dictionary.Values
    End Get
End Property


Public Sub CopyTo(ByVal array() As System.Collections.Generic.KeyValuePair(Of TKey, TVAlue), ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).CopyTo

    For Each Item As TKey In dictionary.Keys
        array.SetValue(New KeyValuePair(Of TKey, TVAlue)(Item, dictionary(Item)), arrayIndex)
        arrayIndex += 1
    Next

End Sub

Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
    Return dictionary.GetEnumerator()
End Function

Public Function GetEnumerator1() As System.Collections.Generic.IEnumerator(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)) Implements System.Collections.Generic.IEnumerable(Of System.Collections.Generic.KeyValuePair(Of TKey, TVAlue)).GetEnumerator
    Return dictionary.GetEnumerator
End Function

End Class

0
ответ дан 18 December 2019 в 14:50
поделиться

Думаю, вы ищете System.Collections.Hashtable :)

-1
ответ дан 18 December 2019 в 14:50
поделиться

Достаточно хорошо обращается к списку T по индексу (List < List < T > > ) ?

List<List<foo>> list = new List<List<foo>>();
List<foo> firstList = list[0];
-1
ответ дан 18 December 2019 в 14:50
поделиться

Если у вас есть массив T, вы можете сгенерировать несколько словарей из этого массива, вызвав ToDictionary и загрузка различных свойств T.

Предположим, что T является клиентом:

Customer[] myCustomers = getArray();
Dictionary<int, Customer> byID = myCustomers
    .ToDictionary(c => c.ID);
Dictionary<string, Customer> byName = myCustomers
    .ToDictionary(c => c.Name);
Dictionary<int, Customer> byOriginalPosition = myCustomers
    .Select( (c, i) => new {c, i})
    .ToDictionary(x => x.i, x => x.c);
0
ответ дан 18 December 2019 в 14:50
поделиться

Мне кажется, что-то вроде этого ближе всего к тому, что вы хотите:

  class IndexDictionary<TKey, TValue> : Dictionary<TKey, TValue>
  {
    public TValue this[int i]
    {
      get { return this[Keys.ElementAt(i)]; }
      set { this[Keys.ElementAt(i)] = value; }
    }
  }

Вы просто берете обычный Dictionary <> и добавляете возможность индексирования по int.

Edit : Мердад поднимает хороший вопрос, что мой метод IndexDictionary.Add (TKey, TValue) может привести к вставке , а не к добавлению . Если это вызовет проблемы в вашей ситуации, я бы предложил что-то вроде этого:

  class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>
  {
    private OrderedDictionary data = new OrderedDictionary();

    public TValue this[int i]
    {
      get { return (TValue)data[i]; }
      set { data[i] = value; }
    }

    //Implement IDictionary<TKey, TValue> using the methods of the OrderedDictionary
  }

Это дает вам преимущества сохранения порядка OrderedDictionary с безопасностью типов Dictionary .

2
ответ дан 18 December 2019 в 14:50
поделиться

Специализированная версия OrderedDictionary не является универсальной.

Вы можете реализовать интерфейс Generic Dictionary с настраиваемый класс GenericOrderedDictionary.

Иметь частный

List<TKey>
и частный
List<TValue>
.

Visual Studio может за вас заглушить методы интерфейса.

Начало будет выглядеть так:


public class GenericOrderedDictionary< TKey, TValue >
    : IDictionary<TKey, TValue>
{
    private List<TKey> keys;
    private List<TValue> values;

    #region IDictionary<TKey,TValue> Members

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

    bool IDictionary<TKey, TValue>.ContainsKey( TKey key )
    {
        return keys.Contains( key );
    }

    ICollection<TKey> IDictionary<TKey, TValue>.Keys
    {
        get
        {
            return new List<TKey>( keys );
        }
    }

    bool IDictionary<TKey, TValue>.Remove( TKey key )
    {
        int index = keys.IndexOf( key );
        if ( index >= 0 )
        {
            keys.Remove( key );
            values.RemoveAt( index );
        }
    }

1
ответ дан 18 December 2019 в 14:50
поделиться
Другие вопросы по тегам:

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