简体   繁体   English

比较IEnumerable的类型<T>

[英]Compare type of IEnumerable<T>

I have dictionary that gives me back a method according to the value passed in. Defined as so: 我有一个字典,可以根据传入的值给我返回一个方法。定义如下:

Dictionary<Type, IXmlWriterConverter>

I have now added a new function that which has the Key/type set to IEnumerable, so far so good. 现在,我添加了一个新函数,该函数的Key / type设置为IEnumerable,到目前为止一切顺利。 But when I execute my unit test with a List containing two DataTables but the dictionary can not find the key eg my type conversion differs. 但是,当我使用包含两个DataTables的List执行单元测试时,字典找不到键,例如,我的类型转换有所不同。

Why is that so? 为什么会这样? And what would be the right attempt to solve my problem? 解决我的问题的正确尝试是什么?

Edit: Sorry here is the requested code ;-) 编辑:对不起,这是要求的代码;-)

Function that generates the testvalues: 生成测试值的函数:

public IEnumerable<DataTable> CreateTestDataTableList()
{
    var resultDataTable = new List<DataTable>();

    resultDataTable.Add(CreateTestTable("testTable1", 2));
    resultDataTable.Add(CreateTestTable("testTable2", 3));

    return resultDataTable;
}

Function called by the unit test: 单元测试调用的函数:

public void Write(XmlWriter xmlWriter, object value)
{
    ...
    converter = FindConverter(value.GetType());
}

Function checking the dictionary: 函数检查字典:

public IXmlWriterConverter FindConverter(Type type)
{
    if(Converters.ContainsKey(type))
    {
        return Converters[type];
    }
    return null;
}

2.Edit: 2.编辑:

Code that adds the values to the Dictionary: 将值添加到字典的代码:

public void Add(IXmlWriterConverter xmlWriterConverter)
{
    if(Converters.ContainsKey(xmlWriterConverter.InputType))
    {
        Remove(xmlWriterConverter);
    }

    Converters.Add(xmlWriterConverter.InputType, xmlWriterConverter);
}

The InputType is a readonly (get) property of the converter. InputType是转换器的只读(获取)属性。 I checked the type added to the dictionary and that was registered as IEnumerable, however when I checked on the typeof when passing in my list the type was List and not IEnumerable. 我检查了添加到字典中的类型,该类型已注册为IEnumerable,但是当我在传递列表时检查typeof时,类型为List而不是IEnumerable。 I was told that this happens because I pass in the values as object. 有人告诉我发生这种情况是因为我将值作为对象传递。

This is a really code-stinky solution to me, and it cuts down on the efficiency, but you can also iterate through the GetInterfaces() method on Type, like this: 对于我来说,这是一个非常糟糕的代码解决方案,它降低了效率,但是您也可以通过Type上的GetInterfaces()方法进行迭代,如下所示:

List<DataTable> l = new List<DataTable>();
var t = l.GetType();
var ints = t.GetInterfaces();

Then you could do a lookup on the type, and, if that doesn't work do a lookup on it's interfaces. 然后,您可以在类型上进行查找,如果不起作用,请在其接口上进行查找。

However , this feels like a terrible hack, which usually indicates that some more design work needs to be done. 但是 ,这感觉像是一个可怕的hack,通常表明还需要做更多的设计工作。 Is it not possible to put the List type in the dictionary? 列表类型不能放在字典中吗? Is there no better way of doing this lookup? 有没有更好的方法来执行此查找?

Also, a note on doing dictionary lookups: It's more efficient to use the TryGetValue method, like this: 另外,还有关于字典查找的说明:使用TryGetValue方法的效率更高,如下所示:

public IXmlWriterConverter FindConverter(Type type)
{
    IXmlWriterConverter converter;
    if( Converters.TryGetValue(type, out converter) )
    {
        return converter;
    }

    return null;
}

When you do it this way, it only does one lookup on the dictionary, whereas if you use ContainsKey it has to do two lookups. 当您以这种方式执行此操作时,它只会在字典上进行一次查找,而如果您使用ContainsKey,则它必须进行两次查找。

Its a bit of hack but the only thing that gets into my mind when looking at your code, is to add an other generic write method: 有点hack,但是在查看代码时,我唯一想到的就是添加了另一个通用的write方法:

public void Write<TValue>(XmlWriter writer, TValue value) {
// ...
}

This allows to identify the right type for IEnumerable and leaves the other Write method to not break any existing code. 这允许为IEnumerable标识正确的类型,并保留其他Write方法以不破坏任何现有代码。

Probably you are trying to retrieve List type and not IEnumerable (inheritance is not going to work in this context) 可能是您尝试检索List类型而不是IEnumerable(继承在这种情况下不起作用)

Please paste the code that does the lookup if you want more details and more certain answer :) 如果您需要更多详细信息和更确定的答案,请粘贴执行查询的代码:)

You should also post the code of where you are retrieving the test values. 您还应该张贴在哪里获取测试值的代码。 But based on what you've given, are you possibly using the non-generic IEnumerable to retrieve the values instead of the generic version that you're using to generate them? 但是根据您给出的内容,您是否可能使用非通用的IEnumerable来检索值,而不是用于生成它们的通用版本?

The InputType is a readonly (get) property of the converter. InputType是转换器的只读(获取)属性。 I checked the type added to the dictionary and that was registered as IEnumerable, however when I checked on the typeof when passing in my list the type was List and not IEnumerable. 我检查了添加到字典中的类型,该类型已注册为IEnumerable,但是当我在传递列表时检查typeof时,类型为List而不是IEnumerable。 I was told that this happens because I pass in the values as object. 有人告诉我发生这种情况是因为我将值作为对象传递。

Like they say on MythBusters , well, there's your problem! 就像他们在MythBusters上说的那样,那是您的问题! Even though List is-a IEnumerable the Type objects that represent each are definitely not the same. 即使ListIEnumerable ,代表每个的Type对象绝对也不相同。 In programmer jargon, typeof(List) != typeof(IEnumerable) . 用程序员的行话, typeof(List) != typeof(IEnumerable) That is why the lookup is not working. 这就是查找不起作用的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM