के बीच संदर्भों की तुलना में मुझे बॉक्सिंग और संदर्भ तुलना के बारे में आज वीबीएनईटी में एक व्यवहार का सामना करना पड़ा जिसकी मुझे उम्मीद नहीं थी। उदाहरण के लिए मैंने एक सरल कार्यक्रम लिखा है जो किसी भी प्रकार के चर को निष्क्रिय रूप से अद्यतन करने का प्रयास करता है।ऑब्जेक्ट मुक्केबाजी में अंतर/सी # और वीबी.Net
using System;
public static class Program
{
private static object o3;
public static void Main()
{
Console.WriteLine("Hello World");
Test<DateTimeOffset?> value = new Test<DateTimeOffset?>();
Console.WriteLine(value.Value == null);
DateTimeOffset dt1 = new DateTimeOffset(2017, 1, 1, 1, 1, 1, TimeSpan.Zero);
DateTimeOffset dt2 = new DateTimeOffset(2017, 1, 2, 1, 1, 1, TimeSpan.Zero);
Console.WriteLine(value.TrySetValue(null, dt1));
Console.WriteLine(value.Value == dt1);
// this should fail
Console.WriteLine(value.TrySetValue(null, dt2));
Console.WriteLine(value.Value == dt1);
// this should succeed
Console.WriteLine(value.TrySetValue(dt1, dt2));
}
}
public class Test<T>
{
public T Value {
get { return (T)System.Threading.Volatile.Read(ref _value); }
}
private object _value;
public bool TrySetValue(T oldValue, T newValue)
{
object curValObj = System.Threading.Volatile.Read(ref _value);
if (!object.Equals((T)curValObj, oldValue))
return false;
object newValObj = (object)newValue;
return object.ReferenceEquals(System.Threading.Interlocked.CompareExchange(ref _value, newValObj, curValObj), curValObj);
}
}
इस कार्यक्रम का उत्पादन होता है:
यहाँ (https://dotnetfiddle.net/VsMBrg) सी # में एक कार्यक्रम है
Hello World
True
True
True
False
True
True
यह उम्मीद और सब कुछ ठीक काम करने के लिए लगता है के रूप में है।
Imports System
Public Module Module1
private o3 as object
Public Sub Main()
Console.WriteLine("Hello World")
Dim value As New Test(Of DateTimeOffset?)
Console.WriteLine(value.Value is nothing)
Dim dt1 As New DateTimeOffset(2017, 1, 1, 1, 1, 1, TimeSpan.Zero)
Dim dt2 As New DateTimeOffset(2017, 1, 2, 1, 1, 1, TimeSpan.Zero)
Console.WriteLine(value.TrySetValue(Nothing, dt1))
Console.WriteLine(value.Value = dt1)
' This should fail
Console.WriteLine(value.TrySetValue(Nothing, dt2))
Console.WriteLine(value.Value = dt1)
' This should succeed
Console.WriteLine(value.TrySetValue(dt1, dt2))
End Sub
End Module
public class Test(Of T)
Public readonly Property Value As T
Get
Return CType(Threading.Volatile.Read(_value), T)
End Get
End Property
Private _value As Object
Public Function TrySetValue(oldValue As T, newValue As T) As Boolean
Dim curValObj As Object = Threading.Volatile.Read(_value)
If Not Object.Equals(CType(curValObj, T), oldValue) Then Return False
Dim newValObj = CObj(newValue)
Return Object.ReferenceEquals(Threading.Interlocked.CompareExchange(_value, newValObj, curValObj), curValObj)
End Function
end class
यहाँ आउटपुट है:
Hello World
True
True
True
False
True
False
यहाँ पिछले बयान जिसका अर्थ है कि सेट काम नहीं किया गलत है यहाँ VB.NET (https://dotnetfiddle.net/lasxT2) में एक ही कार्यक्रम है। क्या मैं यहां कुछ गलत कर रहा हूं या वीबी.नेट में समस्या है?
(नोट:, पर ध्यान न दें/लिखते हैं वाष्पशील पढ़ता इस उदाहरण कोई सूत्र तो यह सूत्रण से प्रभावित नहीं है है): अगर मैं बदल पूर्णांक टी तो सब कुछ ठीक काम करता है:
संपादित
(dotnetfiddle.net/X6uLZs)। इसके अलावा, अगर मैं एक कस्टम वर्ग के लिए टी बदल यह भी ठीक काम करता है:
dotnetfiddle.net/LnOOme
आईएल को देखते हुए, सी # निर्देश 'unbox.any' है जहां वीबी निर्देश' रूपांतरण है।ToGeneric पैरामीटर '। तो इसका मतलब है कि वीबी संरचना की एक प्रति वापस कर रहा है लेकिन सी # एक ही संरचना का संदर्भ दे रहा है, सही? –
Crowcoder
@ क्रोकोडर - इस छोटे कोड नमूने में अप्रत्याशित प्रतियों की कतरनी संख्या ने मुझे सवाल किया है कि कोई भी वीबी कोड बिल्कुल कैसे काम करता है :-( –
सीएलआर स्रोत कोड से: "तकनीकी रूप से हम उन्हें कॉपी किए बिना बॉक्स किए गए डेटटाइम और डेसिमल वापस कर सकते हैं यहां, लेकिन वीबी को एहसास हुआ कि यह उनके ग्राहकों के लिए एक तोड़ने वाला बदलाव होगा। इसलिए उन्हें कॉपी करें। " –