2009-06-10 14 views

回答

5

如果你的「名字」很容易從你的「T」中確定,我建議KeyedCollection

它的工作原理類似於List,因爲您可以按索引查找項目。但它也像字典一樣工作,因爲它在內部使用字典將名稱(鍵)映射到適當的索引,併爲鍵類型提供索引器。


你問它是如何知道密鑰的用法。 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 

這一切就是這麼簡單。您現在擁有一個可以像字典或列表一樣工作的集合。當您可以使用泛型或其他接口來避免將類綁定到特定類型時,它會更加強大。

-1

我認爲你正在尋找System.Collections.Hashtable :)

+0

號哈希表基本上是一個字典的泛型前的形式。馬斯洛(我相信)正在尋找一個可轉位字典,這在覈心框架中並不存在。 – 2009-06-10 19:16:26

+0

打倒我吧。這就是我想說的。 – ryanulit 2009-06-10 19:16:49

+0

我沒有看到一種通過整數索引的方法,它不是通用的。我認爲從我對散列表的理解來看,散列表應該正是我想要的,但到目前爲止,我已經探索了System.Collections.Hashtable它缺少索引和類型安全性。 – Maslow 2009-06-10 19:41:02

7

我覺得System.Collections.Specialized.OrderedDictionary是你在找什麼。

+0

這是一種特殊的multimap; BCL不具備通用目的。 – Charlie 2009-06-10 19:20:30

+0

OrderedDictionary會讓你通過整數或對象的索引它出現?我不喜歡處理不斷投射的拳擊/拆箱,但我認爲它可以在某些情況下起作用。 – Maslow 2009-06-10 19:38:36

-1

正在通過索引訪問T列表(列表<列表< T >>)是否足夠好?

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

聽起來你需要一個multimap,但不幸的是,在BCL中沒有這個通用的實現。正如另一個答案中提到的,System.Collections.Specialized.OrderedDictionary是一個特定的實現,它可能會覆蓋您的需求,儘管它不使用泛型。

1

OrderedDictionary的專用版本不是通用的。

您可以使用自定義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); 
     } 
    } 

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

您只需要定期使用字典<>,並且還可以通過int添加索引功能。

編輯:邁赫達德提出了一個很好的點,我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 
    } 

這給你的OrderedDictionaryDictionary<TKey, TValue>類型安全的保序好處。

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 

末級

相關問題