Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有办法约束匿名函数参数';什么范围?_C#_.net_C# 4.0_Closures_Anonymous Function - Fatal编程技术网

C# 有没有办法约束匿名函数参数';什么范围?

C# 有没有办法约束匿名函数参数';什么范围?,c#,.net,c#-4.0,closures,anonymous-function,C#,.net,C# 4.0,Closures,Anonymous Function,我有一个接受匿名函数参数的方法。此函数的参数由局部变量提供 public void DoSomething<T>(Action<T> method) where T : new() { T instance = new T(); method.Invoke(instance); } public void DoSomething(动作方法),其中T:new() { T实例=新的T(); 方法调用(实例); } 我希望防止创建闭包。当DoSomethin

我有一个接受匿名函数参数的方法。此函数的参数由局部变量提供

public void DoSomething<T>(Action<T> method) where T : new()
{
    T instance = new T();
    method.Invoke(instance);
}
public void DoSomething(动作方法),其中T:new()
{
T实例=新的T();
方法调用(实例);
}
我希望防止创建闭包。当
DoSomething
完成时,局部变量应超出范围。有没有办法在编译时约束它

以下是我想要避免的情况:

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

不幸的是*,这是不可能的。对于方法如何处理其参数,您几乎没有控制权。如果您不使用泛型类型,就可以解决这个问题,但是您确实使用了泛型类型,所以不要担心这种情况。(我希望你不必这么做。)



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

我认为你的代码已经做了你想要的。 代表lambda
item=>capturedInstance=item
的委托仅传递给
DoSomething
,该引用不会分发给任何其他人。因此,当包含方法完成时,委托将超出范围。lambda表达式捕获的局部变量也是如此。
只有将引用传递给代理时,才能获得所需的行为。

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


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

为什么需要这样做?应该注意闭包的是外部代码。@YoryeNathan你是对的,我只是想知道是否有一种方法可以在不让用户做错事的情况下约束它。用户总是会做错事。程序员应该检查他并指导他克服错误。然而,信任其他程序员是你必须做的事情,至少是一点点。你只能封装和抽象你的代码。错了。执行
DoSomething
后,外部局部变量将被更改,因为
操作
/lambda表达式就是这样做的,这正是他试图阻止的。他不需要委托停留在“范围内”,他希望
captureInstance
在执行后被“回滚”,或者避免首先通过一些检查或约束对其进行更改。