0

のセットをループすることに問題がありXElementsます。動作は私が期待したものではありません。

私のコードの短い書き直されたバージョンなので、私の問題を簡単に得ることができます(C#のコンソールアプリ)

IEnumerable<XElement> q = from c in xml.Descendants(aw + "wd") 
                          where (....) 
                          select c;    
...

//--------------------------------------------------------------------    
IEnumerable<XElement> currRow = q.OrderBy(yyy => (int)yyy.Attribute("t"));

int xValue = 10;

currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);
xValue = 20; 
//Here, the currRow gets a new value automatically. I don't want this!


//--------------------------------------------------------------------
//This is want i want to acheive: 

IEnumerable<XElement> currRow = q.OrderBy(yyy => (int)yyy.Attribute("t")); 

int xValue = 10;

currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);
//do somthing with currRow

xValue = 20; 
currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);
//do somthing else with currRow

xValue = 30; 
currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);
// etc....

何か案は?

4

5 に答える 5

1

.where呼び出して結果を currRow に割り当てるたびに、セットを制限しています。

だから一行目

 currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);

t < 10 のすべての要素に制限されます。

 xValue = 20;
 currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);

Where への最初の呼び出しとその後の currRow への代入により、すべての要素 i currRow の値が10未満であるため、まったく同じ結果が得られます。

あなたはこれを行うことができます

   const int stepSize = 10;
   var iterations = 3
    for(var i = 0;i<iterations;++i){
         var curr = currRow.Where(yyy => (int)YYY.Attribute("t") >= i * stepSize 
                                       && (int)YYY.Attribute("t") < (i+1) * stepSize);
         //do sometihng with curr
    }

コメント後に編集

列挙子を使用すると where が評価されます

xValue = 10;
currRow = currRow.Where(yyy => (int)YYY.Attribute("t") > xValue);

foreach(var elem in currRow){
    //this iterates all elements with t < 10;
}

xValue = 20; 
foreach(var elem in currRow){ //notice that currRow hasn't been reassigned
    //this iterates all elements with t < 20;
}

設計によるこの動作を回避するオプションが必要です

xValue の再割り当てを控えるか、次のようにクエリを実行することができます

var list = currRow.Where(yyy => (int)YYY.Attribute("t") > xValue).ToList();

最後に気づく.ToList()

于 2012-11-01T10:26:11.383 に答える
0

xValuewhereステートメントのラムダ式に取り込まれているようです。単に一定の値を提供しないのはなぜですか?

currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < 20);
//do somthing with currRow
currRow = currRow.Where(yyy => (int)yyy.Attribute("t") < 10);
//do somthing with currRow

また、最小のフィルター値から始めないでください< 10。結果をcurrRow変数に代入すると、結果はすでに 未満20および未満であるため、他のフィルターは効果がありません30

于 2012-11-01T10:10:26.650 に答える
0

現時点では、テストするマシンに VS はありませんが、遅延読み込みが原因である可能性があります。

LINQ 式で使用するxValueと、値ではなく参照によって渡されます。これは、LINQ 式を列挙するまでは、変更するたびに、xValue無意識のうちに LINQ 式も変更していることを意味します。

この投稿 ( LINQ 式の値は参照によって渡されますか? ) は、私の理論をサポートしているようです。select ステートメントを次のように変更してみてください。おそらく、期待どおりの動作が得られるでしょう。

currRow = currRow.Where( yyy => ( int ) yyy.Attribute( "t" ) < xValue ).Select( x => x );
于 2012-11-01T11:44:22.587 に答える
0
IEnumerable<XElement> currRow = q.OrderBy(yyy => (int)yyy.Attribute("t")); 

int xValue = 10;    

var abc = currRow.Where(yyy => (int)yyy.Attribute("t") < xValue);
//Do something with abc , abc is IEnumerable<XElement> list;
于 2012-11-01T10:06:18.060 に答える
0
currRow.Where(...)

使用時に実行されるクエリを作成します。
結果を直接取得したい場合 (そして、参照やクエリを台無しにするのを省略したい場合) は、それをリストに変換します。

currRow.Where(...).ToList()

これが必要な理由は、where ステートメントで使用する値がクエリ内の定数としてではなく、使用した変数への参照として認識されるためです。変数を変更すると、クエリの結果が変わる可能性があります。
呼び出すと.ToList()、その瞬間の変数の値でクエリが実行されます。クエリで使用される変数の値が変更されたときに、結果を作成するために作成されたクエリが結果に影響を与えないように、結果は収集され、「永続的」です。

于 2012-11-01T10:06:39.230 に答える