2010-09-14 67 views
1

我有字典,让我回来的方法根据传入的值定义为这样:比较IEnumerable类型的<T>

Dictionary<Type, IXmlWriterConverter> 

我现在补充说,其中有钥匙/类型集的新功能到IEnumerable,到目前为止这么好。 但是,当我执行我的单元测试与包含两个数据表的列表,但字典无法找到密钥,例如我的类型转换不同。

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

编辑:对不起这里是被请求代码;-)

函数生成该testvalues:

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。我被告知发生这种情况是因为我将值作为对象传入。

+0

也许你应该发布相关的代码,所以其他人可以真正看到发生了什么... – sloth 2010-09-14 12:43:17

+0

你可以提供一些示例代码? – LukeH 2010-09-14 12:43:31

+0

@dkson也许我应该这样做在第一次去..对不起,因为懒惰;-) – Mark 2010-09-14 12:58:32

回答

4

这是一个真正的代码臭的解决方案给我,它减少了工作效率,而且还可以通过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它必须做两个查找。

+0

嗨,罗布,是的,我原来也想与列表,但在与工作高级开发人员谈话后,我们想出了一个不同的解决方案,使我们能够使用IEnumerable 。不过谢谢你的提示。 – Mark 2010-09-14 15:23:27

0

也许你正在试图检索列表类型,而不是IEnumerable的(继承不会在这方面的工作)

,请复制粘贴,如果您想了解更多的细节和更确定的答案:)

,做查找代码
0

您还应该发布您所在的代码检索的测试值。但是根据你给出的内容,你是否可能使用非泛型IEnumerable来检索值而不是用来生成它们的通用版本?

+0

不,我从不使用IEnumerable的非通用版本。由于选择了通用转换器,因此测试失败。所以我无法为您提供测试的返回值。 – Mark 2010-09-14 13:07:12

0

InputType是转换器的只读(获取) 属性。我检查了 添加到字典中的类型,并且 被注册为IEnumerable, 但是,当我检查了传入我的列表时,类型为 的列表的类型为 列表而不是IEnumerable。我被告知 ,这是因为我通过 的值作为对象。

就像他们在MythBusters,上说的那样,这是你的问题!即使List是-de IEnumerableType代表每个的对象肯定不是相同的。用程序员的行话来说,typeof(List) != typeof(IEnumerable)。这就是查找不起作用的原因。

+0

这是真的,我也注意到,但为什么它引用我的IEnumerable ,这是我最初通过的,到列表?我想这就是我试图问.. – Mark 2010-09-17 06:32:13

+0

@Mark:我不知道。我想我会看到更多的代码来回答这个问题。具体来说,我需要了解如何将'value'传递给'Write',而不是'InputType'如何获得。 – 2010-09-17 12:40:06

+0

那么唯一缺少的代码片段就是来自单元测试的调用。但是,它将生成的IEnumerable作为写函数所需的对象传递。据我所知,该对象被铸造到列表而不是IEnumerable 。通过实现我的写入版本的通用版本,我能够解决这个问题。 – Mark 2010-09-18 06:51:41

1

它有点技巧,但看你的代码时进入我的脑海中唯一的,是添加其他通用写方法:

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

这允许以确定正确的类型IEnumerable和使另一个Write方法不会破坏任何现有的代码。