2009-07-27 28 views

Respuesta

3

Sí, el tamaño de una estructura se ve afectado por la arquitectura. Las estructuras de C# en 32 bits están alineadas en límites de 4 bytes, y en 64 bits están alineadas en 8 bytes.

Ejemplo:

struct Foo 
{ 
    int bar; 
} 

instancias de esta struct tomarán 4 bytes en los procesos de 32 bits, y 8 bytes en los procesos de 64 bits, a pesar de la "barra int" toma sólo 4 bytes de ambos procesos 32 y 64 bits .

Actualización:

lo hice algunas pruebas con esto.Escribí este código:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication3 
{ 
    struct Bar 
    { 
     int a; 
    } 

    struct Foo 
    { 
     Uri uri; 
     int a; 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Foo[] foo; 
      long fooBefore = System.GC.GetTotalMemory(true); 
      foo = new Foo[10]; 
      long fooAfter = System.GC.GetTotalMemory(true); 

      Bar[] bar; 
      long barBefore = System.GC.GetTotalMemory(true); 
      bar = new Bar[10]; 
      long barAfter = System.GC.GetTotalMemory(true); 

      Foo aFoo = new Foo(); 
      Bar aBar = new Bar(); 

      System.Console.Out.WriteLine(String.Format("[Foo] Size of array of 10: {0}, Marshal size of one: {1}", fooAfter - fooBefore, System.Runtime.InteropServices.Marshal.SizeOf(aFoo))); 
      System.Console.Out.WriteLine(String.Format("[Bar] Size of array of 10: {0}, Marshal size of one: {1}", barAfter - barBefore, System.Runtime.InteropServices.Marshal.SizeOf(aBar))); 
      System.Console.ReadKey(); 
     } 
    } 
} 

Como un proceso de 64 bits, consigo esta salida:

[Foo] Size of array of 10: 208, Marshal size of one: 16 
[Bar] Size of array of 10: 88, Marshal size of one: 4 

Como un proceso de 32 bits, consigo esta salida:

[Foo] Size of array of 10: 92, Marshal size of one: 8 
[Bar] Size of array of 10: 64, Marshal size of one: 4 

Observaciones:

  • La estructura simple, Bar, parece tomar 4 bytes en ambos 32 bits y los procesos de 64 bits
  • La otra estructura, Foo, parece tomar 8 bytes en 32 bits (4 bytes para el int y 4 bytes para la referencia al Uri), pero 16 bytes en 64 bits (4 bytes para el int, 8 bytes para la referencia al Uri, y creo que 4 bytes para la alineación)
+0

JaredPar parece estar en desacuerdo - ¿sabes dónde se puede obtener la información? – thecoop

+0

Hmm, tal vez soy un error aquí. Lo investigaré un poco más. –

+0

Actualicé la respuesta con algunos resultados interesantes. –

6

No es un valor difícil: es solo una guía, una regla de oro. Dependiendo de la situación exacta, 24 o incluso 32 bytes podrían ser perfectamente justificables, pero si su estructura es tan grande, realmente debería preguntarse si es apropiado como estructura en primer lugar. Puede ser - en cuyo caso tomar la decisión de copiar esos 32 bytes en cualquier momento en que realice una tarea o pase un argumento en un método (etc.) puede ser lo correcto; en otros casos, realmente deberías estar usando una clase.

En cuanto a cómo determina qué tan grande es su estructura, por lo general es bastante obvio, ya que normalmente un tipo de valor solo contiene otros tipos de valores. Si su estructura contiene referencias (o un IntPtr/UIntPtr), eso es más un problema, pero eso es bastante raro. (Como señala Mehrdad, también está el problema del relleno por el bien de la alineación).

Por otra parte, me resulta extremadamente raro que quiera escribir mi propia estructura de todos modos. ¿Cuál es tu situación?

4

En .Net la mayoría de los tipos no cambian de tamaño entre un programa de 32 y 64 bits. Los únicos 2 tipos de valores definidos por el marco que va a cambiar su tamaño basado en la plataforma son

  • IntPtr
  • UIntPtr

A menos que tenga uno de éstos directa o indirectamente, en su estructura, se no debería cambiar el tamaño entre las plataformas.

Como Mehrdad señaló, las otras dos clases de campos que cambiarán de tamaño basadas en la plataforma son

  • Punteros
  • Tipos de referencia

todos estos tipos, aunque va a cambiar en el exactamente de la misma manera. 4 bytes en una plataforma de 32 bits y 8 bytes en una plataforma de 64 bits.

Cuestiones relacionadas