Click here to Skip to main content
15,558,034 members

Comments by Visual Herbert (Top 7 by date)

Visual Herbert 28-Feb-21 2:02am View    
I appreciate your effort, really, but I can not accept this answer as the solution.

Yes, in order to obtain the size of a value type (structure), it is oftentimes recommended to use the Marshal.SizeOf method. However, reading the method's documentation states:

Returns the unmanaged size, in bytes, of a class.

and then doubles on with:

The size returned is the size of the unmanaged object. The unmanaged and managed sizes of an object can differ.

As the .NET's value types surely are managed, using Marshal.SizeOf is simply wrong. And it is also inefficient.

Whereas the documentation for Len() states:

Returns an integer containing either the number of characters in a string or the nominal number of bytes required to store a variable.

From Decimal.GetBits it is absolutely clear, that the struct contains 4 x Int32, for a total of 16 bytes. Returning 8 is simply... wrong.
Visual Herbert 27-Feb-21 9:42am View    
Thanks for confirmation! So this might indeed be a VB bug having been undiscovered for decades? Hm.
Visual Herbert 25-Feb-21 8:28am View    
Thank you.

The link provided there is dead, but it was captured by the Wayback Machine, if someone is interested:

The essence is:

Q: Why does the compiler emit a call to System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue whenever you pass an Object reference to an Object parameter?

A: The reason is because we do not want valuetype aliasing to occur. For example, assigning between Objects would copy only the _reference_ to a boxed valuetype. Modifying what the user thinks is a unique instance would in fact modify both copies, which we thought would be surprising and bad. Using reflection and CallByName isn't impossible because you can use System.ValueType. Assigning or passing System.ValueType's will NOT generate calls to GetObjectValue. In other words, you can force aliasing by using System.ValueType instead of Object to manipulate your valuetypes."
Visual Herbert 25-Feb-21 6:55am View    
Thanks kind sir, it works. I did waste my whole morning with research about this problem. Would you please be so kind to share your source?
Visual Herbert 25-Feb-21 5:41am View    
Thanks Chris, it works – in C#. Output then is 42, 42, 21. Our environment is VB.Net though.

Dim oStruct As Object = CType(rStruct, Object)
fValue.SetValue(oStruct, 21)
rStruct = CType(oStruct, SStruct)
oValue = fValue.GetValue(rStruct)
Console.WriteLine("Read After Boxing: {0}", oValue)

still outputs 42,42,42.

I edited my question with copy-pastable source for online verification.