Jordan
Jordan

Reputation: 2758

Lambda usage is confusing me

So I am implementing a project from a book and I am somewhat confused as to WHY i need these 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);
    }
}

Why do I need .RemoveAll(p=> p.Product.ProductID == product.ProductID)? Does it just have to do with .RemoveAll NEEDING a lambda expression? I'm not sure why I can't use this.Product.ProductID, I realize Product is a list, is p=> P.Product doing some sort of iteration and comparing the values till it finds what it needs?

Product is defined in

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; }
}

I'm generally confused as to the purpose of Lambdas in these kinds of things. Is there some equivelant to p=>p.Product.ProductID == product.ProductID I could see not using Lambdas so I could understand more what it is shorthand for??

I can't seem to wrap my head around this one, and thanks in advance.

Upvotes: 4

Views: 404

Answers (5)

M.Babcock
M.Babcock

Reputation: 18965

Lambdas are not required. You could just as well replace them with the name of a method that implements the same signature.

Upvotes: 1

Dax Fohl
Dax Fohl

Reputation: 10781

Download a trial version of ReSharper; it lets you convert from lambdas to delegates to named functions and such just by pressing alt-enter and choosing which one you want. That is what helped me learn to understand what was what.

Upvotes: 2

Dax Fohl
Dax Fohl

Reputation: 10781

You can also remove them like regular.

public void RemoveLine(Product product) {
    for (var i = 0; i < lineCollection.Count;) {
        if (lineCollection[i].Product.ProductID == product.ProductID) {
            lineCollection.RemoveAt(i);
        } else { ++i; }
    }
}

I think the lambda is nicer though. (in fact, looking at this code should demonstrate why using functors (be they lambdas or named functions) makes for much more understandable code).

Upvotes: 1

Fyodor Soikin
Fyodor Soikin

Reputation: 80915

They are a shorthand for a delegate. In your case, the same code without lambdas would look like this:

    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; }
    }

Because your lambda contains a variable that is defined outside of the lambda (called "bound" or "captured" variable), the compiler has to create a helper object with a field to put that variable into.

For lambdas without bound variables, a static method may be used:

    public void RemoveLine( Product product )
    {
        lineCollection.RemoveAll( TheMethod );
    }

    public static bool TheMethod( CartLine p ) { return p.Product.ProductID == 5; }

When the only bound variable is this, then an instance method on the same object may be utilized:

    public void RemoveLine( Product product )
    {
        lineCollection.RemoveAll( this.TheMethod );
    }

    public bool TheMethod( CartLine p ) { return p.Product.ProductID == this.targetProductID; }

Upvotes: 6

zerkms
zerkms

Reputation: 255115

RemoveAll implementation has some sort of iterator which calls your anonymous function for each iteration. Like:

iterator {
    your_lambda_function(current_item);
}

And p => p.Product.ProductID == product.ProductID can be rewritten as:

delegate(CartLine p) { return p.Product.ProductID == product.ProductID; }

which could look a bit clearer for you

Upvotes: 2

Related Questions