我需要显示满足某些条件的项目。
public BindableCollection<BaseTreeItemViewModel> TreeItems
{
get
{
if (_logicTest)
return (BindableCollection<BaseTreeItemViewModel>)_treeItems.Where(n => _logicTest);
else
return _treeItems;
}
set
{
_treeItems = value;
NotifyOfPropertyChange(() => TreeItems);
}
}
事实上在Where
子句中会有不同的测试(n.Header == "ABC"
),但即使对于_logicTest
它也不起作用,我们知道true
在启动时与Where
对齐。
_treeItems
包含大约20个元素,对于_logicTest=false
,它们都返回。另一方面,_logicTest=true
函数返回空集合。
错误在哪里?
提前感谢您的帮助。
修改
作为@ Robert.S suggested,我使用过:
return new BindableCollection<BaseTreeItemViewModel>(_treeItems.Where(n => _logicTest));
它有效。感谢。
答案 0 :(得分:3)
什么是_logicTest
?一个属性?如果是这样,它可能会在评估集合时发生变化。此外,Where
的返回值为IEnumerable<T>
。只有在使用集合时才会评估实际值(例如,在foreach循环中)。
您可以尝试在ToList()
的末尾添加ToArray()
或Where
。这样就可以立即评估集合,并且可以看到在执行getter的时候是否真的没有项目。
另一个选项是VS调试器。在监视表中,您可以使用小刷新图标评估集合。这样你也可以看到真实的&#34;项目
但是如果您稍后使用该集合(例如在foreach循环中)并且_logicTest
不再是真的,则该集合可能为空。
这是一个简单的例子:
class Program
{
static bool _logicTest = false;
static int[] items = new int[] { 1, 2, 3 };
static void Main(string[] args)
{
_logicTest = true;
var foo = items.Where(n => _logicTest);
_logicTest = false;
Console.WriteLine(foo.Count());
_logicTest = true;
Console.WriteLine(foo.Count());
}
}
输出将是: 0 3
在上面的示例中,Count()
将评估集合以确定其大小。您可以看到_logicTest
的值在此时评估,而不是在调用Where
时评估。
您案例的可能解决方法是本地变量:
get
{
bool logicTest = _logicTest;
if (logicTest)
return (BindableCollection<BaseTreeItemViewModel>)_treeItems.Where(n => logicTest);
else
return _treeItems;
}
局部变量不会改变。但是您应该将属性值存储在另一个变量中。如果您在_logicTest
为假时访问该属性,则会遇到同样的问题。
以上是解决方法的上述示例:
class Program
{
static bool _logicTest = false;
static int[] items = new int[] { 1, 2, 3 };
static void Main(string[] args)
{
_logicTest = true;
var foo = items.Where(n => _logicTest);
var bar = Items;
_logicTest = false;
Console.WriteLine(foo.Count());
Console.WriteLine(bar.Count());
_logicTest = true;
Console.WriteLine(foo.Count());
Console.WriteLine(bar.Count());
}
static IEnumerable<int> Items
{
get
{
bool logicTest = _logicTest;
return items.Where(n => logicTest);
}
}
}
输出为0 3 3 3