我将其放在单独的答案中,因为您的 EDIT 使您的问题变得非常不同。
稍后我可能会扩展这个答案,因为我有点急于联系客户。
您的编辑表明您需要重新考虑值类型、引用类型以及 var、out、const 和无参数标记的影响。
让我们先做值类型的事情。
值类型的值存在于堆栈中,并具有赋值时复制的行为。(稍后我将尝试包含一个示例)。
当您没有参数标记时,传递给方法(过程或函数)的实际值将被复制到方法内该参数的本地值。因此该方法不会对传递给它的值进行操作,而是对副本进行操作。
当你有 out、var 或 const 时,不会发生复制:该方法将引用传递的实际值。对于 var,它允许更改实际值,对于 const,它不允许。对于 out,您将无法读取实际值,但仍然可以写入实际值。
引用类型的值存在于堆上,因此对于它们来说,是否有 out、var、const 或没有参数标记几乎无关紧要:当您更改某些内容时,您会更改堆上的值。
对于引用类型,当您没有参数标记时,您仍然会得到一个副本,但那是仍然指向堆上的值的引用的副本。
这就是匿名方法变得复杂的地方:它们进行变量捕获。(巴里可能会更好地解释这一点,但我会试一试)在您编辑的情况下,匿名方法将捕获列表的本地副本。匿名方法将在该本地副本上工作,从编译器的角度来看,一切都是花花公子。
但是,您编辑的关键是“它适用于普通参数”和“谁保证在执行匿名方法时引用仍然指向活动对象”的组合。
无论您是否使用匿名方法,这始终是引用参数的问题。
例如这个:
procedure TMyClass.AddObject(Value: TObject);
begin
FValue := Value;
end;
procedure TMyClass.DoSomething();
begin
ShowMessage(FValue.ToString());
end;
谁保证当有人调用 DoSomething 时,FValue 指向的实例仍然存在?答案是您必须自己保证这一点,当 FValue 的实例死亡时不调用 DoSomething。您的编辑也是如此:当底层实例死亡时,您不应该调用匿名方法。
这是引用计数或垃圾收集解决方案使生活更轻松的领域之一:实例将保持活动状态,直到对它的最后一个引用消失(这可能导致实例的寿命比您最初预期的要长!)。
因此,通过您的编辑,您的问题实际上从匿名方法变为使用引用类型参数和生命周期管理的含义。
希望我的回答可以帮助您进入该领域。
——杰伦