It looks like the IL sizeof instruction might be what you need. The sizeof statement is used by the C # sizeof operator behind the scenes, but for some reason, the IL version has fewer restrictions.
The CLI ECMA specification (section III, section 4.25) describes the sizeof statement:
Returns the size in bytes of the type. typeTok can be a general parameter, a reference type, or a value type.
For a reference type, the returned size is the size of the reference value of the corresponding type, and not the size of the data stored in the objects is called the reference value.
[Rationale: the definition of the type of value may vary between the time the CIL was created and the time during which it is loaded for execution. Thus, the type size is not always known when the CIL is generated. The sizeof command allows you to define CIL code to determine the size at runtime without having to call the Framework library class. The calculation can occur completely at runtime or at compile time in CIL-native. sizeof returns the total size that each element in an array of this type will occupy - including any additions you want to add. In particular, the elements of the array are sizeof bytes. final rationale]
You should be able to get the sizeof statement with a little simple runtime code:
Console.WriteLine("Entry is " + TypeHelper.SizeOf(typeof(Entry)) + " bytes."); // ... public static class TypeHelper { public static int SizeOf<T>(T? obj) where T : struct { if (obj == null) throw new ArgumentNullException("obj"); return SizeOf(typeof(T?)); } public static int SizeOf<T>(T obj) { if (obj == null) throw new ArgumentNullException("obj"); return SizeOf(obj.GetType()); } public static int SizeOf(Type t) { if (t == null) throw new ArgumentNullException("t"); return _cache.GetOrAdd(t, t2 => { var dm = new DynamicMethod("$", typeof(int), Type.EmptyTypes); ILGenerator il = dm.GetILGenerator(); il.Emit(OpCodes.Sizeof, t2); il.Emit(OpCodes.Ret); var func = (Func<int>)dm.CreateDelegate(typeof(Func<int>)); return func(); }); } private static readonly ConcurrentDictionary<Type, int> _cache = new ConcurrentDictionary<Type, int>(); }
Lukeh source share