我有这样的域类:
public class DomainClass
{
public virtual string name{get;set;}
public virtual IList<Note> Notes{get;set;}
}
如何从IList<Note>
删除项目?如果它是List,我可以这样做,但它必须是IList
,因为我使用Nhibernate作为我的持久层。
理想情况下,我想在我的域类中使用这样的方法:
public virtual void RemoveNote(int id)
{
//remove the note from the list here
List<Note> notes = (List<Note>)Notes
notes.RemoveAll(delegate (Note note)
{
return (note.Id = id)
});
}
但我无法将IList
强制转换为List
。这周围有更优雅的方式吗?
答案 0 :(得分:29)
您可以过滤掉您不想要的项目,并创建一个只包含您想要的项目的新列表:
public virtual void RemoveNote(int id)
{
//remove the note from the list here
Notes = Notes.Where(note => note.Id != id).ToList();
}
答案 1 :(得分:10)
Edit2:此方法不需要转换为 List
!
foreach (var n in Notes.Where(note => note.Id == id).ToArray()) Notes.Remove(n);
...或
Notes.Remove(Notes.Where(note => note.Id == id).First());
第一个是最好的
如果没有id
的注释,则第二个将抛出异常。
编辑:感谢Magnus和rsbarro显示我的错误。
答案 2 :(得分:2)
您可以手动编码。天真的实现是O(n * k),其中n是列表中的项目数,k是要删除的项目数。如果你想删除一个项目,那就快了。
但是如果你想删除很多项,那么对于许多O(n^2)
实现(包括IList<T>
,原生实现变为List<T>
,不知道NHibernate的列表是如何表现的)你需要写一个需要更多代码才能获得O(n)
RemoveAll
实现。
旧答案中的一种可能的实施方式:List, not lose the reference
这种实现的技巧是将保留的项目移动到O(n)中列表的开头。然后它继续删除列表的最后一项(通常为O(1),因为没有元素需要移动),因此截断变为O(n)总计。这意味着整个算法是O(n)。
答案 3 :(得分:2)
如果您可以更改数据结构,我建议使用Dictionary
。你可以选择:
public class DomainClass
{
public virtual string name{get;set;}
public virtual IDictionary<int, Note> Notes {get; set;}
//Helper property to get the notes in the dictionary
public IEnumerable<Note> AllNotes
{
get
{
return notes.Select (n => n.Value);
}
}
public virtual void RemoveNote(int id)
{
Notes.Remove(id);
}
}
如果ID不是唯一的,请改用IDictionary<int, IList<Note>>
。
答案 4 :(得分:1)
请考虑,在某些情况下,最好避免公共虚拟,请以这种方式使用template method模式:
public void Load(IExecutionContext context)
{
// Can safely set properties, call methods, add events, etc...
this.Load(context);
// Can safely set properties, call methods, add events, etc.
}
protected virtual void Load(IExecutionContext context)
{
}
答案 5 :(得分:0)
您可以收到一系列要删除的项目。然后将它们从循环列表中删除。 看看这个样本:
IList<int> list = new List<int> { 1, 2, 3, 4, 5, 1, 3, 5 };
var valuesToRemove = list.Where(i => i == 1).ToArray();
foreach (var item in valuesToRemove)
{
list.Remove(item);
}