2010-09-14 70 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方法不會破壞任何現有的代碼。