c# - Size of struct with generic type fields -
i want estimate size of array of structs containing generic type parameters, in case dictionary entry struct. need size of struct.
struct entry { int hash; int next; tkey key; tvalue value; }
how can size in bytes of struct?
edit
it seems using marshal.sizeof
problematic. passing type of struct raise exception saying argument can't generic type definition.
if instead call overload takes instance, e.g. marshal.sizeof(default(entry))
work if both generic type arguments value types. if generic arguments e.g. <int, object>
exception thrown
dictionary`2+entry[system.int32,system.object]' cannot marshaled unmanaged structure; no meaningful size or offset can computed.
it sounds il sizeof
instruction need. sizeof
instruction used c# sizeof
operator behind-the-scenes, il version has fewer restrictions reason.
the ecma cli specification (partition iii, section 4.25) has description of sizeof
instruction:
returns size, in bytes, of type.
typetok
can generic parameter, reference type or value type.for reference type, size returned size of reference value of corresponding type, not size of data stored in objects referred reference value.
[rationale: definition of value type can change between time cil generated , time loaded execution. thus, size of type not known when cil generated.
sizeof
instruction allows cil code determine size @ runtime without need call framework class library. computation can occur entirely @ runtime or @ cil-to-native-code compilation time.sizeof
returns total size occupied each element in array of type – including padding implementation chooses add. specifically, array elements liesizeof
bytes apart. end rationale]
you should able @ sizeof
instruction bit of simple runtime codegen:
console.writeline("entry " + typehelper.sizeof(typeof(entry)) + " bytes."); // ... public static class typehelper { public static int sizeof<t>(t? obj) 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>(); }
Comments
Post a Comment