2016-06-10 6 views
2

Ich bin auf der Suche nach einer Datenstruktur in C# ähnlich Dictionary, wo ich auf den Wert mit Index und Schlüssel zugreifen kann. Der Wert ist vom Typ Klasse und keine Zeichenfolge.Datenstruktur mit Schlüssel und Wert als Klassenart und Zugriffswert unter Verwendung von Schlüssel und Index

Ich erstelle eine Klassenbibliothek, in der ich versuche, eine Methode mit dem Namen Item zu erstellen, die Wert aus meiner Wert- und Schlüsselpaardatenstruktur zurückgibt. Aber wenn ich Integer-Parameter zu Item passieren dann sollte es Wert erhalten, indem Index verwenden und wenn Pass String Typ Item dann sollte es Wert zugreifen, indem Sie Taste (wie in Dictionary)

Hinweis: i bezeichnet this Link. Aber System.Collections.Specialized.NameValueCollection kann nicht verwendet werden, da es nur Zeichenfolgen als Werte speichern kann, aber ich möchte den Klassentyp als Wert angeben. Ich möchte mit Schlüssel und Index auf den Wert zugreifen.

+3

'Wörterbuch '? 'TValue' könnte eine Basisklasse sein. –

+0

@MaxSorin Entschuldigung. Ich habe dich nicht verstanden. Ich möchte auf den Wert zugreifen, indem Sie Schlüssel und Index verwenden. – Navaneet

+0

wie oben, Max ist korrekt, mit Generics können Sie eine Klasse als Wert in einem Wörterbuch speichern und dann linq Abfragen gegen die Wertspalte dieses Dictionary ausführen, um die gewünschten Ergebnisse herauszufiltern. – uk2k05

Antwort

0
System.Collections.Generic.Dictionary<TKeyItem, TValueItem> myDictionary = 
     new System.Collections.Generic.Dictionary<TKeyItem, TValueItem>(); 
    var key = new TKeyItem(); //create key object 
    var val = new TValueItem(); //create value object 
    myDictionary.Add(key, val); //add key value pair to the dictionary 
    var valueByKey = myDictionary[key]; // it will return val by key 
    var valuebyIndex = myDictionary.Values.ElementAt(0); // it will retun val by index 
+0

Siehe den Kommentar zu Max Sorins Antwort: Greifen Sie niemals auf den Wert eines Wörterbuchs per Index zu, die Reihenfolge ist nicht definiert. – Falanwe

0

Aktualisierter Test zum Entfernen/Hinzufügen von Elementen zum Wörterbuch. Es scheint, dass das Entfernen und Hinzufügen eines neuen Elements zum Wörterbuch dazu führt, dass das neue Element an der Position des entfernten Elements angezeigt wird. Was macht meinen Anspruch, dass mit einemDictionaryfür diese Aufgabe funktioniertfalse. Ich ziehe es vor, diese Antwort an Ort und Stelle zu lassen. Obwohl es keine gültige Lösung ist, kann es zeigen, warum die Dictionary-Lösung nicht verwendet werden sollte, wenn Sie auf die Sammlung per Schlüssel oder Index zugreifen möchten.

using System; 
using NUnit.Common; 
using NUnit.Framework; 
using System.Collections.Generic; 
using System.Linq; 

namespace UnitTests 
{ 
    [TestFixture] 
    public class UnitTest1 
    { 
     [Test] 
     public void TestMethod1() 
     { 

      var types = new[] { typeof(int), typeof(float), typeof(Guid), typeof(UnitTest1) }; 

      Dictionary <Guid, object> dictionary = types.Select(x => Activator.CreateInstance(x)).ToDictionary(y => Guid.NewGuid()); 

      types.ToList().ForEach(t => 
       Assert.IsTrue(dictionary.Any(x => x.Value.GetType() == t)) 
      ); 

      Assert.IsTrue(dictionary.ElementAt(0).Value is int); 
      Assert.IsTrue(dictionary.ElementAt(1).Value is float); 
      Assert.IsTrue(dictionary.ElementAt(2).Value is Guid); 
      Assert.IsTrue(dictionary.ElementAt(3).Value is UnitTest1); 

      dictionary.Add(Guid.NewGuid(), Guid.NewGuid()); 

      Assert.IsTrue(dictionary.ElementAt(4).Value is Guid); 

      //Remove the Guid 
      dictionary.Remove(dictionary.ElementAt(2).Key); 

      //See that the Element at the 2 position is now UnitTest1 
      Assert.IsTrue(dictionary.ElementAt(2).Value is UnitTest1); 

      //See that the Element at the 1 position is still float 
      Assert.IsTrue(dictionary.ElementAt(1).Value is float); 

      dictionary.Add(Guid.NewGuid(), new List<Guid>()); 

      //See that a newly added item is put the end of the dictionary 
      Assert.IsTrue(dictionary.ElementAt(4).Value is List<Guid>); //This Assertion Fails. The List<Guid> appears at position 2. 
     } 
    }  
} 

-Code erzeugt über ein Wörterbuch von Objekten verschiedenen Typen und findet sie dann im Wörterbuch auf dem Typ. Schließlich erhalten wir das Wörterbuchelement an der 0-Position und bestätigen, dass es sich um eine int handelt. Beachten Sie, dass der Schlüssel des Wörterbuchs nicht verwendet wird und ein beliebiger Datentyp sein könnte.

+0

Sie sollten niemals 'Dictionary ' auf diese Weise verwenden, da die Reihenfolge, in der der Enumerable den Wert abruft, nicht definiert ist. Es ist sogar explizit in der [Dokumentation] (https://msdn.microsoft.com/en-us/library/xfhwa508 (v = vs.110) .aspx) erwähnt: "Zum Zwecke der Aufzählung ist jedes Element im Wörterbuch behandelt als eine KeyValuePair -Struktur, die einen Wert und seinen Schlüssel darstellt. Die Reihenfolge, in der die Elemente zurückgegeben werden, ist nicht definiert. " – Falanwe

+0

Sie werden feststellen, dass ich die Erweiterungsmethode verwende, die von einer Schnittstelle definiert wird, die 'Dictionary <>' implementiert. Ich verwende nicht '.ToArray() [0]', um den Wert an der Position 0 zu erhalten. Zusätzliche 'Assert'-Anweisungen, die zu der Antwort hinzugefügt wurden, werden beweisen, dass das Verhalten wie erwartet ist. Dies verursacht jedoch zusätzliche Aufzählungen durch die Sammlung. –

+0

Ich merke es, aber das ändert nichts. Nichts gibt Ihnen die Gewissheit, dass 'ElementAt (4)' tatsächlich das fünfte Element ist, das dem Wörterbuch hinzugefügt wurde. Es scheint der Fall bei der Implementierung von .Net 4.5.2 zu sein (die ich ausführe), aber es ist ein undefiniertes Verhalten, ein Implementierungsdetail, auf das man sich nie verlassen sollte. – Falanwe

1

Wenn eine nicht generische Sammlung Ihren Anforderungen entspricht, können Sie OrderedDictionary verwenden. Erwarten Sie eine Menge Boxen und Unboxing, wenn Sie mit Werttypen arbeiten.

Wenn Sie unbedingt eine generische Version möchten, müssen Sie Ihre eigene erstellen. Zum Beispiel:

Sie müssen wahrscheinlich einige Ausnahmenbehandlung, aber die meisten Funktionen sind hier. Wenn Sie von dort aus IDictionary<TKey,TVale> implementieren möchten, sollten die fehlenden Elemente trivial sein.

Verwandte Themen