variable tipos tipo publicas inicializar español declarar datos c# coding-style code-review

tipos - Alcance de variables en C#



variable tipo char c# (15)

  1. No es legible, ya que si tiene una función larga, debe tener un gran alcance de declaración después del alcance de inicialización

Esto solo indica que necesita refactorizar el código. De hecho, es bueno que las declaraciones a futuro te obliguen a pensar en esto.

No es absolutamente más rápido, ya que asigna memoria innecesaria y bombea la pila de funciones.

Idealmente, no lo haces. Si alguna rama de su código necesita asignar objetos que son ortogonales al resto de la función, es mejor descargar esta rama en una función separada.

De esta manera usted también mantiene el principio de "declarar donde lo usa".

Tengo una pregunta para ustedes sobre la escritura del código C #: Tuve un largo debate con mi colega: Él dice que al declarar e iniciar todas las variables al principio de la función, el código es más fácil de leer y rápido .

Por favor, dame al menos una razón sensata para que sea correcto.

1. No es legible, ya que si tiene una función larga, tiene que tener un gran alcance de declaración después del alcance de inicialización, por lo que es mucho más fácil declarar la variable que necesita donde la necesita, por lo que la verá frente a usted.

2. No es absolutamente más rápido, ya que asigna memoria innecesaria y bombea la pila de funciones.

Este ejemplo de pseudo código mío:

