Подтвердить что ты не робот

Как найти размер класса в С#

public class A
{
  int x;
  float y;
}

Как найти размер класса в С#. Есть ли какой-либо оператор, такой как Sizeof(), который раньше использовался в С++

4b9b3361

Ответ 1

Короткий ответ:

Ты не хочешь.

Длинный ответ:

Это можно сделать только в том случае, если у вас есть фиксированный макет и не имеет управляемых членов. Структуры фиксируются по умолчанию. Классы могут быть привязаны к фиксированной компоновке.

(Я не показываю, как, как вам это действительно не нужно. Это важно только при выполнении взаимодействия.)

Ответ 2

Следующее предоставит вам размер класса С#:

Marshal.SizeOf(typeof(Myclass));

using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
class Myclass
{

}

Помните, что размер класса зависит от заполнения.

Ответ 3

Вы можете сериализовать класс в поток памяти, а затем получить размер оттуда, но я бы не рекомендовал делать это, если вам не пришлось.

Ответ 4

Если вы используете оператор sizeof, вы получите размер указателя (который, очевидно, будет одинаковым для всех объектов).

Вы можете написать свой собственный метод и выполнить итерацию (используя отражение) по всем членам объекта (или тем, которые вас интересуют), и добавить размер каждого отдельного члена.

Сложная часть сможет определить размер члена, который не является родным типом... ваш метод должен быть несколько "рекурсивным".

Если бы вы реализовали вышеупомянутую идею, у вас был бы приблизительный размер объекта.

Ответ 5

Большинство опубликованных решений великолепны и работают нормально, но у них есть ограничение на то, что ваш класс должен быть сериализуемым (подробнее см.: https://docs.microsoft.com/en-us/dotnet/standard/serialization/basic-serialization) Однако, если вы не сериализуете класс, может оказаться полезным следующий код. Этот код учитывает тот факт, что использование ссылочного поля не является бесплатным, оно добавляет некоторые накладные расходы. Он также рассматривает использование среднего размера для строк, чтобы вы получили лучшее приближение.

    /// <summary>
    /// Gets the size of object.
    /// </summary>
    /// <param name="obj">The object.</param>
    /// <param name="avgStringSize">Average size of the string.</param>
    /// <returns>An approximation of the size of the object in bytes</returns>
    public static int GetSizeOfObject(object obj, int avgStringSize=-1)
    {
        int pointerSize = IntPtr.Size;
        int size = 0;
        Type type = obj.GetType();
        var info = type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
        foreach (var field in info)
        {
            if (field.FieldType.IsValueType)
            {
                size += System.Runtime.InteropServices.Marshal.SizeOf(field.FieldType);
            }
            else
            {
                size += pointerSize;
                if (field.FieldType.IsArray)
                {
                    var array = field.GetValue(obj) as Array;
                    if (array != null)
                    {
                        var elementType = array.GetType().GetElementType();
                        if (elementType.IsValueType)
                        {
                            size += System.Runtime.InteropServices.Marshal.SizeOf(field.FieldType) * array.Length;
                        }
                        else
                        {
                            size += pointerSize * array.Length;
                            if (elementType == typeof(string) && avgStringSize > 0)
                            {
                                size += avgStringSize * array.Length;
                            }
                        }
                    }
                }
                else if (field.FieldType == typeof(string) && avgStringSize > 0)
                {
                    size += avgStringSize;
                }
            }
        }
        return size;
    }