Я изучаю C#.Can, я имею в виду закрытие как a construct that can adopt the changes in the environment in which it is defined.
Пример:
List<Person> gurus =
new List<Person>()
{
new Person{id=1,Name="Jon Skeet"},
new Person{id=2,Name="Marc Gravell"},
new Person{id=3,Name="Lasse"}
};
void FindPersonByID(int id)
{
gurus.FindAll(delegate(Person x) { return x.id == id; });
}
Переменная id
объявляется в пределах FindPersonByID (), но t мы все еще можем получить доступ к локальной переменной id
в анонимной функции (т.е.) delegate(Person x) { return x.id == id; }
(1) Мое понимание закрытия, корректно?
(2) Каковы преимущества, мы можем добраться от закрытий?
Да, код внутри FindPersonByID
использует закрытие с помощью параметра id
в лямбда-выражении. Строго говоря, определения замыканий немного сложнее, но на базовом уровне это правильно. Если вам нужна дополнительная информация о том, как они работают, я рекомендую вам прочитать следующие статьи
Основное преимущество замыканий - это то, что вы продемонстрировали выше. Это позволяет вам писать код более естественным, прямым образом, не беспокоясь о деталях реализации того, как генерируется лямбда-выражение (обычно)
. Рассмотрим, например, сколько кода вам нужно было бы написать без of closures
class Helper {
private int _id;
public Helper(int id) {
_id = id;
}
public bool Filter(Person p) {
return p.id == _id;
}
}
void FindPersonsByID(int id) {
Helper helper = new Helper(id);
gurus.FindAll(helper.Filter);
}
Все это просто для выражения концепции использования параметра внутри делегата.