所以我一直生活在黑暗的时代,迭代我的数据,找到我感兴趣的老式方式,但这个项目我认为我应该让事情更优雅,并使用LINQ,我知道它可以是用过,但事情并没有完全点击。
所以我有两个简单的ObservableCollections,我想从其中一个中提取所有数据,匹配另一个当前所选项目。对象非常简单......
public class foo
{
//....
public string barID{ get; set; }
//....
}
public class bar
{
public string ID { get; set; }
//....
}
所以在我的代码中我有选择的foo,我想要创建一个具有匹配barID的所有条的集合...
ObservableCollection<bar> bars =
from data in fooCollection
where data.barID == barCollection.SelectedItem.ID
select data;
所以我根据我在网上找到的LINQ的语法尝试了这个,但这会抛出一个无法隐式地将IEnumerable强制转换为ObservableCollection的编译错误。所以我试过......
ObservableCollection<bar> bars =
(ObservableCollection<bar>)
(from data in fooCollection
where data.barID == barCollection.SelectedItem.ID
select data);
编译但会抛出运行时错误...
Unable to cast object of type
'WhereEnumerableIterator`1[TestProj.bar]' to type
'System.Collections.ObjectModel.ObservableCollection`1[TestProj.bar]'.
所以我确信我可以在事后投射对象或做其他事情,但我一直在寻找尽可能优雅的解决方案,所以有点帮助将这个简单的LINQ语句放在一起将不胜感激。此外,对幕后发生的事情的简单解释将极大地帮助我理解一些LINQ基础知识。
答案 0 :(得分:6)
您只需使用ObservableCollection constructor。
IEnumerable<bar> barEnumerable =
from data in fooCollection
where data.barID == barCollection.SelectedItem.ID
select data;
ObservableCollection<bar> bars = new ObservableCollection<bar>(barEnumerable);
基本上是:
IEnumerable<bar> barEnumerable =
fooCollection.Where(data => data.barID == barCollection.SelectedItem.ID);
答案 1 :(得分:2)
转换会更改表达式的类型,如果表达式确实是该类型,它将起作用。
考虑class Customer : Person
Customer c = new Customer();
Person p = c; //no problem; this is an implicit up-cast (from child to parent)
Customer c2 = p; //compiler doesn't allow because
//p may refer to a Person instance that isn't a Customer
Customer c3 = (Customer) p; //we certify to the compiler that p is referencing
//a Customer instance, and we take responsibility
//for an exception if we are wrong.
// this is a down-cast (from parent to child)
Customer cSafe = p as Customer; //safe down-cast, we get a null in cSafe if we are wrong
由于可能存在例外情况,因此在我的代码中,向下转换极为罕见。让我们花一点时间来感谢Generics让这成为可能。好的,转换:
转换从旧实例创建所需类型的新实例。
Customer c4 = new Customer(p); //conversion constructor
Customer c5 = p.ToCustomer(); //conversion method
Customer c6 = (Customer) p; // if defined, implicit conversion. Otherwise, casting
// yes, casting and implicit conversion are the same syntax
// terribly confusing.
我们从异常消息中知道查询返回的实例是WhereEnumerableIterator<TestProj.bar>
。
此结果实例不是数组,不是List<T>
,而不是ObservableCollection<T>
。强制转换不起作用,因为ObservableCollection<T>
不会从WhereEnumerableIterator<T>
继承。如果您需要ObservableCollection<T>
,则需要转换。
在语法后面,该查询调用Enumerable.Where
(msdn),返回IEnumerable<T>
。从该类型转换为所需类型的最简单方法是使用ObservableCollection<T>
{{1}}。
答案 2 :(得分:-4)
您只需使用“var”作为条形类型:
var bars = from data in fooCollection
where data.barID == fooCollection.SelectedItem.ID
select data;