2017-06-13 85 views
0

我讀過String,它是一個「引用類型」,與整數不同。 MS website引用和值類型

我試圖測試它的行爲。

Sub Main() 
    Dim s As New TheTest 
    s.TheString = "42" 
    Dim z As String = s.GimmeTheString 
    z = z & "000" 
    Dim E As String = s.TheString 
    s.GimmeByref(z) 
end sub 
Class TheTest 
    Public TheString As String 
    Public Function GimmeTheString() As String 
     Return TheString 
    End Function 
    Public Sub GimmeByref(s As String) 
     s = TheString 
    End Sub 
End Class 

因此,我期望:

  1. z爲同一基準TheString,從而TheString將被設置爲 「42000」
  2. 則Z爲通過參考由GimmeByref改性從而Z設定爲任何TheString是

實際結果:

  1. Z = 「42000」
  2. E = 「42」
  3. TheString = 「42」

什麼點我缺少什麼? 我也嘗試在GimmeByRef中添加「ByRef」:是的,顯然GimmeByRef確實按預期工作,但如果我將所有內容都稱爲Integer,它們也被稱爲「Value type」。 這些類型之間有任何實際的區別嗎?

+0

的可能的複製[?是什麼在.NET結構和類之間的差別(https://stackoverflow.com/questions/13049/結構和網內類之間的差異) –

+0

字符串也是不可變的。如果您從ByVal變量創建了一個新類,它將不會在方法調用後具有該值。 –

回答

2

混淆的來源有關,因爲無論類型,參數傳遞在VB是傳值默認

如果你想通過引用傳遞參數,你需要指定參數類型爲ByRef

Public Sub GimmeByref(ByRef s As String) 

您還需要了解變異值,並重新分配變量之間的區別。在s = TheString內部的方法不會改變字符串的值,它重新分配s。無論類型是值還是引用類型,顯然都可以這樣做。

值和引用類型之間的差異來修改所述值本身時承受,而不是一個變量:

obj.ModifyMe() 

字符串在.NET是不變的,因而不具有任何這樣的方法(同整數)。然而,List(Of String),例如,是一個可變的參考類型。因此,如果修改List(Of String),類型的參數(即使按值傳遞該參數),那麼該對象本身也會被修改超出該方法的範圍。

+0

謝謝。所以「返回TheString」不會複製它? – Pierre

+0

@Pierre它複製*參考變量*。但它不會複製引用所引用的* object *。 –

2

字符串是不可變的,每次你做了一個改變,它就會創建一個新的「引用」,就像New被調用一樣。

String對象被稱爲immutable(只讀),因爲它的值 在創建後不能被修改。出現在 修改一個String對象的方法實際上返回一個新的String對象,其中 包含修改。Ref

您的代碼基本上沒有這樣的事情:

Sub Main() 

    Dim a, b As String 

    a = "12" 
    b = a 
    a = a & "13" 

    Console.WriteLine(a) ' 1213 
    Console.WriteLine(b) ' 12 
    Console.ReadLine() 

End Sub