2017-07-17 60 views
1

我無法理解VB.NET中下面的代碼發生了什麼。當我運行此代碼時:VB.NET拳擊怪異

Public Function test() As Boolean 
    Dim a As Integer = 1 
    Dim b As Object = a 
    Dim c As Object = b 
    Return Object.ReferenceEquals(b, c) 
End Function 

然後函數返回True。但是,如果我運行這個:

Structure TTest 
    Dim i As Integer 
    Dim tid As Integer 
    Sub New(ByVal _i As Integer, ByVal _tid As Integer) 
     i = _i 
     tid = _tid 
    End Sub 
End Structure 

Public Function test_2() As Boolean 
    Dim a As New TTest(1, 1) 
    Dim b As Object = a 
    Dim c As Object = b 
    Return Object.ReferenceEquals(b, c) 
End Function 

然後它返回False。在這兩個函數中,我聲明瞭兩個值類型變量,第一個是Integer,第二個是自定義Structure。兩者都應該在對象分配時加框,但在第二個例子中,它似乎被裝箱成兩個不同的對象,所以Object.ReferenceEquals返回False

它爲什麼這樣工作?

回答

1

對於原始類型,.Net能夠爲相同的值重新使用相同的「框」,從而通過減少分配來提高性能。

+0

所以沒有辦法有一個唯一的參考,甚至拳擊對象的值類型?問題是我必須分配一個自定義類型緩衝區的對象,在多線程環境中使用無鎖隊列,併爲其分配我使用Interlockes.CompareExchange,但檢查結果我必須比較原始對象到指定的那個,在結構等自定義值類型的情況下失敗。 – dreamprisoner

+0

它只對原始圖像執行此操作。對於值比較...覆蓋.Equals()和.GetHashCode() –

+0

我不需要比較值,我需要比較值的內存引用...... Interlocked.CompareExchange不返回狀態該操作(如果成功或者不成功),所以檢查這個的唯一方法是比較要修改的對象的引用和期望的結果值。 – dreamprisoner

0

與字符串一樣,它是.NET優化方式。但只要您使用它,參考將會改變。

Sub Main() 

    Dim a As String = "abc" 
    Dim b As String = "abc" 

    Console.WriteLine(Object.ReferenceEquals(a, b)) ' True 

    b = "123" 

    Console.WriteLine(Object.ReferenceEquals(a, b)) ' False 

    Console.ReadLine() 

End Sub 
+0

確實,但盒裝對象引用不會更改。在我的例子中,如果我將整數更改爲字符串,然後再執行... Dim c as object = b ...我重新指定了一個仍然引用compare返回true – dreamprisoner

+0

@dreamprisoner是因爲「a」將被賦予一個新的引用。 b和c將指向舊的整數。 –