10 Motivos para aprender C#


C # es un lenguaje para escribir aplicaciones .NET. No es exclusiva en este papel (Visual Basic, C ++, Java, COBOL, Python y Perl, entre otros, tienen compiladores que generan código que ejecutable en .NET), pero fue creado específicamente para apoyar características que se encuentran en el plataforma de desarrollo.

Fue diseñado por Anders Hejlsberg, que también creó el lenguaje de programación Delphi. Está estandarizado por la ECMA y dentro de poco lo estará por la IEEE.


C # tiene una serie de ventajas sobre el lenguaje Java. Las cuales situan a C # como un lenguaje “mejor” en mi opinión, aun así las preferencias del lenguaje de programación tienden a ser muy variadas y dependen del tipo de aplicación que vayamos a escribir, pero si lo que os gusta de Java es su sintaxis, existe un compilador de Java llamado J # que ofrece algunas de las ventajas de C#, entre otras, hacer aplicaciones para en .NET.


En otras palabras, no veais esta lista como un intento de convenceros de renunciar a otros lenguajes de programación. La mayoría de los programadores que han pasado unos años en la industria aprenden un gran número de lenguajes, pero C# es el que me ha resultado más interesante hasta ahora.

1. Foreach:


Bastante simple, pero extremadamente util en un lenguaje de programación, y algo que viene directamente de el mundo de Visual Basic.


Su funcionamiento es parecido a un bucle for, itera sobre los elementos de una colección y permite hacer cosas con cada elemento


Si tenemos un array  (miArray) y queremos imprimir sus elementos por pantalla, es tan sencillo como:


foreach (int x in myArray) { Console.WriteLine(x); }

2. No son necesarias especificaciones para las excepciones anidadas:


En mi experiencia como programador de Java, es muy común obtener una excepción que no es la verdadera causa del problema. Busco la ubicación en el código fuente para ver donde se produce la excepción, sólo para descubrir que la excepción fue arrojado dentro de un catch, ocultando la excepción original, y posiblemente, la causa real del problema.


Esto se produce por una regla que dice que hay que declarar en todos los métodos las excepciones que pueden saltar. Como esta lista puede ser bastante grande para los métodos que llaman a otros métodos que ya tienen sus excepciones, es práctica común especificar una excepción generica que contenga el resto en la biblioteca, creando excepciones derivadas de esa base según sea necesario.


Esta práctica da lugar a que la causa de las excepciones sean “comidas” por las bibliotecas de excepciones que se encuentran más arriba en la pila de llamadas. Esto se complica por la falta de excepciones anidadas en la biblioteca base de Java. El resultado final es que los usuarios de una biblioteca que no han hecho ellos, tienden a no encontrar lo que realmente está causando el problema.


En otras palabras, el no tener que especificar todas las posibles excepciones es algo bueno, ya que ahora es menos probable que se oculte la excepción más concreta, porque salte antes la genérica.

3. Propiedades:


Es cierto que Java puede usar propiedades, pero no se identifican de forma única como tal en los metadatos clase. Los programadores de Java especifican métodos ordinarios como propiedades utilizando los “get” para la recuperación de la propiedad y “set” para ajustar el valor.


Por el contrario, .NET en general y C #, en particular, incluyen a las propiedades como entidades separadas de métodos. System.Type incluye métodos para recuperar propiedades (System.Type.GetProperties y System.Type.GetProperty). Y para añadir alterar u operar con las propiedades de un método es tan sencillo como:


Person person = new Person(); //Creamos un objeto que tiene una propiedad name

person.Name = “Joe”;  // damos un valor a su propiedad              

System.Console.Write(person.Name);  // imprimimos la propiedad por pantalla

4. Indexadores:


C # permite que los objetos sean tratados como arrays mediante el uso de un indexador. El indexador puede tomar y devolver cualquier tipo de valor. Por ejemplo, puedes acceder al contenido de una colección de objetos por un índice (un entero), por un nombre (un string), u otro objeto.


La presencia de los indexadores en C # explican por qué ArrayList y Hashtable se tratan con la sintaxis de un array. Existen clases para crear diferentes estructuras de datos en Java, pero tratarlos como un Array hace la vida mucho más sencilla.


Ejemplo que usa indexadores con int

using System;

class Layout
{
   string[] _values = new string[100];

