2014-08-27 204 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();