Getting the Size of a Field in Bytes with C#

How to know the size of the string in bytes?

You can use encoding like ASCII to get a character per byte by using the System.Text.Encoding class.

or try this

  System.Text.ASCIIEncoding.Unicode.GetByteCount(string);
System.Text.ASCIIEncoding.ASCII.GetByteCount(string);

how to get byte size of type in generic list?

sizeof is only going to work on value types.

For a string, you won't know the actual byte size until you populate it.

If you are set on doing this, serialize the list and measure it then. While not a guaranteed way, it is probably better than the alternative. Scratch that. It won't get you what you want without some real effort, if at all. You could perform a quick and dirty count like so:

public int getListSize()
{
Type type = typeof(T);

if (type.IsEnum)
{
return this.Sum(item => Marshal.SizeOf(Enum.GetUnderlyingType(type)));
}
if (type.IsValueType)
{
return this.Sum(item => Marshal.SizeOf(item));
}
if (type == typeof(string))
{
return this.Sum(item => Encoding.Default.GetByteCount(item.ToString()));
}
return 32 * this.Count;
}

If you really want to know more about size, here is a comprehensive answer on the topic.

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).

What is the easiest way to read different length bit fields in a byte array?

Here is a sample bit reader. This is not too efficient because I am returning the read bits in the lowest bit position, and then shifting to accumulate the next field.

First, a class that tracks the bit and byte position in a byte[] and returns the next bit.

public class BitPosition {
int bytePos = 0;
int bitPos = 0; // 0 - 7 only
Byte[] data;

public BitPosition(Byte[] src) => data = src;

static byte[] byteBitMasks = new byte[] { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
public int ReadNextBit() {
if (bytePos >= data.Length)
throw new IndexOutOfRangeException("ReadNextBit");

int bit = (data[bytePos] & byteBitMasks[bitPos]) == 0 ? 0 : 1;
if (++bitPos > 7) {
bitPos = 0;
++bytePos;
}
return bit;
}
public bool HasMoreData => bytePos < data.Length;
}

Now, a class to describe each entry in the compressed color palette:

public class ColorEntry {
public byte marker;
public int color;
public int sizeInBits;
}

Note: If you need larger markers, you can replace byte with int or uint. If you need up to 64-bit markers, you will need to modify the ColorReader to use uint64.

And finally, a ColorReader class that reads the colors from a byte[] using a compressed palette and the BitPosition class:

public class ColorReader {
BitPosition bp;

public ColorReader(byte[] data) => bp = new BitPosition(data);

static ColorEntry[] palette = new[] {
new ColorEntry { marker = 0b0, color = 0xFFFFFF, sizeInBits = 1 },
new ColorEntry { marker = 0b10, color = 0xFF0000, sizeInBits = 2 },
new ColorEntry { marker = 0b110, color = 0xFF00DC, sizeInBits = 3 },
new ColorEntry { marker = 0b111, color = 0xFF5A0C, sizeInBits = 3 },
};

public IEnumerable<ColorEntry> Colors() {
while (bp.HasMoreData) {
int bitsSoFar = 0;
int numBits = 0;
do {
int nextBit = bp.ReadNextBit();
++numBits;
bitsSoFar |= nextBit;

var nextCE = palette.FirstOrDefault(ce => ce.sizeInBits == numBits && ce.marker == bitsSoFar);
if (nextCE != null) {
yield return nextCE;
break;
}
else
bitsSoFar <<= 1;
} while (true);
}
}
}

You can use the class like so:

var data = new byte[] { 0b01011011, 0b10101100, 0b01011100 };
var cr = new ColorReader(data);
var ans = cr.Colors().Select(c => c.color).ToList();

how to find size of object in memory?

The BinaryFormatter tells you how many bytes it needs to serialize the class to binary. This is very different from the size a class takes in memory. For instance, the BinaryFormatter writes information about the type into the stream.

The size that an object uses in memory is not defined at compile time but at runtime, since the JIT compiler decides on the final layout. Now comes the question how to find out the size. While I have a solution for structs (create an array, do pointer arithmetic), I am not sure how to find that out for classes. One solution would be to define your class MemberStateModel as a struct, measure it, then turn back to a class, assuming it will have the same size.

You can also estimate the size, by counting the size of the fields as a lower bound (since padding occurs). If your class has references to other class instances, then it gets nearly impossible to estimate.

Size of struct with generic type fields

It sounds like the IL sizeof instruction could be what you need. The sizeof instruction is used by the C# sizeof operator behind-the-scenes, but the IL version has fewer restrictions for some reason.

The ECMA CLI specification (partition III, section 4.25) has this description of the sizeof instruction:

Returns the size, in bytes, of a type. typeTok can be a generic
parameter, a reference type or a value type.

For a reference type, the size returned is the size of a reference
value of the corresponding type, not the size of the data stored in
objects referred to by a reference value.

[Rationale: The definition of a value type can change between the
time the CIL is generated and the time that it is loaded for
execution. Thus, the size of the type is not always known when the CIL
is generated. The sizeof instruction allows CIL code to determine
the size at runtime without the need to call into the Framework class
library. The computation can occur entirely at runtime or at
CIL-to-native-code compilation time. sizeof returns the total size
that would be occupied by each element in an array of this type –
including any padding the implementation chooses to add. Specifically,
array elements lie sizeof bytes apart. end rationale]

You should be able to get at the sizeof instruction with a bit of simple runtime codegen:

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>();
}

How to get a byte array length using LINQ to Entities?

Use SqlFunctions.DataLength Method (Byte[]) to compare length.

yourquery..... SqlFunctions.DataLength(o.Data) < 800000)

See: Linq2EF pitfall: Using Length property causes System.NotSupportedException

.NET Reflection: determine sizes of a class' fields

You simply want to use the Marshal.SizeOf method in the System.Runtime.InteropServices namespace.

foreach (var fieldInfo in typeof(MyClass).GetFields(BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic))
{
Console.WriteLine(Marshal.SizeOf(fieldInfo.FieldType));
}

Do however take note of the following paragraph in the Remarks section:

The size returned is the actually the size of the unmanaged type. The unmanaged and managed sizes of an object can differ. For character types, the size is affected by the CharSet value applied to that class.

These differences are probably inconsequential though, depending on your purpose... I'm not even sure it's possibly to get the exact size in managed memory (or at least not without great difficulty).



Related Topics



Leave a reply



Submit