2009-10-29 45 views
1

所以,如果我迭代使用foreach循環,我有一個裏面的函數,需要從列表中迭代的對象的參數,並可以說我設置它的值是不同的。 爲什麼我不必使用或ref?我認爲它只是通過價值傳遞,如果你沒有使用或參考....我知道一個ref你必須已經初始化變量之前,你只需要在從方法返回之前設置它的值。傳遞由ref和out

看來,如果你迭代通過列表並傳遞一個對象在其實際通過引用。考慮下面的例子。

class Program 
    { 
     static void Main(string[] args) 
     { 

      List<Foo> list = new List<Foo>(); 
      list.Add(new Foo() { Bar = "1" }); 
      list.Add(new Foo() { Bar = "2" }); 



      foreach (var f in list) 
      { 
       Foo f2 = f; 
       Console.WriteLine("SetFoo Pre: " + f2.Bar); 
       SetFoo(f2); 
       Console.WriteLine("SetFoo Post: " + f2.Bar); 

       Console.WriteLine("SetFooRef Pre: " + f2.Bar); 
       SetFooRef(ref f2); 
       Console.WriteLine("SetFooRef Post: " + f2.Bar); 
       Console.WriteLine(""); 
      } 




      Console.WriteLine(""); 

      int i = 0; 
      // Not using ref keyword 
      Console.WriteLine("SetI Pre: " + i); 
      SetI(i); 
      Console.WriteLine("SetI Post: " + i); 

      // Using ref keyword 
      Console.WriteLine("SetRefI Pre: " + i); 
      SetRefI(ref i); 
      Console.WriteLine("SetRefI Post: " + i); 
     } 


     private static void SetRefI(ref int i) 
     { 
      i = 3; 
      Console.WriteLine("SetRefI Inside: " + i); 
     } 

     private static void SetI(int i) 
     { 
      i = 2; 
      Console.WriteLine("SetI Inside: " + i); 
     } 

     private static void SetFooRef(ref Foo f) 
     { 
      f.Bar = String.Format("{0} :: {1}", f.Bar, "WithRef"); 
      Console.WriteLine("SetFooRef Inside: " + f.Bar); 
     } 

     private static void SetFoo(Foo f) 
     { 
      f.Bar = String.Format("{0} :: {1}", f.Bar, "WithoutRef"); 
      Console.WriteLine("SetFoo Inside: " + f.Bar); 
     } 
    } 


    class Foo 
    { 
     public string Bar { get; set; } 
    } 

輸出:

SetFoo預:1 SetFoo內:1 ::
WithoutRef SetFoo發表:1 WithoutRef
SetFoo預:1 :: WithoutRef SetFoo
Inside:1 :: WithoutRef :: WithRef
SetFoo Post:1 WithoutRef :: WithRef

SetFoo前:2 SetFoo內部:2 ::
WithoutRef SetFoo帖子:2 WithoutRef
SetFoo前:2 :: WithoutRef SetFoo
內部:2 :: WithoutRef :: WithRef
SetFoo帖子:2 WithoutRef: :WithRef

設置間隔預:0設置間隔內:2 SetIPost:0

SetRefI預:0 SetRefI內部:3
SetRefI發表:3

我理解帶整數示例的ref,但不是上面的Foo對象迭代示例。

謝謝!

回答

12

參考通過值。所以這個方法仍然可以改變對象的內容,但它不能改變你的變量引用哪個對象。

查看my article on parameter passing瞭解更多信息,以及我的文章約reference types and value types

+0

因此,在上面的情況下,我傳遞了對象Foo到我的SetFoo方法的參考。由於它共享相同的內存位置,如果我更改Bar的值,那麼在退出我的函數後,Bar的值將與列表中Foo的實例的值相同?那麼不需要我的SetFooRef方法呢? – Gabe 2009-10-29 15:24:33

+0

它仍然不同,如果你沒有使用ref修飾符,你通過引用值傳遞對象而不是對象引用指針(可以這麼說)。如果你將在方法內部構造一個全新的Foo對象,那麼你的SetFooRef可能是有用的 - 這個新對象將在方法之外被「看到」。相反,如果沒有引用,你可以改變對象屬性等等,這些改變將在外面「看到」,但是如果你在一個參數變量上初始化一個新的Foo對象 - 它將只有本地範圍,因爲你將覆蓋引用值。 – Audrius 2009-10-29 15:38:31

+0

好吧,這更有意義。所以對於整數示例,我通過SetI()的值傳遞它,但設置SetRefI()我通過引用指針傳遞呢? – Gabe 2009-10-29 15:45:20

相關問題