Así que mi profesor me devolvió comentarios sobre un proyecto en el que he estado trabajando. Atracó algunas marcas para este código:
if (comboVendor.SelectedIndex == 0) {
createVendor cv = new createVendor();
cv.ShowDialog();
loadVendors();
}
Esto se encuentra en un controlador combinado de "índice cambiado". Se utiliza cuando el usuario desea crear un nuevo proveedor, mi opción principal (índice 0, que nunca cambia) abre el cuadro de diálogo "Crear un nuevo proveedor". Entonces el contenido de mi cuadro combinado termina luciendo así:
Create New Vendor...
Existing Vendor
Existing Vendor 2
Existing Vendor 3
Su problema es con el código de la primera línea:
if (comboVendor.SelectedIndex == 0)
Afirma que el 0 debería ser una constante, y en realidad me atracó marcas debido a eso. Afirma que no debería usar literales en mi código en absoluto.
La cuestión es que no entiendo por qué querría hacer que ese código en esa situación sea una constante. Ese índice nunca cambiará, ni es algo que deba modificar. Parece un desperdicio de memoria mantener un solo 0 en la memoria que se usa para una situación muy específica y que nunca cambia.
-1
instr.indexOf(substr) != -1
"str
contienesubstr
están perfectamente justificadas. Pero aquí, el significado del 0 no es obvio (¿cuál es la relación con la creación de un nuevo proveedor?) Ni es realmente constante (¿y si cambia la forma de crear un nuevo proveedor?).int.Zero
para hacerlo feliz :)Respuestas:
La forma correcta de hacer esto en C # es no confiar en el orden de los ComboItems .
fuente
El orden en el cuadro combinado podría cambiar. ¿Qué sucede si agrega otra opción como "Crear proveedor especial ..." antes de "Crear nuevo vendedor ..."
La ventaja de usar una constante es que si hay muchos métodos que dependen del orden del cuadro combinado, solo tiene que cambiar la constante y no todos los métodos si esto cambia.
Usar una constante también es más legible que un literal.
La mayoría de los idiomas compilados sustituirán la constante en el momento de la compilación, por lo que no hay penalización de rendimiento.
fuente
Esta situación que describe es una decisión judicial, personalmente no usaría una si solo se usa una vez y ya es legible.
Sin embargo, la verdadera respuesta es que él eligió esto para darte una lección.
No olvide que es profesor, su trabajo es enseñarle codificación y mejores prácticas.
Yo diría que está haciendo un muy buen trabajo en realidad.
Seguro que puede parecer un poco absoluto, pero estoy seguro de que lo pensarás de nuevo antes de usar números mágicos.
También se metió en tu piel lo suficiente como para que te unieras a una comunidad en línea sobre programadores solo para descubrir qué se considera una mejor práctica en esta situación.
Felicitaciones a su profesor.
fuente
El hecho de que tuvieras que explicar eso prueba por qué deberías usar una constante. Si introdujo una constante como
NEW_VENDOR_DIALOG
, su código se explicaría más por sí mismo. Además, los compiladores optimizan las constantes, por lo que no habrá un cambio en el rendimiento.Escribir programas para programadores, no compiladores. A menos que esté tratando específicamente de micro-optimizar, lo que no parece ser.
fuente
Estoy de acuerdo El uso de cero aquí es "mágico". Imagine que está leyendo este código por primera vez. No sabes por qué cero es especial, y el literal no te dice nada acerca de por qué cero es especial. Si en cambio dijiste
if(comboVendor.SelectedIndex == CreateNewVendorIndex)
, se vuelve extremadamente claro para el lector primerizo lo que significa el código.Esa es una posición extrema; Una posición realista sería decir que el uso de literales es una bandera roja que indica que el código podría no ser tan claro como podría ser. A veces es apropiado.
Que nunca cambiará es una excelente razón para hacerlo constante . Es por eso que las constantes se llaman constantes; porque nunca cambian
De Verdad? No puedes ver ninguno situación en la que alguien quiera cambiar el orden de las cosas en un cuadro combinado?
El hecho de que pueda ver una razón por la cual esto podría cambiar en el futuro es una buena razón para no hacerlo constante. Más bien debería ser un campo entero estático de solo lectura no constante. Una constante debe ser una cantidad que se garantice que permanezca igual durante todo el tiempo . Pi y el número atómico de oro son buenas constantes. Los números de versión no son; Cambian cada versión. El precio del oro es obviamente una constante terrible; Cambia cada segundo. Solo haga cosas constantes que nunca, nunca cambien .
Ahora llegamos al quid de la cuestión.
Esta es quizás la línea más importante en su pregunta porque indica que tiene una comprensión profundamente defectuosa de (1) memoria y (2) optimización. Estás en la escuela para aprender, y ahora sería un buen momento para obtener una comprensión correcta de los fundamentos. ¿Puede explicar en detalle por qué cree que "es un desperdicio de memoria mantener un solo cero en la memoria"? En primer lugar, ¿por qué cree que es importante optimizar el uso de cuatro bytes de memoria en un proceso con al menos dos mil millones de bytes de almacenamiento direccionable por el usuario? Segundo, precisamente , ¿qué recurso imaginas que se consume aquí? ? ¿Qué quieres decir con "memoria" consumida?
Estoy interesado en las respuestas a estas preguntas primero porque son una oportunidad para que aprenda cómo su comprensión de la optimización y la gestión de la memoria es incorrecta, y segundo porque siempre quiero saber por qué los principiantes creen cosas extrañas, para poder diseñar mejores herramientas para llevarlos a tener creencias correctas.
fuente
El tiene razón. Tienes razón. Te equivocas.
Tiene razón, conceptualmente, que se deben evitar los números mágicos. Las constantes hacen que el código sea más legible al agregar contexto a lo que significa el número. En el futuro, cuando alguien lea su código, sabrá por qué se utilizó un número en particular. Y si necesita cambiar un valor en algún punto de la línea, es mucho mejor cambiarlo en un lugar en lugar de intentar buscar en todas partes donde se usa un número en particular.
Dicho esto, tienes razón. En este caso específico, realmente no creo que se justifique una constante. Está buscando el primer elemento de la lista, que siempre es cero. Nunca será 23. O -pi. Usted está buscando específicamente cero. Realmente no creo que necesites abarrotar el código haciéndolo constante.
Sin embargo, está equivocado al suponer que una constante se lleva a cabo como una variable, 'usar memoria'. Existe una constante para el humano y el compilador. Le dice al compilador que ponga ese valor en ese lugar durante la compilación, donde de lo contrario habría puesto un número literal. E incluso si llevara la constante en la memoria, para todas las aplicaciones excepto las más exigentes, la pérdida de eficiencia ni siquiera sería medible. Preocuparse por el uso de la memoria de un solo entero definitivamente cae en 'optimización prematura'.
fuente
Hubiera reemplazado el
0
con una constante para aclarar el significado, comoNewVendorIndex
. Nunca se sabe si su pedido cambiará.fuente
Esa es la preferencia total de tu profesor. Por lo general, solo usa una constante si el literal se usará varias veces, desea que sea obvio para el lector cuál es el propósito de la línea, o su literal posiblemente cambiará en el futuro, y solo desea cambiar en un solo lugar Sin embargo, para este semestre, el profesor es el jefe, por lo que lo haría a partir de ahora en esa clase.
¿Buena formación para el mundo corporativo? Muy posiblemente.
fuente
Para ser honesto, aunque no creo que su código sea la mejor práctica, su sugerencia es francamente un poco grotesca.
Una práctica más común para un cuadro combinado .NET es dar al elemento "Seleccionar .." un valor vacío, mientras que los elementos reales tienen valores significativos, y luego hacen:
más bien que
fuente
No está equivocado por enfatizar el valor del uso de constantes y usted no está equivocado al usar literales. A menos que haya enfatizado que este es el estilo de codificación esperado, no debe perder marcas por usar literales ya que no son dañinos. He visto literales usados por todas partes muchas veces en el código comercial.
Sin embargo, su punto es bueno. Esta puede ser su forma de informarle sobre los beneficios de las constantes:
1-Protegen su código hasta cierto punto de alteraciones accidentales
2-Como dice @DeadMG en su respuesta, si se usa el mismo valor literal en muchos lugares, puede aparecer con un valor diferente por error, por lo que las constantes preservan la consistencia.
Las 3 constantes conservan el tipo, por lo que no tiene que usar algo como 0F para significar cero.
4-Para facilitar la lectura, COBOL usa CERO como una palabra reservada para el valor cero (pero también le permite usar el cero literal) - Entonces, dar un nombre a un valor a veces es útil, por ejemplo: (Fuente: ms-Constantes
o como en su caso (como se muestra en la respuesta de @Michael Krussel)
fuente
int weeks = 52
, no hay 52 semanas por año. Hay 52.142857142857146 semanas en un año, y ese es el número en el que debe mantener las fracciones. Por supuesto, lo único que es realmente constante en todo ese conjunto de constantes es la cantidad de meses.Solo necesitaría ponerlo en una constante si tiene una derivación compleja, o si se repite con frecuencia. De lo contrario, un literal está bien. Poner todo en una constante es una exageración total.
fuente
En realidad, como se mencionó, ¿qué pasa si se trata de cambios de posición? Lo que podría / debería hacer es usar un código, en lugar de confiar en el índice.
Entonces, cuando crea su lista de selección, termina con html como
Luego, en lugar de verificar
selectedIndex === 0
, verifique que el valor sea elCREATECODE
que estaría en una constante y se hubiera utilizado tanto para esta prueba como para crear la lista de selección.fuente
Me desharía de eso por completo. Simplemente coloque un botón Crear nuevo junto a la lista del cuadro combinado. Haga doble clic en un elemento de la lista para editar, o haga clic en el botón. No tenga la nueva funcionalidad enterrada en el cuadro combinado. Entonces el número mágico se elimina por completo.
En general, cualquier número literal en el código debe definirse como una constante para poner el contexto alrededor del número. ¿Qué significa cero? En este caso 0 = NEW_VENDOR. En otros casos, puede significar algo diferente, por lo que siempre es una buena idea para la legibilidad y la facilidad de mantenimiento poner algo de contexto a su alrededor.
fuente
Como han dicho otros, debe usar otro método que no sea el número de índice para identificar el elemento del cuadro combinado que corresponde a una acción determinada; o puede encontrar el índice con alguna lógica programática y almacenarlo en una variable.
La razón por la que escribo es para abordar su comentario sobre el "uso de la memoria". En C #, como en la mayoría de los lenguajes, el compilador "dobla" las constantes. Por ejemplo, compile el siguiente programa y examine el IL. Encontrará que todos esos números ni siquiera llegan al IL, y mucho menos a la memoria de la computadora:
IL resultante:
Entonces, ya sea que use una constante, un literal o un kilobyte de código usando aritmética constante, el valor se trata literalmente en la IL.
Un punto relacionado: el plegado constante se aplica a los literales de cadena. Muchos creen que una llamada como esta causa demasiada concatenación de cadenas innecesaria e ineficiente:
Pero mira el IL:
En pocas palabras: los operadores en expresiones constantes dan como resultado expresiones constantes, y el compilador hace todo el cálculo; no afecta el rendimiento en tiempo de ejecución.
fuente