2014-08-27 205 views
3

我一直在用WPF和MVVM開發一個項目一段時間。在我的項目的一部分中,我使用下面的代碼來關閉一個窗口。代碼的作品,但是,我不明白的代碼背後的邏輯。我的代碼是:在WPF MVVM中關閉一個窗口

App.Current.Windows.Cast<Window>() 
    .Where(win => win is DisplayView).FirstOrDefault() 
    .Close(); 

爲什麼需要FirstOrDefault()?

+0

首先或默認是從集合中獲取第一個項目的安全方法。 – kidshaw 2014-08-27 21:30:27

+0

你調用返回枚舉類型的地方,意味着可以包含很多元素,然後你只選擇第一個。將其替換爲FirstOrDefault(win => win是DisplayView).Close() – Maximus 2014-08-27 21:32:45

回答

0

我們分了它:

  • App.Current:獲得運行中的WPF應用程序(應該是Application.Current我認爲)
  • .Windows.Cast<Window>():獲取窗口的列表中,但因爲這是一個類型化集合使其強烈鍵入使用所有的LINQ運算符
  • .Where(win => win is DisplayView):LINQ運算符篩選窗口列表,只保留那些類型DisplayView
  • .FirstOrDefault():得到這個集合的還是第一個元素null如果沒有
  • .Close():關閉,我們得到的窗口,這是很危險的,因爲它會與NullReferenceException吹,如果沒有被發現

這裏是一個更安全的方法:

3

它只是使用了一些LINQ的IEnumerable<T>擴展從集合中給定類型匹配得到的第一個項目,然後調用Close。它實際上是不必要的冗長,因爲這:

App.Current.Windows.Cast<Window>() 
    .Where(win => win is DisplayView) 

或多或少等價於:

App.Current.Windows.OfType<DisplayView>() 

此外,調用FirstOrDefault()其次是「關閉」是有點傻。 FirstOrDefault與First類似,不同之處在於它返回null,而不是在沒有元素的情況下拋出異常 - 但在這種情況下,它會拋出異常,因爲您會在空對象上調用「Close」。


所以我會寫這樣的:

App.Current.Windows.OfType<DisplayView>().First().Close(); 

如果您想驗證是否存在實際上是一個DisplayView實例,並防止在這種情況下的例外,那麼你可以這樣做:

var displayViews = App.Current.Windows.OfType<DisplayView>(); 
if (displayViews.Any()) 
    displayViews.First().Close();