2013-02-14 2 views
-1

Я думал, что это возможно с .Where().Есть ли способ сделать это в одном запросе LINQ?

public void RemoveExpiredEntries(List<CartEntry> entries) 
{ 
    foreach (var entry in entries.Where(x => x.IsExpired())) 
    { 
     entry.Item.QuantityInCarts -= entry.Quantity; 
    } 
    entries.RemoveAll(x => x.IsExpired()); 
} 
+2

Планируете ли вы изменить код? Теперь он значительно отличается от исходного кода ... если бы я опубликовал ответ, который я начал писать, многие из них были бы признаны недействительными. –

+0

В чем смысл изменения количества предметов, а затем их удаления? Они упоминаются где-то в другом месте? –

+0

@JonSkeet Исходный код не скомпилирован. Я общался с ним и в итоге опубликовал неправильную версию. –

ответ

1

Я не вижу (читаемого) решения, где вы можете сделать это с помощью одного заявления. То, что вы делаете, не является «запросом», это операция (или две) для некоторых элементов, которые уже найдены с использованием Where.

я бы, вероятно, сделать следующее:

var expiredEntries = entries.Where(x => x.IsExpired()).ToArray(); 
foreach (var entry in expiredEntries) 
{ 
    entry.Item.QuantityInCarts -= entry.Quantity; 
} 
entries.RemoveAll(expiredEntries); 

Или

foreach (var entry in entries.Where(x => x.IsExpired()).ToArray()) 
{ 
    entry.Item.QuantityInCarts -= entry.Quantity; 
    // remove works here, because it created an array with expired items. 
    entries.Remove(entry); 
} 

которые оба на самом деле не очень отличается от того, что вы делаете. Замена foreach на .ForEach больше похожа на linq, но не сильно меняет его.


Вы можете также рассмотреть герметизирующего операция atomar «RemoveEntry» внутри класса, который содержит и управляет список:

class Cart 
{ 
    List<CartEntry> entries; 

    public void RemoveEntry(CartEntry entry) 
    { 
     entry.Item.QuantityInCarts -= entry.Quantity; 
     entries.Remove(entry); 
    } 

    public void RemoveExpiredEntries() 
    { 
     foreach (var entry in entries.Where(x => x.IsExpired()).ToArray()) 
     { 
      RemoveEntry(entry); 
     } 
    } 
} 
3

Вы не можете изменить коллекцию при перечислении его. Поэтому выражение LINQ не может применяться.

LIN * Q * предназначен для поддержки запросов, которые по определению не изменяют их источник.

0

Только я вижу, что вы делаете это с одной строкой, но это не самое приятное для чтения.

public void RemoveExpiredEnties(List<CartEntries> entries) 
    { 
     (entries.Where(e => e.IsExpired).ToList()).ForEach(item => entries.Remove(item)); 
    } 
Смежные вопросы