   public string this[int number]
   {
get
{
   // Esto se invoca cuando se accede a instancias del Layout con [ ].
&nbsp;&nbsp;&nbsp;if (number >= 0 && number < _values.Length)
&nbsp;&nbsp;&nbsp;{
// si está en rango devolvemos el valor.
return _values[number];
&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;// si no, devolvemos un string error.
&nbsp;&nbsp;&nbsp;return “Error”;
}
set
{
&nbsp;&nbsp;&nbsp;// Esto se invoca cuando se asignan instancias del Layout con [ ].
&nbsp;&nbsp;&nbsp;if (number >= 0 && number < _values.Length)
&nbsp;&nbsp;&nbsp;{
// Lo asignamos.
_values[number] = value;
&nbsp;&nbsp;&nbsp;}
}
&nbsp;&nbsp;&nbsp;}
}

class Program
{
&nbsp;&nbsp;&nbsp;static void Main()
&nbsp;&nbsp;&nbsp;{
// Creamos una nueva instancia y agregamos los elementos
//en el array, a través del indexador.
Layout layout = new Layout();
layout[1] = “Frank Gehry”;
layout[3] = “I. M. Pei”;
layout[10] = “Frank Lloyd Wright”;
layout[11] = “Apollodorus”;
layout[-1] = “Error”;
layout[1000] = “Error”;

// Leemos los elementos que están en el indexador.
string value1 = layout[1];
string value2 = layout[3];
string value3 = layout[10];
string value4 = layout[11];
string value5 = layout[50];
string value6 = layout[-1];

// Escribimos los resultados.
Console.WriteLine(value1); // devuelve Frank Gehry
Console.WriteLine(value2); // devuelve I. M. Pei
Console.WriteLine(value3); // devuelve Frank Lloyd Wright
Console.WriteLine(value4); // devuelve Apollodorus
Console.WriteLine(value5); // devuelve null

Console.WriteLine(value6); // devuelve error
&nbsp;&nbsp;&nbsp;}
}

5. El preprocesador.


En Java, se podía usar un preprocesador del estilo de C y C++, pero se desechó debido al uso “irresponsable” de macros en el código. Los preprocesadores, sin embargo, no son sólo utilizados para hacer macros. También se utilizan para gestionar la compilación condicional.


La compilación condicional permite a los programadores incluir código opcional en el ejecutable final, basado en la presencia de ciertas constantes del preprocesador. Por ejemplo, un uso común de compilación condicional es por la inclusión de código de depuración. Dicho código de depuración puede realizar operaciones que no querrías presentes en el programa terminado. La compilación condicional permite que este código sea incluido o excluido según sea necesario.


Ejemplo:


#define Debug &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Debugging on

class Hello

{

&nbsp;&nbsp;static void Main() {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Console.WriteLine(@”hello, //Vamos a imprimir por pantalla hello, …

#if Debug

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;world &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Si estamos en debug world

#else

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nebraska &nbsp;&nbsp;&nbsp;&nbsp;//Si no lo estamos Nebraska &nbsp;&nbsp;&nbsp;&nbsp;

#endif &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Terminamos la condición de estar o no en debug

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;”); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Cerramos el Writeline (Impresión por pantalla)

&nbsp;&nbsp;}

}


Esto resulta más util ahora que nunca, en muchas situaciones se desarrollan apps para dispositivos móviles, y cuando las estamos desarrollando y queremos probarlas, en algunos casos nos interesa que acepte otros inputs, por ejemplo, nos interesa usar click izquierdo en nuestra app, podemos usar “#define Debug” para que al correr la app en el ordenador acepte código que acepte dicho input, pero evidentemente no queremos que esté presente en la versión final para móviles de la app.

6. Se pueden usar bloques de código para tener una mejor gestión de la memoria.


En lenguajes como C ++, se puede determinar exactamente que memoria vamos a usar en cada momento y cuando la liberamos, esto se puede hacer mediante el operador delete.


En java, esto no es posible, la memoria se administra durante el tiempo de ejecución, lo que significa que no se puede saber con exactitud cuándo se destruirán sus objetos. La solución que se suele usar en Java es definir un método “close()” en los objetos que requieren una limpieza inmediata, la pega es que el método se tiene que llamar en todos los casos, tanto si hemos salido de el bloque de código normalmente como si no, por lo que si salta alguna excepción o el programa se cierra inesperadamente, se producen los infames “memory leaks”.

En C#, el funcionamiento es similar, también se puede invocar “close” o “dispose” (que es más reciente y seguro) pero para evitar los problemas de Java, tenemos el comando “using”, en conclusión el manejo de memoria acaba siendo mucho más seguro, sobre todo cuando tratamos ficheros o bases de datos con un acceso exclusivo y tenemos que abrirlos o cerrarlos, nos asegura evitar conflictos sin la necesidad de usar semáforos, que pueden llegar a ser bastante ineficientes.


obj.Dispose(); // asi hemos liberado este objeto


using (Font font1 = new Font(“Arial”, 10.0f)) &nbsp;//Ejemplo de un using

{

&nbsp;&nbsp;&nbsp;byte charset = font1.GdiCharSet;

}

7. Organización más flexible del código fuente.


En Java, las clases deben estar definidas en un archivo con el nombre dependiente de la clase pública que lo contiene. Además, el programador debe colocar el código fuente en una estructura de directorio que coincida con el paquete asociado de la clase. Por ejemplo, si la directiva del paquete en la parte superior se llama “nombre.core”, los archivos de código deben situarse en un directorio en un directorio llamado nombre/core.


Nunca me ha gustado esta restricción. Para pequeñas aplicaciones, no es necesario mantener una jerarquía tan estricta, y en todo caso, debería corresponder a los desarrolladores decidir dónde colocar sus archivos para encontrarlos más fáclimente en el futuro. Aparte si mueves un fichero para adaptarlo a otro programa, como la nomenclatura es tan estricta, el proceso de adaptación acaba siendo más largo de lo que debería ser. C # no te obliga a seguir estas directrices.

8. Invocaciones nativas muy sencillas:


Muchos programadores de Java, se han dado por vencidos en este aspecto, hacer invocaciones nativas en java es muy tedioso, porque JNI es una API de C terriblemente desordenada. Hay razones para llamar a código nativo, y casos donde es necesario hacerlo, y en Java, es demasiado enrevesado.


C # hace que sea muy sencillo especificar una función de biblioteca para su uso en una clase mediante el uso de PInvoke (Platform Invoke) para llamar a DLLs que pueden ser llamadas por otros programas.

9. Atributos:


Los atributos son una pequeña pieza de información que se inserta de forma declarativa en el propio código, por ejemplo podemos hacer que salte un ”Warning” diciendo que el método que vamos a usar esta obsoleto colocando [Obsolete] al principio del método, pueden también recibir parámetros, [Obsolete, true] convierte el warning en un error, son editables y creables, están disponibles en muchos lenguajes, ya que forman parte de las CLI (common language infrastructure) de .NET y Java, pero solo en .NET puede accederse a esta información durante el tiempo de ejecución.


Los atributos pueden ser aplicados a nivel de clase, interfaz, estructura, método, propiedad, parámetros y valor de retorno, podemos leer esta información en el tiempo de ejecución y actuar en consecuencia, esto es bastante difícil verle la utilidad, hasta que la tienes que usar en un caso práctico.


Atributo personalizado que describe la longitud de caracteres para una propiedad de una clase.


[AttributeUsage(AttributeTargets.Property)]
class Check : Attribute
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int MaxLength { get; set; }
}


