繁体   English   中英

为什么我的INT变量通过引用传递? C#

[英]Why is my INT variable being passed by reference?? C#

好的,我知道C#中的值类型和引用类型之间的区别(我认为)。 但是,下面的代码无法像我期望的那样了解我对值类型和引用类型的了解。

delegate void SomeHandler();

static Action GetSomeHandler()
 {
   int x = 1;

   SomeHandler a = delegate { Console.WriteLine(x); };

   x = 2;

   return a;
 }

static void Main(string[] args)
{
   SomeHandler a = GetSomeHandler();

   a();
}

我很困惑,因为在我的GetSomeHandler方法中声明了局部变量“ x”并将其初始化为1。 然后,声明一个SomeHandler类型的新委托“ a”并将其分配给将“ x”写入控制台的匿名方法。 然后将“ x”分配给2。最后,调用“ a”并将“ x”的值打印到控制台。

我期望输出为1,因为“ x”是一个int(值类型),并且我假设当2被分配给“ x”时,它不会影响我在委托中使用的内容,因为该值将被复制并没有指向内存中的相同位置,但实际输出为2! 为什么!?

啊,您发现了关闭的魔力!

您认为“ x”是值类型并且不应以这种方式运行是正确的。 也就是说,如果您未在方法内部声明匿名函数。 匿名方法是一个闭包,并绑定到其父方法主体和其中的局部变量(在本例中为局部变量“ x”和父方法GetSomeHandler)。

重要的区别是它与变量绑定,而不是 换句话说,声明“ a”时不会复制“ x”的值。 而是使用对“ x”的“引用”,以便“ a”将始终使用“ x”的最新值。 实际上,即使“ x”超出范围,对“ x”的这种“引用”也将保留。 编译程序时,编译器随后会发挥其“编译器魔力”,并生成类似于以下代码片段的内容:

delegate void SomeHandler();

// This is the helper class generated by the compiler that allows an anonymous function inside your method access to local variables even after the function or method has returned.
sealed class SomeHandlerClosure
{
   public int x;

   public void CompilerNamedMethod()
   {
     Console.WriteLine(x);
   }
}

static SomeHandler GetSomeHandler()
 {
   SomeHandlerClosure closure = new SomeHandlerClosure();
   closure.x = 1;

   SomeHandler a = new SomeHandler(closure.CompilerNamedMethod);

   closure.x = 2;

   return a;
 }

static void Main(string[] args)
 {
   SomeHandler a = GetSomeHandler();

   a();
 }

“ GetSomeHandler”方法确实是神奇的地方:

1.在方法开始时,将创建“ SomeClosure”类的实例。 (请注意,为清楚起见,我选择使用名称“ SomeHandlerClosure”和“ CompilerNamedMethod”。实际上,编译器会生成名称以防止名称冲突。)

2.“ GetSomeHandler”方法中对局部变量“ x”的所有引用已替换为对“ SomeHandlerClosure”实例上的“ x”字段的引用。

3.现在,将“ SomeHandlerClosure”实例上的“ CompilerNamedMethod”分配给新的委托实例的委托“ a”。

像泥一样清澈?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM