tag que propiedad programacion poo modificadores acceso c# struct

que - propiedad tag c#



C#¿por qué necesitar estructura si la clase puede cubrirla? (9)

1, el rendimiento. En algunos casos utilizando estructuras obtendremos un rendimiento mucho mejor.
2, inmutabilidad de los datos. Al cambiar alguna propiedad de una estructura obtendrás una nueva estructura. Esto es muy útil en algunos casos.
3, mejor control de la representación en memoria. Podemos definir exactamente cómo se ubica la estructura en la memoria y esto nos permite serializar y deserializar algunos datos binarios de manera rápida y eficiente.

Solo me pregunto por qué necesitamos estructura si la clase puede hacer toda la estructura y mucho más. Poner tipos de valor en clase no tiene ningún efecto secundario, creo.

EDIT: no puede ver ninguna razón fuerte para usar struct

Una estructura es similar a una clase, con las siguientes diferencias clave:

  • Una estructura es un tipo de valor, mientras que una clase es un tipo de referencia.
  • Una estructura no admite herencia (aparte de derivar implícitamente de un objeto).
  • Una estructura puede tener todos los miembros que una clase puede, excepto lo siguiente:
  • Un constructor sin parámetros
  • Un finalizador
  • Miembros virtuales

Se usa una estructura en lugar de una clase cuando la semántica de tipo de valor es deseable. Los buenos ejemplos de estructuras son tipos numéricos, donde es más natural que la asignación copie un valor en lugar de una referencia. Debido a que una estructura es un tipo de valor, cada instancia no requiere la creación de instancias de un objeto en el montón. Esto puede ser importante al crear muchas instancias de un tipo.


Es casi una necesidad de usar para interoperar con la estructura de datos subyacente utilizada por la API de win32. Supongo que una razón muy grande para tenerlo en .net podría ser debido a esa razón.


Las estructuras son útiles simplemente porque se pasan por valor, lo que en realidad puede ser útil en ciertos algoritmos. Esto es realmente algo que las clases NO PUEDEN hacer.

struct ArrayPointer<T> { public T[] Array; public int Offset; }

Puede pasar esta estructura a un método y el método puede alterar el valor de Offset para sus propias necesidades. Mientras tanto, una vez que regrese del método, se comportará como si la compensación nunca hubiera cambiado.


Las estructuras también se requieren a menudo por razones de rendimiento. Las matrices de estructuras toman bastante menos memoria y obtienen una coherencia de caché mucho mejor que una matriz de referencias de objetos. Esto es muy importante si está trabajando con algo como un sistema de representación y necesita generar 5 millones de vértices, por ejemplo.

Para obtener más información, consulte la Prueba de rendimiento de Rico Mariani + Answers .


Para el desarrollador de aplicaciones promedio, usar clases es la norma. En la superficie, las clases hacen que las estructuras parezcan innecesarias, pero cuando profundizas en los detalles esenciales, en realidad son bastante diferentes.

Vea here para algunas diferencias entre estructuras y clases.

La diferencia más conocida es que las clases son tipos de referencia y las estructuras son tipos de valor. Esto es importante porque le permite a un desarrollador de bibliotecas controlar cómo se pueden usar las instancias de un tipo de datos.


¿Por qué usar una struct cuando una class funciona? Porque a veces una class no funciona.

Además de los motivos de rendimiento mencionados por Reed Copsey (versión corta: menos objetos que el GC debe rastrear, lo que permite al GC hacer un mejor trabajo), hay un lugar donde se deben usar las estructuras: P / Invocar a funciones que requieren Estructuras por valor o miembros de la estructura.

Por ejemplo, supongamos que desea invocar la función CreateProcess() . Además, suponga que desea utilizar una estructura STARTUPINFOEX para el parámetro lpStartupInfo en CreateProcess() .

Bueno, ¿qué es STARTUPINFOEX ? Esta:

typedef struct _STARTUPINFOEX { STARTUPINFO StartupInfo; PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; } STARTUPINFOEX, *LPSTARTUPINFOEX;

Observe que STARTUPINFOEX contiene STARTUPINFO como su primer miembro. STARTUPINFO es una estructura.

Dado que las clases son tipos de referencia, si declaramos el tipo de C # correspondiente así:

[StructLayout(LayoutKind.Sequential)] class STARTUPINFO { /* ... */ } class STARTUPINFOEX { public STARTUPINFO StartupInfo; /* ... */ }

El diseño en memoria correspondiente sería incorrecto , ya que STARTUPINFOEX.StartupInfo sería un puntero (4 bytes en plataformas ILP32), NO una estructura (como se requiere, 68 bytes de tamaño en plataformas ILP32).

Por lo tanto, para admitir la invocación de funciones arbitrarias que aceptan estructuras arbitrarias (que es de lo que trata P / Invoke), una de las dos cosas es necesaria:

  1. Totalmente compatible con los tipos de valor. Esto permite que C # declare un tipo de valor para STARTUPINFO que tendrá el diseño en memoria correcto para el cálculo de referencias (es decir, soporte de struct , como C # tiene).

  2. Alguna sintaxis alternativa dentro de las estructuras de P / Invokeable que informaría al contador de tiempo de ejecución de que este miembro debe ser presentado como un tipo de valor en lugar de como un puntero.

(2) es una solución viable (y puede que se haya utilizado en J / Direct en Visual J ++; no lo recuerdo), pero dado que los tipos de valor adecuados son más flexibles, habilite una serie de optimizaciones de rendimiento que de otra manera no sería posible, El uso sensato dentro de los escenarios P ​​/ Invoke, no es una sorpresa que C # admita tipos de valor.


En general , utilice una clase.

Solo use una estructura cuando necesite absolutamente una semántica de tipo valor.


Los tipos de valores personalizados no son absolutamente necesarios , Java lo hace sin ellos, por ejemplo. Sin embargo, todavía pueden ser útiles.

Por ejemplo, en Noda Time los estamos usando bastante, como una manera eficiente de representar cosas como instantes sin la sobrecarga de un objeto involucrado.

No diría que "la clase puede hacer todo lo posible y mucho más", se comportan de manera diferente y deberían pensarse de manera diferente.