¿Por qué necesitamos estructura? (DO#)

Para usar una estructura, necesitamos crear una instancia de la estructura y usarla como una clase. Entonces, ¿por qué no creamos una clase en primer lugar?

Una estructura es un tipo de valor, por lo que si crea una copia, en realidad copiará físicamente los datos, mientras que con una clase solo copiará la referencia a los datos

Una diferencia importante entre la semántica de class y struct es que las struct tienen valor semántico. Lo que esto significa es que si tiene dos variables del mismo tipo, cada una tendrá su propia copia de los datos. Por lo tanto, si una variable de un tipo de valor dado se establece igual a otra (del mismo tipo), las operaciones en uno no afectarán al otro (es decir, la asignación de tipos de valor crea una copia). Esto está en marcado contraste con los tipos de referencia.

Hay otras diferencias:

  1. Los tipos de valor están sealed implícitamente (no es posible derivar de un tipo de valor).
  2. Los tipos de valor no pueden ser null .
  3. A los tipos de valor se les asigna un constructor predeterminado que inicializa el tipo de valor a su valor predeterminado.
  4. Una variable de un tipo de valor es siempre un valor de ese tipo. Contraste esto con las clases donde una variable de tipo A podría referirse a una instancia de tipo B si B deriva de A

Debido a la diferencia en la semántica, no es apropiado referirse a las struct como “clases ligeras”.

En C #, una estructura es un tipo de valor, a diferencia de las clases que son tipos de referencia. Esto conduce a una gran diferencia en la forma en que se manejan o en cómo se espera que se usen.

Probablemente debería leer sobre estructuras de un libro. Las estructuras en C # no son primos cercanos de clase como en C ++ o Java.

Todas las razones que veo en otras respuestas son interesantes y pueden ser útiles, pero si desea leer acerca de por qué son necesarias (al menos por la VM) y por qué fue un error que la JVM no las apoyara (usuario) tipos de valores definidos), lea Desmitificando Magia: Progtwigción de alto nivel de bajo nivel . En su estado actual, C # brilla al hablar sobre el potencial para llevar código seguro y administrado a la progtwigción de sistemas. Esta es también una de las razones por las que creo que la CLI es una plataforma superior [que la JVM] para la informática móvil. Algunas otras razones se enumeran en el documento vinculado.

Es importante tener en cuenta que muy rara vez, si alguna vez, verás una mejora de rendimiento observable al usar una estructura. El recolector de basura es extremadamente rápido, y en muchos casos en realidad superará las estructuras. Cuando agrega los matices de ellos, ciertamente no son una herramienta de primera elección. Sin embargo, cuando los necesita y tiene resultados de perfiles o construcciones a nivel del sistema para demostrarlo, hacen el trabajo.

Edit: Si querías una respuesta de por qué los necesitamos en lugar de a lo que hacen, ^^^

Este es un mito que las estructuras siempre se crean en el montón. Ok, es correcto que la estructura sea tipo de valor y la clase sea tipo de referencia. Pero recuerda que

1. Un tipo de referencia siempre va en el montón.
2. Los tipos de valor van donde fueron declarados.

Ahora lo que significa la segunda línea es que explicaré con el siguiente ejemplo.

Considere el siguiente método

  public void DoCalulation() { int num; num=2; } 

Aquí num es una variable local, por lo que se creará en la stack .

Ahora considera el siguiente ejemplo

 public class TestClass { public int num; } public void DoCalulation() { TestClass myTestClass = new TestClass (); myTestClass.num=2; } 

Esta vez num es el número que se crea en el montón. Sí, en algunos casos, los tipos de valor realizan más que los tipos de referencia, ya que no requieren recolección de basura.

También recuerde:

El valor de un tipo de valor siempre es un valor de ese tipo. El valor de un tipo de referencia es siempre una referencia.

Y tiene que pensar en el tema de que si espera que haya mucha instanciación, eso significa que habrá más espacio del montón, y el trabajo del recolector de basura. Para ese caso, puede elegir estructuras.

Las estructuras tienen muchas semánticas diferentes a las clases. Las diferencias son muchas pero las principales razones de su existencia son:

  1. Se pueden colocar explícitamente en memoria.
    • Esto permite ciertos escenarios de interoperabilidad.
  2. Se pueden asignar en la stack.
    • Haciendo posible algunos tipos de código de alto rendimiento de una manera mucho más simple

la diferencia es que una estructura es un tipo de valor que he encontrado útil en 2 situaciones

1) Interoperabilidad: puede especificar el diseño de memoria de una estructura, por lo que puede garantizar que cuando invoque una llamada no administrada.

2) Rendimiento: en algunos casos (muy limitados), las estructuras pueden ser más rápidas que las clases. En general, esto requiere que las estructuras sean pequeñas (escuché 16 bytes o menos) y no se cambien con frecuencia.

Una de las razones principales es que, cuando se utilizan como variables locales durante una llamada de método, las estructuras se asignan en la stack.

La asignación de stack es barata, pero la gran diferencia es que la desasignación también es muy barata. En esta situación, el recolector de basura no tiene que rastrear las estructuras, se eliminan cuando regresan del método que les asignó cuando el marco de stack se abrió.

  • editar – aclaró mi post con respecto al comentario de Jon Skeet.

Una estructura es un tipo de valor (como Int32), mientras que una clase es un tipo de referencia. Las estructuras se crean en la stack en lugar de en el montón. Además, cuando se pasa una estructura a un método, se pasa una copia de la estructura, pero cuando se pasa una instancia de clase, se pasa una referencia.

Si necesita crear su propio tipo de datos, digamos, entonces una estructura es a menudo una mejor opción que una clase, ya que puede usarla como los tipos de valor integrados en el marco .NET. Hay algunos buenos ejemplos que puedes leer aquí .