C#: Getting Size of a Value-Type Variable at Runtime

C#: Getting size of a value-type variable at runtime?

To find the size of an arbitrary variable, x, at runtime you can use Marshal.SizeOf:

System.Runtime.InteropServices.Marshal.SizeOf(x)

As mentioned by dtb, this function returns the size of the variable after marshalling, but in my experience that is usually the size you want, as in a pure managed environment the size of a variable is of little interest.

sizeof() operator for types

The sizeof operator in C# works only on compile-time known types, not on variables (instances).

The correct example would be

int variable = 10;
int sizeOfVariable = sizeof(int);

So probably you are looking for Marshal.SizeOf which can be used on any object instances or runtime types.

int variable = 10;
int sizeOfVariable = Marshal.SizeOf(variable);

See here for more information

get native type size from c#

Unlike C++, getting an object's size in .NET is always a runtime operation. Marshal.SizeOf calls do not get translated into compile-time constants in the same way that C++'s sizeof operator does. At runtime, .NET would require a .NET object that it could reflect across, and that object must be defined correctly using attributes like StructLayout.

So you've got two options:

  1. Define a .NET version of your C++ object and use Marshal.SizeOf. You don't need to use the .NET object for anything. It's just there to allow you to determine the size. Of course, if you mess up that object, or if they get out of sync because of evolution, you're gonna have a bad time.
  2. Expose a new method from the C++ that just returns sizeof(MyCppObject). This is probably the better solution.

Using Reflection to get number of bytes from PropertyType

Two possible solutions for you:

  1. Marshal.SizeOf() method (http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx)

  2. The sizeof keyword (http://msdn.microsoft.com/en-us/library/eahchzkf%28VS.71%29.aspx)

The latter though will still need a switch statement as it's not possible to do:

int x;
sizeof(x);

sizeof only works with explicitly stated types, e.g. sizeof(int)

So (1) is your better option in this case (and it will work for all types, not just those in your switch statement).

Value types of variable size

Once again, I had an epiphany in the shower.

I guess what I was kind of looking for was something like var x = new Vector<int, 4>();, which is impossible in C#. So, remembering this, my current solution is:

public struct Vector<TElement, TImpl> where TImpl : struct, IImplementation<TElement>
{
private TImpl impl;

public int Dimensions { get { return impl.Dimensions; } }

public TElement this[int index]
{
get { return impl[index]; }
set { impl[index] = value; }
}
}

Thank you to everyone who responded.

Byte width of a value type

Can you use the Marshal.SizeOf method?

http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx

EDIT: NB! Read Tor Haugen's comment prior to actually doing this.

How runtime knows the exact type of a boxed value type?

When a value is boxed it gets an object header. The kind that any type that derives from System.Object has. The value follows that header. The header contains two fields, one is the "syncblk", it has various uses that are beyond the scope of the question. The second field describes the type of object.

That's the one you are asking about. It has various names in literature, most commonly "type handle" or "method table pointer". The latter is the most accurate description, it is a pointer to the info the CLR keeps track of whenever it loads a type. Lots of framework features depend on it. Object.GetType() of course. Any cast in your code as well as the is and as operators use it. These casts are safe so you can't turn a Dog into a Cat, the type handle provides this guarantee. The method table pointer for your boxed int points to the method table for System.Int32

Boxing was very common in .NET 1.x, before generics became available. All of the common collection types stored object instead of T. So putting an element in the collection required (implicit) boxing, getting it out again required explicit unboxing with a cast.

To make this efficient, it was pretty important that the jitter didn't need to consider the possibility that a conversion would be required. Because that requires a lot more work. So the C# language included the rule that unboxing to another type is illegal. All that's needed now is a check on the type handle to ensure it is expected type. The jitter directly compares the method table pointer to the one for System.Int32 in your case. And the value embedded in the object can be copied directly without any conversion concerns. Pretty fast, as fast as it can possibly be, this can all be done with inline machine code without any CLR call.

This rule is specific to C#, VB.NET doesn't have it. Typical trade-off between those two languages, C#'s focus is on speed, VB.NET on convenience. Converting to another type when unboxing isn't otherwise a problem, all simple value types implement IConvertible. You write it explicit in your code, using the Convert helper class:

        int i = 123;                    // A value type
object box = i; // Boxing
long j = Convert.ToInt64(box); // Conversion + unboxing

Which is pretty similar to the code that the VB.NET compiler auto-generates.



Related Topics



Leave a reply



Submit