Sé que esta pregunta se le preguntó hace muchos años, pero todavía es visible para el público.
había pocos ejemplos que aquí se proponen en este tema y en éste:
Determine if type is dictionary [duplicate]
pero hay pocos desajustes, así que quiero compartir mi solución
Respuesta corta:
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())))
Respuesta más larga:
Creo que esta es la razón por la cual la gente comete errores:
//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
así que vamos a decir que tenemos estos tipos:
public class CustomReadOnlyDictionary : IReadOnlyDictionary<string, MyClass>
public class CustomGenericDictionary : IDictionary<string, MyClass>
public class CustomDictionary : IDictionary
y estos casos:
var dictionaries = new object[]
{
new Dictionary<string, MyClass>(),
new ReadOnlyDictionary<string, MyClass>(new Dictionary<string, MyClass>()),
new CustomReadOnlyDictionary(),
new CustomDictionary(),
new CustomGenericDictionary()
};
por lo que si vamos a utilizar Método .IsAssignableFrom():
var dictionaries2 = dictionaries.Where(d =>
{
var type = d.GetType();
return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type.GetGenericTypeDefinition());
}); // count == 0!!
no vamos a obtener cualquier instancia
así que mejor manera es conseguir todas las interfaces y comprobar si alguno de ellos es la interfaz diccionario:
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
probablemente funcionaría mejor usando el valor encerrado que usando la reflexión. –
No estoy seguro de lo que quieres decir? No puede simplemente colocar un KeyValuePair para extraer el valor del mismo. –
Su solución funcionó. Cambié la declaración if para continuar y simplemente probar "is IDictionary" (el tipo de parte de la tuya no funcionó por algún motivo). También cambié "typeof (KeyValuePair <,>)" a "listBox.SelectedItem" –