簡體   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