Как делегат получает свои аргументы? - PullRequest
2 голосов
/ 02 декабря 2011

Вот пример использования класса коллекции List:

List<int> list = new List<int>();

List<int> evenNumbers = list.FindAll(delegate (int i)
{
return (i % 2) == 0;
});

Я часто задавался вопросом, как сам делегат, переданный FindAll (), вызывается один раз для каждого элемента в списке.

Это также приводит к другому вопросу, из фрагмента кода, с которым я сейчас работаю.Он использует лямбда-выражение вместо прямого делегата:

    class SampleViewModel : ViewModelBase
    {
        private int quantitySaved;
        public int QuantitySaved
        {
            get { return quantitySaved; }
            set
            {
                if (quantitySaved != value)
                {
                    quantitySaved = value;
                    NotifyPropertyChanged(p => QuantitySaved);
                }
            }
        }

      //class continues below....
    }

Класс ViewModelBase выглядит следующим образом (сокращение для краткости):

public abstract class ViewModelBase : DependencyObject, INotifyPropertyChanged 
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void NotifyPropertyChanged<T>(Expression<Func<ViewModelBase, T>> property)
    {
        MvvmHelper.NotifyPropertyChanged(property, PropertyChanged);
    }
}

Разрешение 'p' в лямбде-выражении SampleViewModelв ViewModelBase, когда установлено свойство QuantitySaved, но как это разрешение на самом деле работает во время выполнения?

1 Ответ

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

Это, безусловно, 2 отдельных вопроса.

Параметры делегатов

Типы делегатов всегда указывают все параметры и возвращаемые типы.
Метод FindAll имеет следующую подпись :
public List<T> FindAll(Predicate<T> match).
Predicate<T> является делегатом со следующей подписью :
public delegate bool Predicate<in T>(T obj).

Когда FindAll вызывает предикат, он должен предоставить T obj, например: match(item), который вернет bool.

Лямбда-выражения

Лямбда-выражения - это действительно классная особенность .NET 4. Они очень отличаются от лямбда-функций, хотя синтаксис идентичен !

По сути, когда вы пишете лямбда-функцию, она компилируется так же, как и любой другой код.Однако когда вы пишете лямбда-выражение, компилятор фактически генерирует набор метаданных , который полностью описывает код.Обычно код никогда не выполняется.

Это очень полезно в сценариях, таких как событие PropertyChanged, потому что это событие должно знать имя свойства, а не только значение.Лямбда-выражение может быть проанализировано, и оно будет указывать, что изменяемое свойство равно "QuantitySaved".

Использование лямбда-выражений позволяет писать строго типизированный код, но позволяет анализировать, а не выполнять этот код.Это отличная особенность языка и обеспечивает множество замечательных функций, таких как LINQ to SQL, но, безусловно, сложно понять!

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