1

だから私は自分のデータを反復処理し、昔ながらの方法で興味のあるものを見つけるという暗黒時代に生きてきましたが、このプロジェクトでは物事をよりエレガントにし、使用できることがわかっているLINQを使用する必要があると考えましたが、物事は完全にクリックしていません。

したがって、2 つの単純な ObservableCollections があり、そのうちの 1 つから現在選択されている他のアイテムと一致するすべてのデータを取得したいと考えています。オブジェクトは非常にシンプルです...

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 の基本を理解するのに非常に役立ちます。

4

3 に答える 3

6

ObservableCollection コンストラクターを使用するだけです。

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);
于 2012-05-16T20:12:18.010 に答える
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.Wheremsdn)を呼び出しており、これは。を返しますIEnumerable<T>。その型から目的の型に変換する最も簡単な方法は、のコンストラクターを使用することですObservableCollection<T>

于 2012-05-16T20:56:13.463 に答える
-4

バーのタイプとして単純に「var」を使用できます。

var bars = from data in fooCollection
where data.barID == fooCollection.SelectedItem.ID
select data;
于 2012-05-16T20:13:08.990 に答える