Lambda的用法让我很困惑
本文关键字:用法 Lambda | 更新日期: 2023-09-27 18:17:58
所以我正在实施一个项目从一本书,我有点困惑,为什么我需要这些lambdas。
public class Cart
{
private List<CartLine> lineCollection = new List<CartLine>();
public class CartLine
{
public Product Product { get; set; }
public int Quantity { get; set; }
}
public void RemoveLine(Product product)
{
lineCollection
.RemoveAll(p => p.Product.ProductID == product.ProductID);
}
}
为什么我需要.RemoveAll(p=> p.Product.ProductID == product.ProductID)
?它只是与.RemoveAll
需要一个lambda表达式吗?我不知道为什么我不能使用this.Product.ProductID
,我意识到产品是一个列表,是p=> P.Product
做某种迭代和比较值,直到它找到它需要什么?
Product定义在
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
我通常对lambda在这些事情中的目的感到困惑。是否有一些与p=>p.Product.ProductID == product.ProductID
相对应的我可以看到不使用lambda,所以我可以更多地理解它是什么缩写??
我似乎无法理解这个问题,提前感谢。
它们是委托的简写。在您的示例中,没有lambdas的相同代码看起来像这样:
public void RemoveLine( Product product )
{
var helper = new RemoveAllHelper();
helper.product = product;
lineCollection.RemoveAll( helper.TheMethod );
}
class RemoveAllHelper
{
public Product product;
public bool TheMethod( CartLine p ) { return p.Product.ProductID == product.ProductID; }
}
因为你的lambda包含一个在lambda之外定义的变量(称为"绑定"或"捕获"变量),编译器必须创建一个带有字段的helper对象来将该变量放入。
对于没有绑定变量的lambdas,可以使用静态方法:
public void RemoveLine( Product product )
{
lineCollection.RemoveAll( TheMethod );
}
public static bool TheMethod( CartLine p ) { return p.Product.ProductID == 5; }
当唯一的绑定变量是this
时,则可以在同一对象上使用实例方法:
public void RemoveLine( Product product )
{
lineCollection.RemoveAll( this.TheMethod );
}
public bool TheMethod( CartLine p ) { return p.Product.ProductID == this.targetProductID; }
RemoveAll
实现有某种迭代器,每次迭代调用您的匿名函数。如:
iterator {
your_lambda_function(current_item);
}
和p => p.Product.ProductID == product.ProductID
可以重写为:
delegate(CartLine p) { return p.Product.ProductID == product.ProductID; }
看起来更清晰一些
下载ReSharper的试用版;它允许您将lambda转换为指定函数的委托,只需按alt-enter键并选择所需的委托。
你也可以像平常一样删除它们。
public void RemoveLine(Product product) {
for (var i = 0; i < lineCollection.Count;) {
if (lineCollection[i].Product.ProductID == product.ProductID) {
lineCollection.RemoveAt(i);
} else { ++i; }
}
}
我认为lambda更好。(实际上,看看这段代码就会明白为什么使用函函数(无论是lambdas还是命名函数)会让代码更容易理解)。
不需要lambda。您也可以将它们替换为实现相同签名的方法名。