Buenas prácticas en C# (Parte 2)
Hola y bienvenidos a un nuevo artículo del blog. Seguimos con las buenas prácticas en C# para Unity, este será el segundo artículo sobre este tema. Hoy veremos desde el punto 8 hasta el 10, si quieres refrescar la memoria puedes encontrar el primero aquí.
Buenas prácticas en C#
RECOMENDACIONES PARA C#
- Usa nombres descriptivos en tus variables (y funciones)
- Usa clases de utilidad para tareas comunes
- Almacena la información en objetos en lugar de arrays
- No abuses de las variables estáticas
- Alinea el código con las llaves en vertical
- Crea las variables como privadas si no planeas compartirlas
- Evita los comentarios innecesarios (si usas bien el punto 1).
- Usa Enums
- Evita funciones con muchos parámetros. Si es necesario usa un struct.
- No silencies los errores (Exception)
BONUS: ESPECÍFICAS PARA UNITY
- Guarda las referencias necesarias en el Start()
- Usa print() en todas partes
- No todo son GameObjects
- Usa «requiredcomponent»
- Update vs FixedUpdate
Vamos allá, continuamos con C# estándar.
Usa Enums
Hace no tanto tiempo, este código era común:
int TIPO_ORDENACION_FECHA = 0;
int TIPO_ORDENACION_NOMBRE = 1;
int TIPO_ORDENACION_APELLIDO = 2;
void ordenar(int tipoOrdenacion)
{
if (tipoOrdenacion == TIPO_ORDENACION_FECHA)
{
…
}
}
En esencia no está mal, y se usa así:
ordenar(TIPO_ORDENACION_FECHA);
pero qué pasa si alguien con prisa hace esto?
ordenar(7);
El programa compila y ejecuta perfectamente, lo que pasa es… Que no pasa nada. No ordena nada. Es cierto que podemos poner un “else” en nuestro programa y generar un error, pero de entrada es confuso porque el “int” no nos da ninguna información de lo que tenemos que enviar.
Una forma más limpia de hacer esto sería:
public enum Tipo_Ordenacion
{
fecha,
nombre,
apellido
}
void ordenar(Tipo_Ordenacion tipo)
{
if (tipo == Tipo_Ordenacion.fecha)
{
…
}
}
y para usarlo, haríamos:
ordenar(Tipo_Ordenacion.fecha)
de nuevo, si probamos:
ordenar(7)
nos dará un error (lo que es bueno) porque 7 es un int y la función quiere un valor de tipo “Tipo_Ordenacion”.
Evita funciones con muchos parámetros. Si es necesario usa un struct.
Observa la siguiente función
void guardarEnBaseDatos(String nombre, String apellido1, String apellido2, int edad, String email, int telefono, String pais, String ciudad, String calle)
aún faltarían parámetros, pero para el ejemplo es suficiente. Cuando vamos a usar la función, encontramos algo así:
guardarEnBaseDatos(“Antonio”, “García”, “fernández”, 25, “antonio@gmail.com, 655455655, “España”, “Barcelona”, “Carrer de les camelies 33”)
Funcionaría, pero a mi parecer es engorroso (por lo menos). Hay una alternativa, primero creamos un struct de tipo Persona:
struct Persona
{
String nombre:
String apellido1;
String apellido2;
int edad;
String email;
int telefono;
String pais;
String ciudad;
String calle;
}
después podemos dar valores a ese struct, así:
Persona pers = new Persona();
pers.nombre = “Antonio”;
pers.apellido1 = “García”;
pers.apellido2 = “Fernández”;
pers.edad = 25;
pers.email = “antonio@gmail.com”;
pers.telefono = 655455655;
pers.pais = “España”;
pers.ciudad = “Barcelona”
pers.calle = “Carrer de les camelies 33”;
y pasar el struct a la función, así:
guardarEnBaseDatos(pers);
El lado “malo” de esta solución es la extensión: Es más largo de escribir. El bueno, en cambio es que prevenimos errores como éste:
guardarEnBaseDatos(“Antonio”, “García”, “fernández”, 25, “antonio@gmail.com, 655455655, “Barcelona”, “España”, “Carrer de les camelies 33”)
es muy sutil, pero si comparamos con el “correcto”:
guardarEnBaseDatos(“Antonio”, “García”, “fernández”, 25, “antonio@gmail.com, 655455655, “España”, “Barcelona”, “Carrer de les camelies 33”)
hay un error al introducir los datos, el país es Barcelona y la ciudad España (toma ya).
Con el uso del struct, o una clase “Persona” normal y corriente, prevenimos este error.
Está claro que si son pocos parámetros, no es buena solución. La expresión es “matar mosquitos a cañonazos”, como en el ejemplo a continuación:
guardarEnBaseDatos(“Antonio”, “García”);
Si solo son 2 parametros, no tiene sentido crear el Struct con todo lo que conlleva.
No silencies los errores (Exception)
Y llegamos por fin al último de los pecados capitales en c#, peor a mi modo de ver el más dañino de todos: Silenciar los errores, o “esconderlos para que no hagan feo”. Puedes encontrar un ejemplo a continuación:
void List<Persona> listarClientes()
{
List<Persona> personas = new List<Persona>();
try
{
myConnection.Open();
………..
………..
………..
personas.Add(…);
}
catch (Exception ex)
{
//aquí no ha pasado nada
}
return personas;
}
Como ves, en la parte en negrita (catch) es donde capturamos el error que puede suceder. Cosas como un corte de internet, el servidor de base de datos desconectado o caído, un usuario y contraseña cambiados que nis impiden conectar… De nada de eso nos enteraremos, porque el lugar destinado para controlar el error no controla nada.
Donde pone //aquí no ha pasado nada debería haber (como mínimo) esto:
Console.WriteLine(ex.Message);
Con esa línea, tan “poca cosa” aparentemente, evitaremos horas y horas de buscar errores y comportamientos inesperados en nuestro programa. Es como permitir que nuestro programa diga “ay!” cuando le duele algo, porque si no lo sabemos le seguirá doliendo… Y al final lo pagaremos nosotros (después de todo el ordenador no sufre, no tiene sentimientos).
y hasta aquí el artículo de hoy. Hemos terminado con c#, así que en el siguiente nos pondremos con los de Unity.
¡Feliz semana!