C#代理,参考解析时间 [英] C# delegates, reference resolution time

查看:122
本文介绍了C#代理,参考解析时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于.net代表的简单问题。说我有这样的东西:

  public void Invoke(Action< T> action)
{
Invoke(()=> action(this.Value));
}

public void Invoke(Action action)
{
m_TaskQueue.Enqueue(action);
}

第一个函数包含对 this.Value的引用。在运行时,当第一个通用参数的方法被调用时,它将向第二个方法提供 this.Value ,但是如何?这些进入我的脑海:




  • 按值(struct)调用 - 当前值 this.Value 获得通过,所以如果 m_TaskQueue 在5分钟后执行,该值将不会处于最近的状态,它将无论是首次引用时是什么。

  • 通过引用调用(引用类型) - 然后在的最新状态将被引用执行动作,但如果在执行操作之前将 this.Value 更改为另一个引用,则仍将指向旧引用

  • 按名称(两者)调用 - 其中 this.Value 将在调用操作时进行评估。我相信实际的实现将会引用这个,然后评估 Value 在实际执行委托期间,因为那里没有名字。



我认为这将是Call的名称风格,但找不到任何文件,所以想知道是否是明确的行为。这个类是像Scala或Erlang中的Actor,所以我需要它是线程安全的。我不想要调用函数来立即取消引用,这将在安全的线程中完成这个对象由 m_TaskQueue

解决方案

p>让我回答你的问题,通过描述我们为此产生的代码。我会重命名你的混淆命名的其他Invoke方法;没有必要了解这里发生了什么。



假设你说

  C类
{
public T Value;
public void Invoke(Action< T> action)
{
Frob(()=> action(this.Value));
}
public void Frob(Action action)
{//任何
}
}

编译器生成代码,就好像您已经写过的那样:

  class C< ; T> 
{
public T Value;

私人类CLOSURE
{
public Action< T>行动;
public C< T>这个;
public void METHOD()
{
this.ACTION(this.THIS.Value);
}
}

public void Invoke(Action< T> action)
{
CLOSURE closure = new CLOSURE();
closure.THIS = this;
closure.ACTION = action;
Frob(new Action(closure.METHOD));
}
public void Frob(Action action)
{//任何
}
}

这是否会回答您的问题?


I have a simple question about .net delegates. Say I have something like this:

    public void Invoke(Action<T> action)
    {
        Invoke(() => action(this.Value));
    }

    public void Invoke(Action action)
    {
        m_TaskQueue.Enqueue(action);
    }

The first function encloses a reference to this.Value. During runtime, when the first, method with generic parameter gets called, it will provide this.Value somehow to the second one, but how? These came into my mind:

  • Call by value (struct) - the current value of this.Value gets passed, so if the m_TaskQueue executes it 5 minutes later, the value will not be in its recent state, it will be whatever it was when first referencing.
  • Call by reference (reference type) - then the most recent state of Value will be referenced during execution of action but if I change this.Value to another reference before execution of action, it will still be pointing to the old reference
  • Call by name (both) - where this.Value will be evaluated when the action gets called. I believe the actual implementation would be holding a reference to this then evaluate Value on that during actual execution of delegate since there is no call by name.

I assume it would be Call of name style but could not find any documentation so wondering if it is a well-defined behavior. This class is something like an Actor in Scala or Erlang so I need it to be thread safe. I do not want Invoke function to dereference Value immediately, that will be done in a safe thread for this object by m_TaskQueue.

解决方案

Let me answer your question by describing what code we actually generate for this. I'll rename your confusingly-named other Invoke method; it's not necessary to understanding what's going on here.

Suppose you said

class C<T>
{
  public T Value;
  public void Invoke(Action<T> action) 
  { 
      Frob(() => action(this.Value)); 
  } 
  public void Frob(Action action) 
  {  // whatever
  } 
}

The compiler generates code as though you had actually written:

class C<T>
{
  public T Value;

  private class CLOSURE
  {
     public Action<T> ACTION;
     public C<T> THIS;
     public void METHOD()
     {
       this.ACTION(this.THIS.Value);
     }
  }

  public void Invoke(Action<T> action) 
  { 
      CLOSURE closure = new CLOSURE();
      closure.THIS = this;
      closure.ACTION = action;
      Frob(new Action(closure.METHOD)); 
  } 
  public void Frob(Action action) 
  {  // whatever
  } 
}

Does that answer your question?

这篇关于C#代理,参考解析时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