你能解释一下下面的代码:
private static List<Post> _Posts;
public static Post GetPost(Guid id)
{
return _Posts.Find(delegate(Post p)
{
return p.Id == id;
});
}
通过这种方式在通用列表中找到对象有什么意义?他可以简单地重复列表。
这个委托方法如何为列表的每个元素调用?
注意:如果这有一个通用名称,您可以更新我的问题标题吗?
谢谢!
答案 0 :(得分:19)
你可以在列表中进行迭代,你可以将问题中的代码视为概念上与以下内容相同:
private static Post GetPost(Guid id)
{
Post p = default(Post);
foreach (Post post in _Posts)
{
if (post.Id == id)
{
p = post;
break;
}
}
return p;
}
编写代码片段所需的代码更少,重要的是,您现在正在说出您想要找到的内容而不是如何找到它:
private static Post GetPost(Guid id)
{
return _Posts.Find(delegate(Post p)
{
return p.Id == id;
});
}
在C#3.0中,可以使用所谓的“lambda expression”进一步缩短:
private static Post NewGetPost(Guid id)
{
return _Posts.Find(p => p.Id == id);
}
使用最少量的可读代码来实现相同的目标,使得代码的编写者和读者都更加满意。
答案 1 :(得分:7)
他正在使用匿名代表。他本来可以使用lambda expression代替:
Posts.Find(p => p.Id == id)
此外,在这种情况下,对方法中列表的包装访问不会实现任何效果,并且会将列表的元素公开给外部调用者。这是不好的做法。
答案 2 :(得分:3)
Predicate<T>
返回true。它本质上是一个快捷方式,因此您不必遍历列表。 List<T>.Find(Predicate<T>)
也可能有一些内置的优化。 delegateInstance(arg1,arg2);
答案 3 :(得分:1)
如果您使用的是C#3.0或更高版本,则可以使用Linq在列表中快速查找对象。
public static Post GetPost(Guid id)
{
return (from p in _Posts
where p.Id == id
select p).First();
}
答案 4 :(得分:1)
List.Find(谓词匹配)不是LINQ扩展方法,因为这个方法自2.0以来一直在框架中,如MSDN所示。 其次,使用Find()没有任何问题。它往往比其替代品更具可读性:
经典:
public static Post GetPost(Guid id)
{
bool found = false;
foreach(post in _Posts)
{
if post.Id == id return post;
}
return default(Post);
}
LINQ:
public static Post GetPost(Guid id)
{
var post = (
from p in _Posts
where p.Id = id
select p
).FirstOrDefault();
}
使用List.Find()会立即告诉您正在寻找一个项目,而另一个则必须遵循逻辑来确定这一点。 Find()基本上将迭代封装在列表项上。如果您在Post类上有public bool HasId(Guid id)
的方法,那么您可以编写
_Post.Find(post.HasId(id));