2010-02-25 14 views
12
public class A 
{ 
    int x; 
    float y; 
} 

Cómo encontrar el tamaño de la clase en C#. ¿Hay cualquier operador como sizeof(), que solía ser en C++Cómo encontrar el tamaño de una clase en C#

+2

¿Cuál es el escenario donde necesita saber explícitamente el tamaño de clase? –

+0

¿qué quieres decir con tamaño? líneas de código, la memoria total que está utilizando? –

+1

@ Asad Butt: Google 'sizeof' – leppie

Respuesta

7

Respuesta corta:

Usted no.

Respuesta larga:

Sólo puede hacerlo si el tipo tiene un diseño fijo y no tiene miembros administrados. Las estructuras se arreglan por defecto. Las clases pueden atribuirse a tener un diseño fijo.

(no estoy mostrando cómo, ya que realmente no lo necesita. Sólo es importante cuando se hace de interoperabilidad.)

+0

Gracias, Leppie. encuentre el tamaño de las estructuras, ya que están fijadas? – Sunil

+0

@Sunil: Sí, puede usar 'Marshal.Sizeof()' o en modo inseguro 'sizeof'. Le dará un error si el tamaño no puede determinarse. – leppie

0

Si se utiliza el operador sizeof, obtendrá el tamaño del puntero (que será el mismo para todos los objetos, obviamente).

Puede escribir su propio método e iterar (utilizando la reflexión) sobre todos los miembros del objeto (o los que le interesan) y agregar el tamaño de cada miembro individual.

La parte difícil podría determinar el tamaño del miembro que no son tipos nativos ... su método tendría que ser algo "recursivo".

Si tuviera que implementar la idea anterior, tendría el tamaño aproximado del objeto.

2

Usted puede serializar la clase en una secuencia de memoria y luego obtener el tamaño de allí, pero Realmente no recomendaría hacer esto a menos que tuvieras que hacerlo.

+7

Ese sería el tamaño de la instancia serializada, que puede no ser el mismo que el tamaño de la instancia. –

+0

Lo he hecho antes.Ejercicio interesante – jcollum

+0

¿Por qué no? –

16

A continuación se le daría el tamaño de la clase C#:

Marshal.SizeOf(typeof(Myclass)); 

using System.Runtime.InteropServices; 

[StructLayout(LayoutKind.Sequential)] 
class Myclass 
{ 

} 

Recuerde tamaño de una clase depende de relleno.

0

La mayoría de las soluciones publicadas son grandes y funcionar bien, pero tienen la limitación de que su clase debe ser serializable (para más detalles ver: https://docs.microsoft.com/en-us/dotnet/standard/serialization/basic-serialization) Sin embargo, si la clase no es serializable entonces el siguiente código puede ser útil. Este código tiene en cuenta el hecho de que usar un campo de referencia no es gratuito, agrega algo de sobrecarga. También considera usar un tamaño promedio para cadenas para que obtenga una mejor aproximación.

/// <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; 
    } 
Cuestiones relacionadas