public void A(double dParam) { if(... condition ... ) { double dAnotherParam; string sParam; ... // use local scope vars here } }

Ejemplo de pseudo código:

public void A(double dParam) { double dAnotherParam; string sParam; dAnotherPatam = 0; sParam = null; if(... condition ... ) { ... } }

¿Alguna idea sobre el tema?

Gracias de antemano.


No es legible, ya que si tiene una función larga, tiene que tener un gran alcance de declaración después del alcance de inicialización, por lo que es mucho más fácil declarar la variable que necesita donde la necesita, por lo que la verá frente a usted.

Tampoco entiendo cómo sería más legible. Aleja la declaración de la sección de código que intenta usarla y da como resultado la pérdida de pistas de proximidad.

No es absolutamente más rápido, ya que asigna memoria innecesaria y bombea la pila de funciones.

El argumento de que es más rápido también es erróneo. No importa en qué parte del método se declara una variable, todavía ocupa la misma cantidad de espacio en la pila. Así que no hay diferencias fundamentales en el rendimiento que yo sepa. Sin embargo, podría argumentar que las declaraciones con inicializaciones en línea consumirían ciclos de CPU adicionales si la inicialización se considera innecesaria. Por ejemplo, puede declarar e inicializar una variable dentro de un bloque if , en cuyo caso la inicialización ocurre solo si la ejecución se introduce en ese bloque. Compare esto con lo que sucedería si hiciera la declaración y la inicialización en la parte superior del método.

1 Supongo que podría haber algunas consecuencias extrañas del método de alineación o similares que podrían afectar esto, pero lo dudo.


Declara las variables en el ámbito que pretendes utilizarlas.


El punto de su colega es de la programación de la vieja escuela. No es que sea malo, pero esto viene del lenguaje ensamblador.

Al comienzo de un código de ensamblaje, tenía que declarar el registro DS (Segmento de datos) que hizo alguna asignación en la pila para reservar algo de memoria. Aquí hay una muestra de código:

.MODEL SMALL .DATA myVariable1 DW "This is my first variable" myVariable2 DB "Second var" .CODE ''code segment :ProgramStart MOV AX,01h ... :ProgramEnd

Como los otros ya han dicho, en los programas de C, las declaraciones de variables debían estar al principio de una función. Al igual que necesitaba escribir las definiciones de sus funciones al comienzo de su programa C, antes de la función main() , luego escriba su cuerpo después de su función principal, de lo contrario, su función (o variable) no se reconoció. Entonces, sí, esto fue más rápido porque la dirección variable ya era conocida por el código en línea generado.

Sin embargo, con la llegada de OOP y la programación de eventos, tendemos a permanecer lo más cerca posible del evento. Lo que quiero decir se resume siendo tu punto de vista. Los compiladores de hoy analizan el código de tales variables en todo el código y lo convierten en un código CLR manejable. Así que esto ya no hace una diferencia, hablando de performance. En la programación de hoy, tendemos a hacer que el código sea tan fácil de leer y entender como sea posible. Dicho esto, esto incluye declaraciones de variables.

Declarar una variable al comienzo de una función, y usarla solo 20 líneas más no sirve, y además hace que el programa sea más difícil de entender. Por ejemplo, estás analizando una pieza de código, ¡entonces salta! Aparece un nombre de variable, pero no hay declaración alrededor. ¿De dónde viene esta variable, preguntas? Deberá desplazarse hacia arriba (o ir a la definición) para averiguar qué es esta variable. Mientras tanto, es posible que haya perdido su idea sobre el propósito de la rutina que realmente estaba leyendo y tratando de entender. Hazlo tres o más veces, y perderás el intento de entender el código.

Es mejor tener un punto de vista ágil y veloz sobre el propósito del código. Es decir, no declarar ninguna variable innecesaria antes de que realmente sea indispensable. Escribir de esta manera evitará que siempre se desplace hacia arriba y hacia abajo mientras lee o escribe el código de un programa.

Estos son mis dos centavos. Espero ser lo suficientemente claro en lo que he estado tratando de explicar.

Espero que esto ayude de todos modos!


El rendimiento no importa porque el compilador se encargará de esto. Al compilador no le importa si los declara en la parte superior del método o justo antes de usarlos.

Sin embargo, tener 20 declaraciones en la parte superior en lugar de declarar la variable cuando la usa no hace que el código sea más legible.

Absolutamente iría por la primera opción.


En cuanto al código que se ejecuta más rápido con todas las variables declaradas en la parte superior de la rutina, yo diría que el caso opuesto es el caso, si hay alguna diferencia en absoluto. No soy un experto en esto, pero asumo que la recolección de basura será más eficiente al declarar las variables en el alcance más bajo posible. De esa manera la limpieza puede ocurrir antes.

Además, al colocar las variables cerca del código que las usa, mejora la legibilidad de la OMI.

Una analogía es que es la diferencia entre tener notas de margen (junto al texto que está leyendo), frente a un muro de notas al pie de la página (no está seguro de qué nota se refiere a qué texto sin hacer una cruz) -referencia de ti mismo).


En mi opinión, la declaración al comienzo de la función es mucho menos legible que la declaración en el alcance más bajo posible. Debe prestar atención a que su código sea legible, ya que esto es mucho más importante que esta optimización de micro velocidad.


Es bastante simple y directo. Esta regla es la que uso en mi código todo el día, todos los días.

Declara las variables en el alcance más bajo que puedas evitar.

Si solo está utilizando una variable dentro de un método, declare en el método, no es necesario colocarlo en el nivel de clase.

Edición: Parece que estás preguntando acerca de las variables de alcance en métodos específicamente.

En ese caso, piénselo de esta manera, si su uso de una variable depende de si una condición es verdadera o no, por qué declararla antes incluso de pasar la condición. Estarías desperdiciando recursos al hacerlo.


Esto es una cuestión de estilo. Mis consideraciones:

  1. Si el bloque de código es pequeño, al final no importará dónde coloque la declaración. Sin embargo, es preferible tener declaraciones más cercanas al uso, principalmente en bloques de código grandes. Primero, de esta manera puede asegurarse de que la variable no se modificó hasta ese punto en el bloque, y segundo, porque puede verificar el tipo y la inicialización de la variable más rápido.

  2. Además, es más rápido codificar al declarar las variables cerca de donde las usas; no tienes que desplazarte al principio del ámbito para declarar una variable olvidada y luego retroceder.

  3. Esto no es más rápido o más lento. Las variables, sin importar dónde se declaren en el alcance, tendrán su asignación e inicialización centradas al comienzo del alcance. Esto se puede verificar generando IL para el idioma.

Por ejemplo, el código:

static void Main(string[] args) { var a = 3; if (a > 1) { int b = 2; a += b; } var c = 10; Console.WriteLine(a + c); }

Genera la siguiente IL:

.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 24 (0x18) .maxstack 2 .locals init ([0] int32 a, // Declare a [1] int32 b, // Declare b [2] int32 c) // Declare c IL_0000: ldc.i4.3 IL_0001: stloc.0 IL_0002: ldloc.0 IL_0003: ldc.i4.1 IL_0004: ble.s IL_000c IL_0006: ldc.i4.2 IL_0007: stloc.1 IL_0008: ldloc.0 IL_0009: ldloc.1 IL_000a: add IL_000b: stloc.0 IL_000c: ldc.i4.s 10 IL_000e: stloc.2 IL_000f: ldloc.0 IL_0010: ldloc.2 IL_0011: add IL_0012: call void [mscorlib]System.Console::WriteLine(int32) IL_0017: ret } // end of method Program::Main

Una cosa importante a tener en cuenta es que las variables en los ámbitos internos, como la variable b, que estaba en el ámbito if, son declaradas en el ámbito del método por el compilador.

Espero eso ayude.


La declaración de variables en la parte superior de un método es muy antigua y está aferrada a C. Me enseñaron exactamente lo mismo en la universidad.

Hoy en día, tratamos de mantener los métodos muy pequeños y magros con parámetros significativos y nombres de métodos. Es mucho más limpio declarar e inicializar una variable dentro del ámbito en el que se va a utilizar. Si hay muchas de estas áreas de código en un método dado, puede ser una indicación de que debe refactorizar métodos más pequeños y fáciles de leer.

La única vez que consideraría hacer esto es cuando quiere inicializar algo dentro de una declaración try catch catch donde quiere hacer algo con el objeto en el catch o bloque final.

SomeObject someObject = null; try { someObject = GetSomeObject(); return someObject.DoSomething(); } finally { if (someObject != null) someObject.DoSomethingElse(); }

La mayoría de las veces, lo único que desea hacer es limpiar el objeto para que una declaración de uso sea más que adecuada, pero a veces es necesario.


Para agregar otro punto, es posible que no siempre desee inicializar las variables que se declaran a nivel de clase. A veces, es posible que desee que estas cosas sean nulas y pruebe activamente para eso.

Además, menciona que tiene métodos muy largos ... los métodos deben ser funcionales, cumplir un propósito particular y luego volver al flujo del programa. Por lo tanto, los métodos a menudo se pueden refactorizar en un código manejable más pequeño.


Parece que tu colega es un viejo programador de C Solía ​​ser que tenías que colocar todas tus variables al comienzo del alcance, y la gente se acostumbraba a hacerlo de esa manera.

En C #, es mejor colocarlos en el ámbito donde se necesitan. Esto tiene algunos beneficios, incluyendo:

  • Reduce el riesgo de error al reutilizar una variable de manera inapropiada, especialmente durante el mantenimiento a largo plazo
  • Mantiene la variable restringida dentro de ese alcance, lo que facilita la refactorización

El último punto es, en mi opinión, el más importante. La buena capacidad de mantenimiento y la capacidad de prueba dependen de la capacidad para mantener pequeños sus métodos, y el hecho de mantener las variables declaradas a medida que se usan hace que la extracción de un método sea mucho más simple. No solo las herramientas se vuelven más efectivas, sino que las refactorizaciones automáticas resultantes tienden a ser más simples (ya que la variable no se pasa por ref, etc.).

En cuanto a su código de ejemplo, yo personalmente lo haría diferente a cualquiera de ustedes. Todavía estás declarando tu variable al principio del ámbito interno. No los declararía hasta que realmente se usen:

public void A(double dParam) { if(... condition ... ) { double dAnotherParam = GetValueFromMethod(); // use local scope vars here // Later, as needed: string sParam = dAnotherParam.ToString(); } }

Declarar esto en la parte superior del alcance (incluso un alcance interno), nuevamente, reduce la capacidad de las herramientas de refactorización automática para que los métodos de extracción no sean exitosos según sea necesario.


Pascal fue uno de los últimos idiomas que aprendí, donde todo tenía que ser declarado por adelantado según el ejemplo de su compañero. Perdónanos, los idiomas anteriores no permitían variables con un alcance cercano a la .NET, por lo que "los viejos hábitos son duros".

El rendimiento ya no es un problema, el costo en programación es la mano de obra. Los compiladores se han vuelto más inteligentes que la mayoría de nosotros, por lo que el problema real es evitar los errores. (Perdóneme por ilustrar en VB, simplemente hago menos errores tipográficos).

Comparar:

Dim X as integer = 0 '' 100 lines of drivel, where I''m forgetting about X For X = 1 To 10 If pornographic(X) then '' Pron integers, geek alert! Viagra(X) End if Next '' 50 lines of drivel, X lurks with his raincoat If X >= 10 Then '' Compiles. X=11, if you''re damn lucky '' make a nasty mistake End if

No te rías, pasa todos los días.

Con:

'' 100 lines of drivel, nothing lurid in sight For X As Integer = 1 To 10 If pornographic(X) then '' Pron integers, geek alert! Viagra(X) End if Next '' 50 lines of drivel, X is no more If X >= 10 Then '' *** FAILS AT COMPILE-TIME *** '' *** CAN''T *** make a nasty mistake End if

Respuesta fácil, ¿verdad?

Maurice

PD: Olvidé declarar: Public Protected Viagra (clipno As Film) ...


Re: legibilidad, tienes toda la razón. Y también considere que la declaración de variables en un ámbito superior pierde cualquier información sobre dónde son relevantes. Un usuario que lo mira necesita leer el método completo para ver dónde se usa una variable. Además, hay más riesgo de usar erróneamente la variable incorrecta.


Una regla general que siempre he seguido es rellenar las variables lo más cerca posible de su declaración, esto significa que no declarar una variable en la línea 10 y luego darle un valor inicial en la línea 100.