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:
Determine if type is dictionary [duplicate]
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())))
Längere 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, dass wir diese Art haben:
public class CustomReadOnlyDictionary : IReadOnlyDictionary<string, MyClass>
public class CustomGenericDictionary : IDictionary<string, MyClass>
public class CustomDictionary : IDictionary
und diese Instanzen:
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 verwenden .IsAssignableFrom() Methode:
var dictionaries2 = dictionaries.Where(d =>
{
var type = d.GetType();
return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type.GetGenericTypeDefinition());
}); // count == 0!!
wir jede Instanz nicht bekommen
so beste Weg ist, alle Schnittstellen zu bekommen und überprü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
es würde wahrscheinlich besser mit dem Boxed-Wert als mit Reflektion arbeiten. –
Ich bin mir nicht sicher, was du meinst? Sie können nicht einfach eine KeyValuePair boxen, um den Wert daraus zu extrahieren. –
Ihre Lösung hat funktioniert. Ich habe die if-Anweisung geändert, um weiterzumachen und nur "is IDictionary" zu testen (der Typ Ihres Teils funktionierte aus irgendeinem Grund nicht). Ich änderte auch "typeof (KeyValuePair <,>)" zu "listBox.SelectedItem" –