2015-03-03 63 views
0

我有一個從ProfileBase派生的列表。這個列表將包含個人資料的一個實例,, DynamicViewProfile因爲兩者都是從ProfileBaseLinq哪裏適合不同類型

衍生而來,但如果項目類型爲DynamicViewProfile,我必須使用節點名,如果配置文件那麼我應該那麼這個

profileListsForSearch = profileLists.Where(stringToCheck => 
((Profile)stringToCheck).DocName.Contains(searchBar.Text)).ToList(); 

可採用DocName使用是個人資料,這是正常的,但如果列表中包含DynamicViewProfile對象的話,我有一個例外,因爲DOCNAME爲空,我需要得到節點名

我希望我的問題是明確的

回答

7

沒有什麼特別之處LINQ在這裏 - 你基本上寫相同的代碼,你通常會使用isas

string searchText = searchBar.Text; 
profileListsForSearch = profileLists 
    .Where(profile => 
     profile is Profile 
     ? ((Profile)profile).DocName.Contains(searchText) 
     : ((DynamicViewProfile)profile).NodeName.Contains(searchText)) 
    .ToList(); 

這是假設這些都是涉及到的只有兩種。如果你的列表包含其他類型,你會得到一個InvalidCastException

然而,這是很醜陋 - 感覺就像ProfileBase應該揭露一些屬性或方法指示的總稱 - 然後可以實施在ProfileNodeNameDynamicViewProfile返回DocName。然後,你只需要:

string searchText = searchBar.Text; 
profileListsForSearch = profileLists 
    .Where(profile => profile.Name.Contains(searchText)) 
    .ToList(); 

這也是面向未來的中添加新的子類的ProfileBase方面 - 一般清潔使用多態性。每次需要投射時 - 特別有條件地投射一種或另一種 - 考慮一種常用的方法/屬性是否可行以使其更清潔。

+0

非常感謝您的解釋 – unbalanced 2015-03-03 07:00:50

+2

jeez,你怎麼能這麼快地輸入。我開始認爲你有一些「精神」鍵盤,而不是我們擁有的舊硬件:) – nvoigt 2015-03-03 07:05:55

+0

正如我在另一評論中所說的,我不能改變這些類,因爲它們來自WCF服務。你說得對,我可以有個例外。但類型是肯定的,所以它不會是問題。我知道我應該投出類型,但從來沒有經驗在Where條件下做:)謝謝 – unbalanced 2015-03-03 07:12:58

1

可以使用is來檢查對象並使用ternary操作符將條件應用於對象。

var result = profileLists.Where(stringToCheck =>stringToCheck is Profile ? 
          ((Profile)stringToCheck).DocName.Contains(searchBar.Text) 
          : ((DynamicViewProfile)stringToCheck).NodeName.Contains(searchBar.Text)).ToList(); 
+0

你是偉大的!謝謝:)我會在10分鐘後接受你的回答.. – unbalanced 2015-03-03 07:00:09

+0

很高興幫助。快樂的編碼。 – 2015-03-03 07:01:40

1
profileListsForSearch = profileLists.Where(p => 
{ 
    if(p is Profile) return ((Profile)p).DocName.Contains(searchBar.Text)); 
    if(p is DynamicViewProfile) return ((DynamicViewProfile)p).NodeName.Contains(searchBar.Text)); 
    return false; 
}).ToList(); 

您可以檢查類型。但是,這隻意味着你的班級結構被打破了。如果你推導出來,你永遠不應該被迫明確地檢查一個類型。

相反,您可以在您的基類中有一個名爲FilterText的屬性,它由基類return DocName;和派生類return NodeName;實現。然後你的代碼看起來像這樣:

profileListsForSearch = profileLists.Where(p => p.FilterText.Contains(searchBar.Text)).ToList(); 
+0

謝謝你的解釋,但我不能改變類,因爲它來自webservice – unbalanced 2015-03-03 07:04:48