Использование лямбды меня смущает - PullRequest
3 голосов
/ 15 декабря 2011

Итак, я реализую проект из книги, и меня несколько смущает вопрос, ПОЧЕМУ мне нужны эти лямбды.

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 НУЖДАЮТСЯ в лямбда-выражении? Я не уверен, почему я не могу использовать 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; }
}

Я, как правило, смущен целями лямбд в подобных вещах. Есть ли какой-нибудь эквивилант к p=>p.Product.ProductID == product.ProductID Я мог видеть, что я не использую Lambdas, чтобы я мог понять больше, что это сокращение для ??

Я не могу обернуть голову вокруг этого, и спасибо заранее.

Ответы [ 5 ]

6 голосов
/ 15 декабря 2011

Они являются сокращением для делегата.В вашем случае тот же код без лямбды будет выглядеть так:

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

Поскольку ваша лямбда содержит переменную, которая определена вне лямбда-выражения (называемой «связанной» или «захваченной» переменной), компилятордолжен создать вспомогательный объект с полем для помещения этой переменной.

Для лямбда-выражений без связанных переменных можно использовать статический метод:

    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; }
2 голосов
/ 15 декабря 2011

Скачать пробную версию ReSharper; это позволяет вам преобразовывать лямбды в делегаты в именованные функции и тому подобное, просто нажав alt-enter и выбрав, какую вы хотите. Это то, что помогло мне научиться понимать, что к чему.

2 голосов
/ 15 декабря 2011

RemoveAll Реализация имеет своего рода итератор, который вызывает вашу анонимную функцию для каждой итерации.Например:

iterator {
    your_lambda_function(current_item);
}

И p => p.Product.ProductID == product.ProductID можно переписать как:

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

, что может показаться вам более понятным

1 голос
/ 15 декабря 2011

Вы также можете удалить их как обычные.

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

Я думаю, что лямбда лучше.(на самом деле, просмотр этого кода должен продемонстрировать, почему использование функторов (будь то лямбды или именованные функции) делает код намного более понятным).

1 голос
/ 15 декабря 2011

Лямбды не требуются. Вы также можете заменить их именем метода, который реализует ту же сигнатуру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...