Bob*_*erg 15 c# reflection collections dictionary
有没有办法测试对象是否是字典?
在一个方法中,我试图从列表框中的选定项目中获取值.在某些情况下,列表框可能绑定到字典,但在编译时不知道.
我想做类似的事情:
if (listBox.ItemsSource is Dictionary<??>)
{
    KeyValuePair<??> pair = (KeyValuePair<??>)listBox.SelectedItem;
    object value = pair.Value;
}
有没有办法在运行时使用反射动态地执行此操作?我知道可以使用泛型类型的反射并确定键/值参数,但我不确定在检索这些值之后是否有办法完成其余的操作.
Guv*_*nte 13
检查它是否实现了IDictionary.
请参阅System.Collections.IDictionary的定义以查看它为您提供的内容.
if (listBox.ItemsSource is IDictionary)
{
    DictionaryEntry pair = (DictionaryEntry)listBox.SelectedItem;
    object value = pair.Value;
}
编辑: 当我意识到KeyValuePair不能转换为DictionaryEntry时的替代方案
if (listBox.DataSource is IDictionary)
{
     listBox.ValueMember = "Value";
     object value = listBox.SelectedValue;
     listBox.ValueMember = ""; //If you need it to generally be empty.
}
此解决方案使用反射,但在这种情况下,您不必执行繁琐的工作,ListBox会为您执行此操作.此外,如果您通常将字典作为数据源,则可以避免一直重置ValueMember.
Gre*_*ech 10
它应该类似于以下内容.我在答案框中写了这个,所以语法可能不完全正确,但我已经将它编辑为Wiki,所以任何人都可以解决.
if (listBox.ItemsSource.IsGenericType && 
    typeof(IDictionary<,>).IsAssignableFrom(listBox.ItemsSource.GetGenericTypeDefinition()))
{
    var method = typeof(KeyValuePair<,>).GetProperty("Value").GetGetMethod();
    var item = method.Invoke(listBox.SelectedItem, null);
}
小智 5
我知道这个问题是多年前提出的,但它仍然公开可见。
本主题和本主题中提出的示例很少:
确定类型是否为字典 [重复]
但几乎没有不匹配,所以我想分享我的解决方案
简短的回答:
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())))
更长的答案: 
我相信这就是人们犯错误的原因:
//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
所以假设我们有这些类型:
public class CustomReadOnlyDictionary : IReadOnlyDictionary<string, MyClass>
public class CustomGenericDictionary : IDictionary<string, MyClass>
public class CustomDictionary : IDictionary
和这些实例:
var dictionaries = new object[]
{
    new Dictionary<string, MyClass>(),
    new ReadOnlyDictionary<string, MyClass>(new Dictionary<string, MyClass>()),
    new CustomReadOnlyDictionary(),
    new CustomDictionary(),
    new CustomGenericDictionary()
};
所以如果我们将使用 .IsAssignableFrom() 方法:
var dictionaries2 = dictionaries.Where(d =>
    {
        var type = d.GetType();
        return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type.GetGenericTypeDefinition());
    }); // count == 0!!
我们不会得到任何实例
所以最好的方法是获取所有接口并检查它们中是否有一个是字典接口:
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
| 归档时间: | 
 | 
| 查看次数: | 12865 次 | 
| 最近记录: |