Aquí se usa para comprobar que la longitud no supera 10


class Customer
&nbsp;&nbsp;&nbsp;{
private string _CustomerCode;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Check(MaxLength = 10)] //Usamos el atributo
public string CustomerCode
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
get { return _CustomerCode; }
set { _CustomerCode = value; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;}


Java intenta emular atributos usando XDoclet, que es el código fuente marcado por etiquetas JavaDoc personalizadas. Esta información no está disponible en tiempo de ejecución, y es sobre todo una herramienta para la generación de código fuente durante o antes de la compilación del programa.

10. Plataformas de destino de tu aplicación


Java nos lleva prometiendo “Compile once, run everywhere” desde hace muchos años, y aunque han resuelto la mayoría de los problemas, muchas veces tenemos que acabar haciendo debug para cada plataforma, y en algunos casos, en cada dispositivo. Por cosas como estas se ha llegado a la conclusión que es mejor desarrollar las aplicaciones específicamente para cada plataforma.


C# ofrece una solución a medio camino, “write once, adapt interface and compile everywhere”, escribe tu código una vez, adapta la interfaz a la plataforma objetivo y compila donde quieras, esta es la solución definitiva, permite mantener la gran mayoría del código aunque desarrolles para diferentes plataformas, y ofrecer aplicaciones nativas.


Esto se puede hacer gracias a Visual Studio para los PC (del cual puedes aprender más en este artículo), que te permite compilar tanto en Windows, Linux y OS X. Y con addons o apps de terceras partes como Xamarin para plataformas móviles.


Conclusión

C # es en la gran mayoría de los casos, el lenguaje más versátil, cómodo y útil de .NET. Fue escrito explícitamente para apoyar características encontradas en .NET, la mayoría de los programadores .NET se encontrarán con código C # frecuentemente, y tendrán que adquirir familiaridad con el mismo.


C # es un lenguaje interesante, y espero que te hayan entrado ganas de aprenderlo. Para aquellos interesados en la programación .NET, C # es en mi opinión la más valiosa adición a la caja de herramientas del programador.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *