Я помещаю это в отдельный ответ, потому что ваш EDIT делает ваш вопрос действительно другим.
Я, вероятно, расширю этот ответ позже, так как я немного спешу, чтобы добраться до клиента.
Ваше редактирование означает, что вам необходимо переосмыслить типы значений, ссылочные типы и влияние var, out, const и вообще без маркировки параметров.
Давайте сначала разберемся с типами значений.
Значения типов значений находятся в стеке и имеют функцию копирования при назначении.
(Я постараюсь привести пример позже).
Если у вас нет маркировки параметра, фактическое значение, переданное методу (процедуре или функции), будет скопировано в локальное значение этого параметра внутри метода. Таким образом, метод работает не со значением, переданным ему, а с копией.
Если у вас есть out, var или const, то копирование не происходит: метод будет ссылаться на фактическое переданное значение. Для var это позволит изменить это фактическое значение, для const это не допустит. Из-за этого вы не сможете прочитать фактическое значение, но все равно сможете записать фактическое значение.
Значения ссылочных типов находятся в куче, поэтому для них не имеет значения, если у вас есть маркировка параметров out, var, const или no: когда вы что-то меняете, вы меняете значение в куче.
Для ссылочных типов вы по-прежнему получаете копию, когда у вас нет маркировки параметров, но это копия ссылки, которая все еще указывает на значение в куче.
Здесь анонимные методы усложняются: они осуществляют захват переменных.
(Барри, вероятно, может объяснить это еще лучше, но я попробую)
В вашем отредактированном случае анонимный метод будет захватывать локальную копию списка. Анонимный метод будет работать с этой локальной копией, и с точки зрения компилятора все будет просто замечательно.
Однако суть вашего редактирования - это сочетание «он работает для нормальных параметров» и «который гарантирует, что ссылка все еще указывает на живой объект всякий раз, когда выполняется анонимный метод».
Это всегда проблема со ссылочными параметрами, независимо от того, используете ли вы анонимные методы или нет.
Например, это:
procedure TMyClass.AddObject(Value: TObject);
begin
FValue := Value;
end;
procedure TMyClass.DoSomething();
begin
ShowMessage(FValue.ToString());
end;
Кто гарантирует, что когда кто-то вызывает DoSomething, что экземпляр, на который указывает FValue, все еще существует?
Ответ заключается в том, что вы должны гарантировать это сами, не вызывая DoSomething после смерти экземпляра FValue.
То же самое относится и к вашему редактированию: вы не должны вызывать анонимный метод, когда основной экземпляр умер.
Это одна из областей, где подсчет ссылок или сборщик мусора облегчают жизнь: там экземпляр будет оставаться в живых до тех пор, пока не исчезнет последняя ссылка на него (что может привести к тому, что экземпляр будет жить дольше, чем вы ожидали!) .
Итак, с вашим редактированием ваш вопрос фактически меняется с анонимных методов на последствия использования ссылочных типизированных параметров и управления временем жизни в целом.
Надеюсь, мой ответ поможет вам в этом.
- Йерун