2017-05-19 15 views
1

LINQを使用するようにコードを変更したい。ここリストでLINQを使用するとInvalidOperationExceptionが発生する

私の以前のコードでは、働いている:

// Remove unselected features 
var removedFeatures = new List<VehicleFeature>(); 
foreach(var f in v.Features) 
    if(!vr.Features.Contains(f.FeatureId)) 
    removedFeatures.Add(f); 

私はこのようにLINQにそれをリファクタリングする場合:

と、InvalidOperationException:コレクションだった

var removedFeatures=v.Features.Where(f=>!vr.Features.Contains(f.FeatureId)); 
foreach(var f in removedFeatures) 
    v.Features.Remove(f); 

私は以下の例外を取得します変更されました。列挙操作が実行されないことがあります。 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResourceリソース)

私はそれは私のコードは、リストが反復されたときにリストを変更意味を知っているが、私はこのエラーが起こった場所がわからないのですか?

+0

foreach内で同じコレクションを変更することはできません。 foreachの代わりにループを試してみてください。 – Santhosh

+0

しかし、私は反復されたリストを変更しませんでした。私が反復するリストは削除されていますが、私が修正したリストはv –

+0

の削除されたフィーチャーは実際にv.Featuresを参照しています。 removedFeaturesの変更は実際にv.Featuresを変更しています – Santhosh

答えて

0

ループの代わりにforeachループを試してください。forループ。

for (var i = 0; i < removedFeatures.Count; i++) 
{ 
     v.Features.Remove(removedFeatures[i--]); 
} 
1

あなたはToListメソッド()を使用する代わりに、照会可能の列挙コレクションを作成する必要があり

foreach(var f in removedFeatures.ToList()) 
    v.Features.Remove(f); 
+0

ありがとうございます!私はちょうど私のremovedFeaturesコレクションenumerableであることに気づいた。 ToList()を追加した後に動作します。 –

+0

私は別のコードを持っています。 Select(id => new VehicleFeature {FeatureId = id});を選択してください(id => new vf.Features.Any(f => f.FeatureId == id))。 foreach(addedFeaturesのvar f) v.Features.Add(f); ========================動作しています。 –

+0

上記のコードが機能している理由は分かりますか?それはAdd(f)を使っても問題ないですが、remove(f)を使っても問題ないのですか? –

-1

それとも

var features = new int[] {1, 2, 3, 4, 5}; 
var removedFeatures = new int[] { 1, 2, 3 }; 
features = features.Except(removedFeatures).ToArray(); 
//4, 5 
+0

lol、どのように上下しているか:) – Artyom

+0

これは単純な型でしか動作しません。あるいは、あなたがカスタムの比較関数を持っていても有効なオプションです。 – Artyom

+0

あまりにも多くの仮定( 'ToArray')をいい答えだ。 – NetMage

2
var removedFeatures=v.Features.Where(f=>!vr.Features.Contains(f.FeatureId)); 
foreach(var f in removedFeatures) 
    v.Features.Remove(f); 

removedFeaturesはリストだけでイテレータ、しなくても単純。 foreachが実行されると、基本的に「基準を満たす次のアイテムを取得します」と表示されます。 Where()が実行されるのは初めてです。したがって、最初のものが削除された場合は、v.Featuresのリストが変更されます。あなたがから削除されているリストを検討する必要はありませんので、あなたは、あなたが削除wnat項目の別のリストを作成している、ToList()を追加することにより

var removedFeatures=v.Features 
        .Where(f=>!vr.Features.Contains(f.FeatureId)) 
        .ToList(); 

関連する問題