标签: anonymous-methods

从匿名类调用新定义的方法

我实例化了一个匿名类的对象,我添加了一个新方法.

Date date = new Date() {
    public void someMethod() {}
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有可能从外部调用此方法,类似于:

date.someMethod();
Run Code Online (Sandbox Code Playgroud)

java anonymous-methods anonymous-class

18
推荐指数
4
解决办法
8992
查看次数

接口,匿名方法和内存泄漏

这是一个构造的例子.我不想在这里发布原始代码.我尝试提取相关部分.

我有一个管理监听器列表的界面.

TListenerProc = reference to procedure (SomeInt : ISomeInterface);

ISomeInterface = interface
   procedure AddListener (Proc : TListenerProc);   
end;
Run Code Online (Sandbox Code Playgroud)

现在我注册一个监听器:

SomeObj.AddListener (MyListener);

procedure MyListener (SomeInt : ISomeInterface);
begin
  ExecuteSynchronized (procedure
                       begin
                       DoSomething (SomeInt);
                       end);
end;
Run Code Online (Sandbox Code Playgroud)

我确实得到了内存泄漏.永远不会释放匿名方法和接口.我怀疑这是由于某种循环引用.匿名方法保持界面生效,界面保持匿名方法生效.

两个问题:

  1. 你支持这个解释吗?或者我在这里错过了其他什么?
  2. 我能做些什么吗?

提前致谢!


编辑:在一个小到足以在此发布的应用程序中重现这一点并不容易.我现在能做的最好的事情如下.匿名方法不会在这里发布:

program TestMemLeak;

{$APPTYPE CONSOLE}

uses
  Generics.Collections, SysUtils;

type
  ISomeInterface = interface;
  TListenerProc  = reference to procedure (SomeInt : ISomeInterface);

  ISomeInterface = interface
  ['{DB5A336B-3F79-4059-8933-27699203D1B6}']
    procedure AddListener (Proc : TListenerProc);
    procedure NotifyListeners;
    procedure Test;
  end;

  TSomeInterface = class (TInterfacedObject, ISomeInterface) …
Run Code Online (Sandbox Code Playgroud)

delphi memory-management interface anonymous-methods delphi-2010

17
推荐指数
1
解决办法
1057
查看次数

匿名监听器是否与弱引用不兼容?

我正在读这个被问到的问题:避免回调中的内存泄漏?

我很困惑,直到有人回答以下问题:

"这种方法的问题是你不能有一个只在集合中引用的监听器,因为它会随机消失(在下一个GC上)"

我是否理解使用弱引用(如存储在WeakHashMap中)与匿名侦听器不兼容?

我通常传递这样的听众:

public static void main(String[] args) {
    final Observable obs = new SomeObservable();
    obs.addObserver(new Observer() {
        public void update(final Observable o, final Object arg) {
            System.out.println("Notified");
        }
    });
    obs.notifyObservers();
    ... // program continues its life here
}

private static final class SomeObservable extends Observable {

    @Override
    public void addObserver(final Observer o) {
        super.addObserver(o);
        setChanged(); // shouldn't be done from here (unrelated to the question)
    }

}
Run Code Online (Sandbox Code Playgroud)

我使用CopyOnWriteArrayList跟踪侦听器(上面的默认Observable显然使用了一个旧的Vector,但它只是一个示例来说明我通常如何创建一个匿名类来用作侦听器). …

java garbage-collection callback anonymous-methods

17
推荐指数
2
解决办法
1685
查看次数

匿名方法与lambda表达式

任何人都可以提供匿名方法和lambda表达式之间的简洁区别吗?

使用匿名方法:

private void DoSomeWork()
{
    if (textBox1.InvokeRequired)
    {
        //textBox1.Invoke((Action)(() => textBox1.Text = "test"));
        textBox1.Invoke((Action)delegate { textBox1.Text = "test"; });
    }
}
Run Code Online (Sandbox Code Playgroud)

是仅仅将普通的lambda表达式强制转换为强类型的委托,还是有更多的表达式.

我很清楚一个强类型的代表就像跟随

UpdateTextDelegate mydelegate = new UpdateTextDelegate(MethodName)
Run Code Online (Sandbox Code Playgroud)

足够作为类型的参数System.Delegate,但匿名方法的想法对我来说是新的.

c# lambda delegates anonymous-methods

17
推荐指数
2
解决办法
1万
查看次数

如何检查两个方法引用是否引用相同的方法?

我正在尝试制作事件处理程序列表,其中handler是方法引用.要删除特定的处理程序,我需要在列表中找到它.但是我如何比较两个方法引用的代码地址?

type
  TEventHandler = reference to procedure;

procedure TestProc;
begin
end;

procedure TForm26.FormCreate(Sender: TObject);
var
  Handlers: TList<TEventHandler>;
begin
  Handlers := TList<TEventHandler>.create;
  try
    Handlers.Add(TestProc);
    Handlers.Remove(TestProc); { doesn't work }
    Assert(Handlers.Count=0);  { fails }
    Assert(Handlers.IndexOf(TestProc)>=0); { fails }
  finally
    FreeAndNil(Handlers);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

TList <>的默认比较器不能正确比较方法引用.我该如何比较它们?是否存在类似于TMethod的结构,但是方法参考?

delphi anonymous-methods method-reference

17
推荐指数
1
解决办法
521
查看次数

为什么匿名委托/ lambdas不在out/ref参数上推断类型?

StackOverflow上的几个C#问题询问如何使用outref参数创建匿名委托/ lambdas .例如,见:

为此,您只需指定参数的类型,如:

public void delegate D(out T p);
// ...
D a = (out T t) => { ... };      // Lambda syntax.
D b = delegate(out T t) { ... }; // Anonymous delegate syntax.
Run Code Online (Sandbox Code Playgroud)

我很好奇的是为什么明确要求类型.有这种情况的特殊原因吗?也就是说,从编译器/语言的角度来看,为什么不允许以下内容?

D a = (out t) => { ... };      // Lambda syntax -- implicit typing.
D b = delegate(out t) { ... }; // Anonymous delegate syntax -- implicit typing.
Run Code Online (Sandbox Code Playgroud)

甚至更好,只是:

D a = (t) …
Run Code Online (Sandbox Code Playgroud)

c# lambda delegates anonymous-methods out-parameters

16
推荐指数
1
解决办法
2240
查看次数

如何将由另一个函数返回的函数赋值给函数变量?结果而不是生成函数本身

函数返回匿名函数.我想将结果分配给变量.但是编译器认为我正在尝试分配函数而不是函数的结果.我该如何解决这个问题?

program Project9;

{$APPTYPE CONSOLE}

type
  TMyEvent = reference to function: string;

var
  v1: TMyEvent;

function GetHandler: TMyEvent;
begin
  Result := function: string
            begin
              Result := '';
            end;
end;

begin
  v1 := GetHandler;  // <- Incompatible types: 'TMyEvent' and 'Procedure'
end.
Run Code Online (Sandbox Code Playgroud)

注意:我确实有一个解决方法,但我希望在不引入包装器的情况下解决这个问题:

program Project9;

{$APPTYPE CONSOLE}

type
  TMyEvent = reference to function: string;

  TWrapper = record
    FHandler: TMyEvent;
  end;

var
  v1: TMyEvent;

function GetHandler: TWrapper;
begin
  Result.FHandler := function: string
                     begin
                       Result := '';
                     end;
end;

begin
  v1 := GetHandler.FHandler; …
Run Code Online (Sandbox Code Playgroud)

delphi variables function-pointers function anonymous-methods

16
推荐指数
2
解决办法
1471
查看次数

为什么我不能在调试器中编辑包含匿名方法的方法?

所以,每次我在一个方法中编写一个lambda表达式或匿名方法时,我都没有完全正确,我被迫重新编译并重新启动整个应用程序或单元测试框架以便修复它.这非常令人烦恼,我最终浪费的时间比我首先使用这些结构所节省的时间多.如果可以的话,我会尽量远离他们,尽管Linq和lambdas是我最喜欢的C#功能之一.

我想有一个很好的技术理由说明为什么会这样,也许有人知道呢?此外,有谁知道它是否会在VS2010中修复?

谢谢.

c# debugging lambda anonymous-methods visual-studio-2010

15
推荐指数
1
解决办法
3641
查看次数

VB.NET是否具有匿名功能?

从我在谷歌上可以找到的,VB.NET只有一个语句lambdas,而不是多语句匿名函数.但是,我读到的所有文章都在谈论旧版本的VB.NET,我找不到比vs2008 beta 1或2更新的内容.

所以问题是:如何在VB.NET中执行此操作?

C#代码:

private void HandleErrors( Action codeBlock ){
    try{
        codeBlock();
    }catch(Exception e){
        //log exception, etc
    }
}

HandleErrors(() => {
    var x = foo();
    x.DoStuff();
    etc
});
Run Code Online (Sandbox Code Playgroud)

vb.net anonymous-methods

15
推荐指数
3
解决办法
2万
查看次数

使用匿名方法的VCL事件 - 您对此实现有何看法?

由于在Delphi中出现了匿名方法,我想在VCL组件事件中使用它们.显然,为了向后兼容,VCL没有更新,所以我设法做了一个简单的实现,但有几点需要注意.

type
  TNotifyEventDispatcher = class(TComponent)
  protected
    FClosure: TProc<TObject>;

    procedure OnNotifyEvent(Sender: TObject);
  public
    class function Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent; overload;

    function Attach(Closure: TProc<TObject>): TNotifyEvent;
  end;

implementation

class function TNotifyEventDispatcher.Create(Owner: TComponent; Closure: TProc<TObject>): TNotifyEvent;
begin
  Result := TNotifyEventDispatcher.Create(Owner).Attach(Closure)
end;

function TNotifyEventDispatcher.Attach(Closure: TProc<TObject>): TNotifyEvent;
begin
  FClosure := Closure;
  Result := Self.OnNotifyEvent
end;

procedure TNotifyEventDispatcher.OnNotifyEvent(Sender: TObject);
begin
  if Assigned(FClosure) then
    FClosure(Sender)
end;

end.
Run Code Online (Sandbox Code Playgroud)

以下是它的用法:

procedure TForm1.FormCreate(Sender: TObject);
begin    
  Button1.OnClick := TNotifyEventDispatcher.Create(Self,
    procedure (Sender: TObject)
    begin
      Self.Caption := 'DONE!'
    end)
end;
Run Code Online (Sandbox Code Playgroud)

我相信很简单,有两个缺点:

  • 我必须创建一个组件来管理匿名方法的生命周期(我浪费了更多的内存,对于间接方式来说它有点慢,我仍然希望在我的应用程序中更清晰的代码)

  • 我必须为每个事件签名实现一个新类(非常简单).这个有点复杂,VCL仍然有非常常见的事件签名,而且对于我创建类的每一个特殊情况,它都是永远完成的. …

delphi vcl anonymous-methods

15
推荐指数
2
解决办法
4115
查看次数