比较IEnumerable <t> </t>的类型

时间:2010-09-14 12:40:29

标签: c# generics types ienumerable

我有字典,根据传入的值返回一个方法。定义如下:

Dictionary<Type, IXmlWriterConverter>

我现在添加了一个新的函数,其Key / type设置为IEnumerable,到目前为止一直很好。 但是当我用包含两个DataTables的List执行我的单元测试时,但字典找不到密钥,例如我的类型转换不同。

为什么会这样?什么是解决我的问题的正确尝试?

编辑:对不起,这是请求的代码; - )

生成测试值的函数:

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

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

    return resultDataTable;
}

单元测试调用的函数:

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

检查词典的功能:

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

2.Edit:

将值添加到词典中的代码:

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

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

InputType是转换器的只读(get)属性。我检查了添加到字典中的类型,并注册为IEnumerable,但是当我在列表中传递时检查typeof时,类型是List而不是IEnumerable。我被告知发生这种情况是因为我将值作为对象传递。

5 个答案:

答案 0 :(得分:4)

这对我来说是一个真正具有代码性的解决方案,它会降低效率,但您也可以在Type上迭代GetInterfaces()方法,如下所示:

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

然后你可以对类型进行查找,如果不起作用,可以对它的接口进行查找。

然而,这感觉就像一个可怕的黑客,这通常表明需要做更多的设计工作。是不是可以将List类型放在字典中?有没有更好的方法来进行此查找?

另外,关于进行字典查找的注意事项:使用TryGetValue方法更有效,如下所示:

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

    return null;
}

当你这样做时,它只对字典进行一次查找,而如果你使用ContainsKey则必须进行两次查找。

答案 1 :(得分:1)

它有点破解但是在查看代码时我唯一想到的是添加其他通用的写入方法:

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

这允许为IEnumerable标识正确的类型,并使另一个Write方法不会破坏任何现有代码。

答案 2 :(得分:0)

可能您正在尝试检索List类型而不是IEnumerable(继承在此上下文中不起作用)

如果您需要更多详细信息和更确定的答案,请粘贴执行查找的代码:)

答案 3 :(得分:0)

您还应该发布检索测试值的代码。但是根据您提供的内容,您是否可以使用非通用IEnumerable来检索值而不是您用于生成它们的通用版本?

答案 4 :(得分:0)

  

InputType是只读(get)   转换器的属性。我检查了   添加到字典中的类型和   已注册为IEnumerable,   但是当我查看了typeof   在我的列表中传递时,类型是   列表而不是IEnumerable。有人告诉我   发生这种情况是因为我传入了   作为对象的值。

就像他们在MythBusters上说的那样,嗯,这是你的问题!尽管ListIEnumerable代表的Type个对象每个都绝对不一样。用程序员术语typeof(List) != typeof(IEnumerable)。这就是查找不起作用的原因。