2014-11-25 3 views
1

Мне нужно удалить данные из ICollection, если идентификатор коллекции находится в списке идентификаторов.Петля через ICollection и значение null

То, что я до сих пор:

foreach (var notSelectedToolId in notSelectedToolIds) 
    { 
     for (int i = 0; i < matchingHoleInfoVm.ToolHeader.Count; i++) 
     { 
      if (matchingHoleInfoVm.ToolHeader.ElementAt(i).ToolID == notSelectedToolId) 
      { 
       matchingHoleInfoVm.ToolHeader.ElementAt(i) = new ToolHeaderViewModel(); 
      } 
     } 
    } 

Я получаю ошибку: "This expression cannot be used as an assignment target".

Как это сделать?

ответ

4

Вы не можете, в основном - не с толькоICollection (или даже ICollection<T>). Ни один из них не позволяет заменить существующий элемент на новый.

С IList<T>, это довольно легко:

var list = matchingHoleInfoVm.ToolHeader; 
for (int i = 0; i < list.Count; i++) 
{ 
    if (list[i].ToolID == notSelectedToolId) 
    { 
     list[i] = new ToolHeaderViewModel(); 
    } 
} 

В большинстве случаев, когда вы уже получили ICollection<T>, вы увидите, что уже реализует IList<T>. Если это не так, вам нужно внимательно посмотреть, что на самом деле коллекция равна, и подумайте, имеет ли смысл «заменить на тот же индекс» даже смысл. (Если это HashSet<,>, например, вы можете просто удалить существующий элемент и добавить новый ...)

EDIT: Если вам нужно только удалить элементы, вы можете просто использовать метод Remove:

var itemsToRemove = collection.Where(c => c.ToolID == notSelectedToolId).ToList(); 
           .ToList(); 
foreach (var item in itemsToRemove) 
{ 
    collection.Remove(item); 
} 

Кроме того, вам не нужны вложенные циклы - вы можете использовать что-то вроде:

var itemsToRemove = collection.Where(c => notSelectedToolIds.Contains(c.ToolID)) 

найти все из них, чтобы удалить за один проход (а затем удалить их, как указано выше).

+0

Любой подход на основе LINQ? – haim770

+2

@ haim770: Нет. LINQ предназначен для запросов, а не для изменения коллекций. –

+0

Я знаю, я имел в виду запрос Linq, который закончится как новый «List ». – haim770

0

Какого типа ToolHeader

После кода неверен:

matchingHoleInfoVm.ToolHeader.ElementAt(i) = new ToolHeaderViewModel(); 

ElementAt (я) является методом расширения, который предназначен для возвращения значения по данному индексу I, особенно в случай, когда индексатор не реализован. Вы можете достичь возможность путем внедрения индексатор в типе для ToolHeader, проверьте следующее Creating indexer

После этого вы можете позвонить:

matchingHoleInfoVm.ToolHeader[i] = new ToolHeaderViewModel(); 
+0

Если это не настраиваемый тип, а предопределенный тип, например ICollection , то, как предложил Jon, вы должны создать из него такой, как List , а затем использовать неявный индекс для замены элемента при заданном индексе i –

1

Вы можете применить фильтр к matchingHoleInfoVm.ToolHeader с помощью LINQ к верните новый список. Что-то вроде

var toolsExlcuded = matchingHoleInfoVm.ToolHeader.Where(x => !notSelectedToolIds.Contains(x.ToolId)).ToList(); 
+0

You может * удалить * (используя метод 'Remove') - вы просто не можете * заменить *. –

+0

Действительно. Виноват. Удален этот бит. –

Смежные вопросы