MSDN dice que debe usar estructuras cuando necesite objetos livianos. ¿Hay otros escenarios cuando una estructura es preferible a una clase?
Algunas personas podrían haber olvidado que:
- Las estructuras pueden tener métodos.
- Las estructuras no pueden ser heredadas.
Entiendo las diferencias técnicas entre estructuras y clases, simplemente no tengo una buena idea de cuándo usar una estructura.
Respuestas:
MSDN tiene la respuesta: Elegir entre clases y estructuras .
Básicamente, esa página le brinda una lista de verificación de 4 elementos y le dice que use una clase a menos que su tipo cumpla con todos los criterios.
fuente
ref
parámetros siempre que sea razonable hacerlo. Pasar una estructura con 4.000 campos como parámetro de referencia a un método que cambie uno será más barato que pasar una estructura con 4 campos por valor a un método que devuelve una versión modificada.Me sorprende no haber leído en ninguna de las respuestas anteriores esto, que considero el aspecto más crucial:
Yo uso estructuras cuando quiero un tipo sin identidad. Por ejemplo un punto 3D:
Si tiene dos instancias de esta estructura, no le importa si son una sola pieza de datos en la memoria o dos. Solo le importan los valores que tienen.
fuente
return false
es lo que debería haber estado allí, corrigiendo ahora.Bill Wagner tiene un capítulo sobre esto en su libro "efectivo C #" ( http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660 ). Concluye utilizando el siguiente principio:
fuente
Use una estructura cuando desee semántica de tipo de valor en lugar de tipo de referencia. Las estructuras se copian por valor, ¡así que ten cuidado!
Consulte también las preguntas anteriores, p. Ej.
¿Cuál es la diferencia entre struct y class en .NET?
fuente
Usaría estructuras cuando:
se supone que un objeto es de solo lectura (cada vez que pasa / asigna una estructura se copia). Los objetos de solo lectura son excelentes cuando se trata de procesamiento multiproceso, ya que no requieren bloqueo en la mayoría de los casos.
un objeto es pequeño y de corta vida. En tal caso, existe una buena posibilidad de que el objeto se asigne en la pila, lo que es mucho más eficiente que colocarlo en el montón administrado. Además, la memoria asignada por el objeto se liberará tan pronto como salga de su alcance. En otras palabras, es menos trabajo para Garbage Collector y la memoria se usa de manera más eficiente.
fuente
Use una clase si:
Use una estructura si:
fuente
Siempre he usado una estructura cuando quería agrupar algunos valores para pasar cosas de una llamada a método, pero no necesitaré usarla para nada después de haber leído esos valores. Solo como una forma de mantener las cosas limpias. Tiendo a ver las cosas en una estructura como "desechables" y las cosas en una clase como más útiles y "funcionales"
fuente
Si una entidad va a ser inmutable, la cuestión de si usar una estructura o una clase generalmente será de rendimiento en lugar de semántica. En un sistema de 32/64 bits, las referencias de clase requieren 4/8 bytes para almacenarse, independientemente de la cantidad de información en la clase; copiar una referencia de clase requerirá copiar 4/8 bytes. Por otro lado, cada distintivoLa instancia de clase tendrá 8/16 bytes de sobrecarga además de la información que contiene y el costo de memoria de las referencias a ella. Supongamos que uno quiere una matriz de 500 entidades, cada una con cuatro enteros de 32 bits. Si la entidad es un tipo de estructura, la matriz requerirá 8,000 bytes independientemente de si las 500 entidades son todas idénticas, todas diferentes o en algún punto intermedio. Si la entidad es un tipo de clase, la matriz de 500 referencias tomará 4,000 bytes. Si todas esas referencias apuntan a objetos diferentes, los objetos requerirían 24 bytes adicionales cada uno (12,000 bytes para los 500), un total de 16,000 bytes, el doble del costo de almacenamiento de un tipo de estructura. Por otro lado, del código creó una instancia de objeto y luego copió una referencia a las 500 ranuras de matriz, el costo total sería de 24 bytes para esa instancia y 4, 000 para la matriz: un total de 4.024 bytes. Un gran ahorro. Pocas situaciones funcionarían tan bien como la última, pero en algunos casos puede ser posible copiar algunas referencias a suficientes ranuras de matriz para que valga la pena compartirlas.
Si se supone que la entidad es mutable, la cuestión de si se debe usar una clase o estructura es de alguna manera más fácil. Suponga que "Thing" es una estructura o clase que tiene un campo entero llamado x, y uno hace el siguiente código:
¿Se quiere que la última declaración afecte a t1.x?
Si Thing es un tipo de clase, t1 y t2 serán equivalentes, lo que significa que t1.xy t2.x también serán equivalentes. Por lo tanto, la segunda declaración afectará a t1.x. Si Thing es un tipo de estructura, t1 y t2 serán instancias diferentes, lo que significa que t1.xy t2.x se referirán a enteros diferentes. Por lo tanto, la segunda declaración no afectará a t1.x.
Las estructuras mutables y las clases mutables tienen comportamientos fundamentalmente diferentes, aunque .net tiene algunas peculiaridades en su manejo de mutaciones de estructura. Si uno quiere un comportamiento de tipo de valor (lo que significa que "t2 = t1" copiará los datos de t1 a t2 mientras deja t1 y t2 como instancias distintas), y si uno puede vivir con las peculiaridades en el manejo de tipos de valor de .net, use una estructura. Si uno quiere una semántica de tipo de valor pero las peculiaridades de .net causarían una semántica de tipo de valor rota en la aplicación, use una clase y murmure.
fuente
Además, las excelentes respuestas anteriores:
Las estructuras son tipos de valor.
Nunca se pueden establecer en Nothing .
Establecer una estructura = Nada, establecerá todos sus tipos de valores a sus valores predeterminados.
fuente
cuando realmente no necesita comportamiento, pero necesita más estructura que una simple matriz o diccionario.
Seguimiento Así es como pienso en las estructuras en general. Sé que pueden tener métodos, pero me gusta mantener esa distinción mental general.
fuente
Como dijo @Simon, las estructuras proporcionan una semántica de "tipo de valor", por lo que si necesita un comportamiento similar a un tipo de datos incorporado, use una estructura. Como las estructuras se pasan por copia, debe asegurarse de que sean pequeñas, de unos 16 bytes.
fuente
Es un tema antiguo, pero quería proporcionar una prueba de referencia simple.
He creado dos archivos .cs:
y
Ejecutar punto de referencia:
Resultados:
fuente
Hmm ...
No usaría la recolección de basura como argumento a favor / en contra del uso de estructuras vs clases. El montón administrado funciona de manera muy similar a una pila: crear un objeto simplemente lo coloca en la parte superior del montón, que es casi tan rápido como asignarlo en la pila. Además, si un objeto es de corta duración y no sobrevive a un ciclo de GC, la desasignación es gratuita, ya que el GC solo funciona con memoria que aún es accesible. (Busque MSDN, hay una serie de artículos sobre administración de memoria .NET, soy demasiado vago para ir a buscarlos).
La mayoría de las veces uso una estructura, termino pateándome por hacerlo, porque luego descubro que tener una semántica de referencia habría hecho las cosas un poco más simples.
De todos modos, esos cuatro puntos en el artículo de MSDN publicado anteriormente parecen una buena guía.
fuente
class MutableHolder<T> { public T Value; MutableHolder(T value) {Value = value;} }
, y luegoMutableHolder<T>
será un objeto con semántica de clase mutable (esto funciona igual de bien siT
es una estructura o un tipo de clase inmutable).Las estructuras están en la pila, no en el montón, por lo tanto, son seguras para subprocesos y deben usarse al implementar el patrón de objetos de transferencia, nunca querrá usar objetos en el montón, son volátiles, en este caso desea usar la pila de llamadas, Este es un caso básico para usar una estructura. Estoy sorprendido por las respuestas completas aquí,
fuente
Creo que la mejor respuesta es simplemente usar struct cuando lo que necesita es una colección de propiedades, clase cuando es una colección de propiedades Y comportamientos.
fuente