Frage

Gibt es eine Möglichkeit zu testen, ob ein Objekt ein Wörterbuch ist?

Bei einem Verfahren Ich versuche, einen Wert von einem ausgewählten Elemente in einem Listenfeld zu bekommen. Unter bestimmten Umständen kann das Listenfeld ein Wörterbuch gebunden werden, aber dies ist nicht bei der Kompilierung bekannt.

Ich möchte etwas ähnliches wie dies tun:

if (listBox.ItemsSource is Dictionary<??>)
{
    KeyValuePair<??> pair = (KeyValuePair<??>)listBox.SelectedItem;
    object value = pair.Value;
}

Gibt es eine Möglichkeit, diese dynamisch zur Laufzeit zu tun, mithilfe von Reflektion? Ich weiß, es ist möglich, Reflexion mit generischen Typen zu verwenden und die Schlüssel / Wert-Parameter bestimmen, aber ich bin nicht sicher, ob es eine Möglichkeit, den Rest zu tun, nachdem diese Werte abgerufen werden.

War es hilfreich?

Lösung

Es sollte so etwas wie die folgenden sein. Ich schrieb dies in der Antwort-Box, so dass die Syntax nicht ganz richtig sein kann, aber ich habe es Wiki editierbar gemacht, so kann jemand reparieren.

if (listBox.ItemsSource.IsGenericType && 
    typeof(IDictionary<,>).IsAssignableFrom(listBox.ItemsSource.GetGenericTypeDefinition()))
{
    var method = typeof(KeyValuePair<,>).GetProperty("Value").GetGetMethod();
    var item = method.Invoke(listBox.SelectedItem, null);
}

Andere Tipps

Überprüfen Sie, ob es implementiert IDictionary.

Siehe die Definition von System.Collections.IDictionary zu sehen, was das gibt Ihnen.

if (listBox.ItemsSource is IDictionary)
{
    DictionaryEntry pair = (DictionaryEntry)listBox.SelectedItem;
    object value = pair.Value;
}

EDIT: Alternative, als ich erkannte KeyValuePair ist nicht gießbar sind Dictionary

if (listBox.DataSource is IDictionary)
{
     listBox.ValueMember = "Value";
     object value = listBox.SelectedValue;
     listBox.ValueMember = ""; //If you need it to generally be empty.
}

Diese Lösung verwendet Reflektion, aber in diesem Fall, dass Sie nicht über die Grunzen Arbeit zu tun, List-Box macht es für Sie. Auch wenn Sie in der Regel Wörterbücher als Datenquellen haben Sie in der Lage sein Reseting Valuemember die ganze Zeit zu vermeiden.

Ich weiß, diese Frage vor vielen Jahren gefragt wurde, aber es ist öffentlich noch sichtbar.

Es gab hier einige Beispiele in diesem Thema vorgeschlagen und in dieser:
fest, ob Art Wörterbuch [Duplikat] ist

, aber es gibt nur wenige Mismatches, so dass ich möchte, dass meine Lösung teilen

Kurze Antwort:

var dictionaryInterfaces = new[]
{
    typeof(IDictionary<,>),
    typeof(IDictionary),
    typeof(IReadOnlyDictionary<,>),
};

var dictionaries = collectionOfAnyTypeObjects
    .Where(d => d.GetType().GetInterfaces()
        .Any(t=> dictionaryInterfaces
            .Any(i=> i == t || t.IsGenericType && i == t.GetGenericTypeDefinition())))

Lange Antwort:
Ich glaube, dies ist der Grund, warum Menschen machen Fehler:

//notice the difference between IDictionary (interface) and Dictionary (class)
typeof(IDictionary<,>).IsAssignableFrom(typeof(IDictionary<,>)) // true 
typeof(IDictionary<int, int>).IsAssignableFrom(typeof(IDictionary<int, int>)); // true

typeof(IDictionary<int, int>).IsAssignableFrom(typeof(Dictionary<int, int>)); // true
typeof(IDictionary<,>).IsAssignableFrom(typeof(Dictionary<,>)); // false!! in contrast with above line this is little bit unintuitive

so lassen sagen, wir haben diese Typen:

public class CustomReadOnlyDictionary : IReadOnlyDictionary<string, MyClass>
public class CustomGenericDictionary : IDictionary<string, MyClass>
public class CustomDictionary : IDictionary

und diese Fälle:

var dictionaries = new object[]
{
    new Dictionary<string, MyClass>(),
    new ReadOnlyDictionary<string, MyClass>(new Dictionary<string, MyClass>()),
    new CustomReadOnlyDictionary(),
    new CustomDictionary(),
    new CustomGenericDictionary()
};

also, wenn wir .IsAssignableFrom () -Methode verwenden:

var dictionaries2 = dictionaries.Where(d =>
    {
        var type = d.GetType();
        return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type.GetGenericTypeDefinition());
    }); // count == 0!!

wir keine Instanz bekommen

so beste Weg ist, um alle Schnittstellen zu bekommen und prüfen, ob einer von ihnen Wörterbuch-Schnittstelle ist:

var dictionaryInterfaces = new[]
{
    typeof(IDictionary<,>),
    typeof(IDictionary),
    typeof(IReadOnlyDictionary<,>),
};

var dictionaries2 = dictionaries
    .Where(d => d.GetType().GetInterfaces()
        .Any(t=> dictionaryInterfaces
            .Any(i=> i == t || t.IsGenericType && i == t.GetGenericTypeDefinition()))) // count == 5

können Sie überprüfen, um zu sehen, ob es IDictionary . Sie müssen nur die Verwendung aufzählen über Dictionary Klasse.

Sie könnten ein wenig mehr Generika und fragen sein, anstatt wenn es IDictionary implementiert. Dann wird die KeyValue Sammlung Ebene Objects Contina.

Ich glaube, eine Warnung an Ort ist.

Wenn Sie testen, ob ein Objekt dieses oder jenes etwas ‚a‘, du bist (Teil) des Typs System Neuimplementierung. Die erste ‚ist ein‘ wird oft durch einen zweiten rasch folgt, und bald Ihr Code ist voll von Typprüfungen, die sollten sehr gut vom Typ System gehandhabt werden. - zumindest in einem objektorientierten Design

Natürlich, ich weiß nichts von dem Kontext der Frage. Ich kenne eine 2000 Linie Datei in unserer eigenen Code-Basis, der String Konvertierungen 50 verschiedene Objekt-Handles ...: (

if(typeof(IDictionary).IsAssignableFrom(listBox.ItemsSource.GetType()))
{

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top