所以我正在从书中实施一个项目,我有点困惑为什么我需要这些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
,我意识到Product是一个列表,是p=> P.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; }
}
我常常对Lambdas在这些事情上的目的感到困惑。 p=>p.Product.ProductID == product.ProductID
是否有一些平等的东西?
我可以看到没有使用Lambdas所以我可以更多地了解它是什么简写?
我似乎无法绕过这一个,并提前感谢。
答案 0 :(得分:6)
他们是代表的简写。在您的情况下,没有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之外定义的变量(称为“bound”或“captured”变量),所以编译器必须创建一个带有字段的辅助对象来放入该变量。
对于没有绑定变量的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; }
答案 1 :(得分:2)
RemoveAll
实现有一些迭代器,它为每次迭代调用你的匿名函数。像:
iterator {
your_lambda_function(current_item);
}
p => p.Product.ProductID == product.ProductID
可以改写为:
delegate(CartLine p) { return p.Product.ProductID == product.ProductID; }
对你来说可能看起来更清楚
答案 2 :(得分:2)
下载ReSharper的试用版;它允许你从lambdas转换为委托到命名函数,只需按alt-enter并选择你想要的那个。这就是帮助我学会理解什么是什么的原因。
答案 3 :(得分:1)
不需要Lambda。您也可以使用实现相同签名的方法的名称替换它们。
答案 4 :(得分:1)
您也可以像常规一样删除它们。
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还是命名函数)可以使代码更易理解。)