是否存在存储由字符串键或整数索引索引的数据的类型?

时间:2009-06-10 19:11:20

标签: .net collections

List(Of T)存储由整数索引的数据 Dictionary(Of String, T)存储通过字符串

索引的数据

是否有类型或通用或专门的东西可以让我通过索引或名称访问T数组?

9 个答案:

答案 0 :(得分:7)

我认为System.Collections.Specialized.OrderedDictionary正是您所寻找的。

答案 1 :(得分:5)

如果您的“姓名”很容易通过“T”确定,我建议KeyedCollection

它的作用类似于List,因为您可以按索引查找项目。但它也像字典一样工作,因为它在内部使用Dictionary来将名称(键)映射到适当的索引,并为您的键类型提供索引器。


你问它是如何知道密钥使用的。 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

这就是它的全部。您现在拥有一个可以像字典或列表一样工作的集合。当你可以使用泛型或其他接口来避免将类绑定到特定类型时,它会更加强大。

答案 2 :(得分:2)

我觉得这样的东西最接近你想要的东西:

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

你只是采用常规词典&lt;&gt;并且还添加了通过int索引的能力。

修改:Mehrdad提出了一个很好的观点,即我的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<TKey, TValue>

答案 3 :(得分:1)

OrderedDictionary的专业版不通用。

您可以使用自定义GenericOrderedDictionary类实现Generic Dictionary接口。

拥有私人

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 );
        }
    }

答案 4 :(得分:0)

听起来你需要一个多图,但不幸的是在BCL中没有这个通用的实现。正如另一个答案所述,System.Collections.Specialized.OrderedDictionary是一个可能满足您需求的特定实现,尽管它不使用泛型。

答案 5 :(得分:0)

如果你有一个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);

答案 6 :(得分:0)

这就是我正在测试的内容当我实现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

结束班

答案 7 :(得分:-1)

我认为您正在寻找System.Collections.Hashtable:)

答案 8 :(得分:-1)

通过索引(列出<列表< T > >)访问T列表是否足够好?

List<List<foo>> list = new List<List<foo>>();
List<foo> firstList = list[0];