【问题标题】:Is there a way to constrain anonymous function parameter's scope?有没有办法限制匿名函数参数的范围?
【发布时间】:2012-05-25 13:14:09
【问题描述】:

我有一个采用匿名函数参数的方法。该函数的参数由局部变量提供。

public void DoSomething<T>(Action<T> method) where T : new()
{
    T instance = new T();
    method.Invoke(instance);
}

我想防止创建闭包。当DoSomething&lt;T&gt; 完成时,局部变量应该超出范围。有没有办法在编译时对其进行约束?

这是我想避免的情况:

Foo capturedInstance = null;
DoSomething<Foo>(item => capturedInstance = item);
capturedInstance.Call();

【问题讨论】:

  • 你为什么需要那个?应该注意闭包的外部代码。
  • @YoryeNathan 你是对的,我只是想知道是否有一种方法可以在不让用户做错事的情况下限制它。
  • 用户总会做错事。程序员应该检查他并指导他解决错误。然而,信任其他程序员是你必须做的事情,至少是一点点。你只能封装和抽象你的代码。

标签: c# .net c#-4.0 closures anonymous-function


【解决方案1】:

很遗憾*,这是不可能的。您几乎无法控制方法对其参数的作用。如果您不使用泛型类型,则可以解决,但您使用的是,所以不要担心这种情况。 (我希望你不必这样做。)


* 实际上,我认为这是“幸运的”。这不是我们在这里讨论的 C++。

【讨论】:

    【解决方案2】:

    我认为您的代码已经完成了您想要的工作。 代表 lambda item =&gt; capturedInstance = item 的委托仅传递给 DoSomething&lt;Foo&gt;,并且该引用不会分发给其他任何人。因此,当包含方法完成时,委托将超出范围。 lambda 表达式捕获的局部变量也是如此。 仅当您传递对委托的引用时,您才会获得所需的行为。

    【讨论】:

    • 错了。在执行DoSomething 之后,外部局部变量将被更改,因为这就是Action/lambda 表达式所做的,这是他试图阻止的。他不需要委托保持“在范围内”,他希望captureInstance 在执行后“回滚”,或者首先通过一些检查或约束避免对其进行更改。
    【解决方案3】:

    如果T 是一个结构体,那么保存T 类型字段或T[] 类型数组的代码可以将字段或数组元素作为ref 参数传递给外部方法;该方法将能够在该字段或数组槽上直接有效地操作,而无需制作结构的临时副本,但是一旦该方法返回保存该字段或数组的类型,就可以确信外部代码无法再访问该槽.当然,Outside 可以复制字段或元素的内容,但它无法更改原始内容,除非或直到持有该结构的类型再次将其暴露给外部代码。

    不幸的是,如果T 是一个可变类,那么公开引用将允许外部代码随意复制并永远传递该引用。出于这个原因,可变类比可变结构更糟糕的数据持有者。如果希望允许外部代码在不暴露直接引用的情况下使用类,则有必要创建一个包装类和接口。不幸的是,如果不使用大量重复的代码,或者在运行时使用反射生成包装器,就无法做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多