【问题标题】:Is it possible for a managed local variable to transparently "travel to" another local scope?托管局部变量是否可以透明地“移动到”另一个局部范围?
【发布时间】:2011-11-10 13:49:17
【问题描述】:

这个问题与my other one有关,希望能从中得到一些想法:

本地托管变量(记录、接口……)是否有可能在不使用任何显式 out/var 参数或结果值的情况下在本地范围内运行并“移动到”另一个范围?

对不起,如果这听起来很奇怪,但这将允许我在 调用 方法中创建一个托管对象,该对象只会在 调用 方法结束时被销毁,而不是它是在其中创建的,而整个过程对调用者是完全透明的(这是主要目标)。调用者不必声明任何东西。

第一个 hacky 想法来了:

(错误)为匿名方法使用自动创建的包装对象并将数据附加到它。我的假设是:这个对象是在调用者本地范围内创建的,在被调用者本地范围内存在(因此被调用者可以将数据附加到它),并且一直存在到调用者的end;。

是否可以将数据附加到此包装对象?除了hackyness:它有任何工作机会吗?

编辑:这个问题的更简单的措辞可能是:“如何在不使用任何参数或函数结果的情况下从函数传递结果值?”

Edit2:写一些代码让我怀疑我是否应该放手:

function TForm1.L<T>(Func: TFunc<T>):T;
var
  Value: T;
begin
  Result := Func;

  // now attach something to the anon wrapper of Func
end;

function TForm1.O<T>(Value: T): T;
begin
  Result := T;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  List: TList;
begin
  for Item in L(O<TList>(List)) do
  begin

  end;

  // List should be destroyed here
end;

我想我应该。

【问题讨论】:

  • 您使用变量捕获的想法会奏效,但听起来它比仅传递参数更复杂和不透明。对于您的方式,您需要传递 anon func。这真的有什么帮助。
  • "How to pass a result value from a function without using any parameters or function result?":假设存在某种魔法,即使是在伪代码中也会是什么样子?实际问题的无用答案是:使用全局变量。
  • 你想在这里解决什么问题?一般来说,这种隐藏的依赖关系(即方法 B 依赖于首先调用的方法 A)通常是代码理解和后续更改的障碍。
  • @HeinrichUlbricht,我建议使用显式销毁,它更不容易出错,而且真的没有那么困难。完成后使用FreeandNil(MyObject);。使用try .. finally 块来确保销毁发生。
  • 你可以使用一个接口:它是引用计数的,所以当你停止使用它时会自动销毁。请记住不要将对同一对象的对象和接口引用混合在一起 - 仅通过一个或另一个来引用特定对象。

标签: delphi scope


【解决方案1】:

对不起,如果这听起来很奇怪,但这将允许我在被调用方法内创建一个托管对象,该对象只会在调用方法结束时被销毁,而不是在其中创建它的那个。这样我没有使用 out/var 变量或返回值(这实际上是我的目标)。

CALLED 方法中的托管局部变量需要“移动”到调用方法。发生这种情况的唯一定义方法是使用var、out 或返回实际值。这是因为所有可以“传输”的“托管”数据类型都是引用计数的。这包括接口和字符串。

为匿名方法使用自动创建的包装对象并将数据附加到它。我的假设是:这个对象是在调用者本地范围内创建的,存在于被调用者本地范围内(因此被调用者可以将数据附加到它),并一直存在到最后;来电者的。

Delphi 为匿名方法生成一个实际的TInterfacedObject 后代。它将为每个声明匿名方法的方法/过程生成一个这样的后代。生成的对象的名称将基于声明匿名方法的过程的名称。这个对象有方法,每个匿名方法使用一个方法。它还具有数据字段:匿名方法中使用的每个局部变量都有一个字段,以及对您正在操作的对象的引用。

详细解释请看这里:How and when are variables referenced in Delphi's anonymous methods captured?

这个想法是,您可以通过在声明匿名方法的同一过程中简单地声明局部变量并在该匿名方法中使用它们来将数据字段附加到匿名方法。然后,您将能够获取该数据,但这将是一个 hacky,困难的方法:您需要将匿名方法强制转换为实现对象(匿名方法实际上是一个接口,因此可以完成)。然后您需要使用 RTTI 来获取保存数据的字段。对我来说似乎不是很有用。

【讨论】:

  • 听起来像是一个丰富的错误来源。感谢您的链接!我会放开它并迅速关闭它。
猜你喜欢
  • 1970-01-01
  • 2014-03-02
  • 2017-12-22
  • 1970-01-01
  • 2022-06-12
  • 2010-11-26
  • 2013-01-07
  • 2017-03-05
  • 2013-10-14
相关资源
最近更新 更多