Introducción a C# para programadores Java

Java y C# (pronunciado C sharp) son lenguajes de programación con muchas similitudes. No obstante .NET, y C# en particular, fueron la respuesta de Microsoft a la demanda de Sun en la que esta acusaba a la compañía de Redmond de intentar «secuestrar» el lenguaje Java con una implementación incompatible de la máquina virtual, la MSJVM (Microsoft Java Virtual Machine). De no haberse producido esta demanda, quizás las cosas se hubieran desarrollado de forma totalmente distinta, y puede que C# ni si quiera hubiera nacido.

En todo caso C# y Java también tienen muchas e importantes diferencias. C# cuenta, por ejemplo, con características tan interesantes como closures, funciones lambda, generadores, preprocesador, punteros, etc. Este artículo tiene como objetivo servir a modo de pequeña introducción a C# a los programadores Java.

La última versión disponible de C# es la 3.5, de Noviembre de 2007, aunque se está trabajando en importantes e interesantes mejoras para el próximo C# 4.0.

Para poder programar en C# necesitaremos instalar, al menos, el framework .NET, aunque es muy probable que ya lo tengas instalado. De ser así tendrás una carpeta C:\WINDOWS\Microsoft.NET\Framework\v3.5 donde podrás encontrar, entre otras cosas, el compilador de C#, csc.exe (de C Sharp Compiler).

Compilar una clase usando csc es de lo más sencillo. Funciona de forma similar a javac, pasando como argumento los archivos con las clases a compilar. En este caso, no obstante, la extensión de los ficheros es cs, de C Sharp. Para compilar un archivo de código fuente:

csc Ejemplo.cs

Para compilar varios archivos:

csc *.cs

Otra opción a la hora de programar y compilar nuestras aplicaciones es utilizar Visual Studio, el popular entorno de desarrollo de Microsoft. Es posible descargar una versión trial de 90 días del entorno desde la web de Microsoft, así como una versión gratuita recortada llamada Express Edition, ideal para estudiantes y para personas que estén empezando con el lenguaje.

Por último también podemos recurrir a alternativas libres, como es el caso de #develop (SharpDevelop), un IDE muy similar a Visual Studio, salvando las distancias.

En todo caso una vez compilemos nuestro programa el resultado será un exe o una dll, que, como las clases de Java, no contendrá código máquina, sino un lenguaje intermedio para una máquina virtual llamado CIL (Common Intermediate Language). Este código intermedio se compilará a código máquina usando un compilador JIT cuando sea necesario.

El punto de entrada a una aplicación de consola en C# es el método Main. Por convención los nombres de los miembros, las clases, interfaces y espacios de nombres utilizan pascal casing, es decir, la primera letra de cada palabra en mayúsculas.

class Ejemplo {
  static void Main(string[] args) {
  }
}

Main puede devolver void o un int a modo de estado de retorno.

class Ejemplo {
  static void Main(string[] args) {
    return 0;
  }
}

Podemos obviar los argumentos si no vamos a pasar ningún parámetro por línea de comandos, cosa que no podemos hacer en Java.

class Ejemplo {
  static void Main() {
  }
}

Para imprimir un texto en la consola se utilizan los métodos System.Console.Write() y System.Console.WriteLine()

class Ejemplo {
  static void Main() {
    System.Console.WriteLine("Hola mundo");
  }
}

Estos métodos son más parecidos al System.out.printf de Java que a System.out.print y System.out.println, ya que permiten formatear las cadenas.

class Ejemplo {
  static void Main() {
    string usuario = "juan";
    System.Console.WriteLine("Bienvenido {0}", usuario);
  }
}

Para ejecutar el programa en Visual Studio podemos utilizar la combinación de teclas Ctrl + F5, o bien F5 si queremos iniciar el programa con el depurador.

Dependiendo del IDE que utilices puede que te interese añadir una llamada a System.Console.Read() o System.Console.ReadLine() para leer un carácter o una línea de texto desde el teclado antes de terminar la ejecución del programa, y así poder ver el resultado tranquilamente.

class Ejemplo {
  static void Main() {
    System.Console.WriteLine("Hola mundo");
    System.Console.Read();
  }
}

Los tipos predefinidos son similares a Java, a excepción de que existen tipos enteros sin signo, además de un tipo de punto flotante decimal que ofrece mayor precisión que float y double y es similar a la clase BigDecimal de Java. Es posible que en Java 7 BigDecimal soporte operadores, reduciendo así las diferencias con decimal.

Tipos enteros
Tipo Tamaño Significado Equivalencia Java
sbyte 8 bits Byte con signo byte
byte 8 bits Byte sin signo
short 16 bits Entero corto con signo short
ushort 16 bits Entero corto sin signo
int 32 bits Entero con signo int
uint 32 bits Entero sin signo
long 64 bits Entero largo con signo long
ulong 64 bits Entero largo sin signo

Tipos punto flotante
Tipo Tamaño Significado Equivalencia Java
float 32 bits Flotante float
double 64 bits Flotante doble precisión double
decimal 128 bits Flotante alta precisión BigDecimal

Todos los literales con punto se consideran valores de tipo double. Si queremos asignar un literal con coma a una variable de tipo float o decimal tendremos que añadir obligatoriamente el sufijo F o M respectivamente para indicar que el literal es de ese tipo. En caso contrario no compilará.

Esto no compilaría:

class Ejemplo {
  public static void Main() {
    float f = 1.23;
  }
}

Esto si:

class Ejemplo {
  public static void Main() {
    float f = 1.23F;
  }
}
Otros tipos
Tipo Tamaño Significado Equivalencia Java
bool 8 bits Booleano boolean
char 16 bits Caracter unicode char
string Cadena de caracteres unicode String

string es en realidad un simple alias de la clase System.String. No existe, por tanto, ninguna diferencia entre las siguientes formas de crear un objeto cadena. string se sustituye por System.String al compilar.

class Ejemplo {
  public static void Main() {
    string cadena1 = "hola";
    System.String cadena2 = "adios";
  }
}

De igual forma int, long, byte, … son en realidad alias de las clases System.Int32, System.Int64, System.Byte, …

En C# todos los objetos derivan de System.Object, de forma análoga a los objetos de Java que derivan de java.lang.Object. también existe un alias de System.Object que es object.

Los operadores son similares a los de Java: +, -, *, /, %, ==, !=, &, ^, …

La instrucción ifelse funciona igual que en Java, así como los bucles for, while y dowhile. Tenemos también sentencias break y continue, igual que en Java.

Un ejemplo del uso del bucle for:

class Ejemplo {
  public static void Main() {
    int[] numeros = new int[]{1, 2, 3, 4,};
    for (int i = 0; i < numeros.Length; i++)
      System.Console.WriteLine(numeros[i]);
  }
}

Como vemos los arrays también son similares a los de Java.

El bucle foreach tiene una palabra clave propia, a diferencia de Java, que utiliza for. La sintaxis es parecida, sustituyendo los dos puntos (:) de Java por la palabra clave in.

class Ejemplo {
  public static void Main() {
    int[] numeros = {1, 2, 3, 4};
    foreach (int numero in numeros)
      System.Console.WriteLine(numero);
  }
}

Ambos lenguajes tienen en común varios modificadores.

De entre los modificadores de acceso coinciden public (acceso no restringido), private (acceso restringido a la clase contenedora) y protected (acceso restringido a la clase contenedora y a las que la extienden). C# añade un par de modificadores nuevos: internal que indica que un miembro o tipo sólo se puede acceder desde tipos del mismo proyecto o assembly y protected internal que limita el acceso a las clases del proyecto actual y a las clases que extiendan la clase actual.

Por defecto las clases son internal y los miembros de las clases, private.

Otros modificadores en común son abstract, volatile y static. En C# static también se puede utilizar sobre clases para indicar que la clase se compone exclusivamente de miembros estáticos y que no se puede instanciar. En C# también existe un equivalente al inicializador o bloque estático de Java en forma de constructor estático.

public class Reunion {
  public string Nombre;
  public static int ZonaHoraria;

  static Reunion() {
    System.Console.WriteLine("Constructor estático");
    ZonaHoraria = System.TimeZoneInfo.Local.BaseUtcOffset.Hours;
  }

  public Reunion(string nombre) {
    System.Console.WriteLine("Constructor");
    this.Nombre = nombre;
  }
}

class Ejemplo {
  static void Main() {
    Reunion r = new Reunion("Reunión de desarrollo");
    System.Console.WriteLine(r.Nombre);
    System.Console.WriteLine(Reunion.ZonaHoraria);
    System.Console.ReadLine();
  }
}

const se utiliza para crear constantes, convirtiendo una variable en estática e inmutable de forma similar a static final en Java. En Java const es, de hecho, una palabra clave, aunque no se utiliza, por lo que no podemos crear variables o métodos con dicho nombre.

sealed es parecido al final de Java. Al aplicarse sobre una clase, indica que la clase no se puede extender. Al aplicarse a un método, indicada que no se puede sobreescribir. Sin embargo, a diferencia de final, sealed no se puede aplicar sobre variables y sólo es válido para métodos si este reemplaza un método de una clase padre a su vez. Para variables se puede utilizar const o readonly (sólo lectura), que se diferencia del primero en que se puede inicializar tanto en la declaración de la variable como en un constructor, además de no convertirse en estática.

extern es parecido al native de Java. Indica que el método está implementado externamente, posiblemente en otro lenguaje.

El equivalente del modificador transient de Java sería el atributo [NonSerialized]. Los atributos son el equivalente en C# de las anotaciones Java.

[Serializable()]
class MiClase {
  public int Serializable1;
  public string Serializable2;

  [NonSerialized()]
  public int NoSerializable;
}

C# cuenta con muchos otros modificadores que no tienen equivalente directo en Java como override, partial, ref, ...

El modificador ref, por ejemplo, hace que el parámetro indicado se pase por referencia en lugar de por valor, que es el comportamiento estándar de C#. De esta forma las modificaciones que se realicen dentro de la función afectarán a la variable y no serán locales al método. Esto, sin embargo, no es una buena práctica.

class Ejemplo {
  public static void Main() {
    int numero = 10;
    sumar(ref numero);
    System.Console.WriteLine(numero);
  }

  static void sumar(ref int num) {
    num = num + 1;
    System.Console.WriteLine(num);
  }
}

El modificador params se utiliza para crear métodos con número de parámetros variable de forma similar a los varargs en Java.

class Ejemplo {
  public static void Main() {
    imprimir("Uno", "Dos", "Tres");
    System.Console.ReadLine();
  }

  public static void imprimir(params string[] cadenas) {
    foreach (string cadena in cadenas)
      System.Console.WriteLine(cadena);
  }
}

En C# las clases se organizan en namespaces o espacios de nombre, un concepto similar al de los paquetes en Java.

namespace Aplicacion {
  namespace Interfaz {
    class VentanaPrincipal {
    }
  }
}

Para importar un espacio de nombres se utiliza la palabra clave using, que sería algo parecido al import de Java. Comparemos el siguiente código:

class Ejemplo {
  public static void Main() {
    System.Console.WriteLine(System.Math.Sqrt(16));
  }
}

con este otro en el que importamos el espacio de nombres System:

using System;

class Ejemplo {
  public static void Main() {
    Console.WriteLine(Math.Sqrt(16));
  }
}

Las clases y las interfaces tienen el mismo aspecto que en Java.

class Ejemplo {
  int atributo = 10;

  public Ejemplo() {
    Console.WriteLine("Constructor");
  }

  public void saludar() {
    Console.WriteLine("Un método");
  }
}
interface Instrumento {
  public void Tocar();
}

Lo que no existe en Java, a pesar de que sea pan de cada día en muchos lenguajes modernos y no tan modernos, son las propiedades, que ofrecen una forma más elegante de trabajar con getters y setters y que se descartaron para Java 7.

Para utilizar las propiedades creamos por un lado un atributo privado al que se accederá a través de una propiedad, y por otro la propiedad en si misma, que tiene el aspecto de la definición de un atributo seguido de un bloque get y un bloque set (o bien sólo un bloque get si queremos una propiedad de sólo lectura, o sólo un bloque set si queremos una propiedad de sólo escritura).

class Usuario {
  private string nombre;

  public string Nombre {
    get { return nombre; }
    set { nombre = value; }
  }
}

La única peculiaridad a tener en cuenta es el uso de la palabra clave value para referirnos al valor que se está intentando asignar al atributo.

Desde C# 3.0 existe una forma aún más sencilla de definir las propiedades, y es que si la funcionalidad del get o el set va a consistir tan solo en leer o modificar el valor, podemos ahorrarnos el código del bloque y escribir algo así:

class Usuario {
  private string nombre;

  public string Nombre {
    get;
    set;
  }
}

Una vez definida nuestra propiedad podemos acceder o modificar el atributo como si de un atributo cualquiera se tratase, aunque sabemos que por debajo estamos utilizando un método, con todo lo que ello conlleva (podríamos haber hecho, por ejemplo, que se impidiera que se asignara un valor a nombre que tuviera más de 15 letras).

class Usuario {
  private string nombre;

  public string Nombre {
    get; set;
  }
}

class Ejemplo {
  static void Main() {
    Usuario u = new Usuario();
    u.Nombre = "Raúl";
    System.Console.WriteLine("Hola " + u.Nombre);
  }
}

Otro mecanismo parecido a las propiedades del que también carece Java son los indizadores. Estos funcionan igual que las propiedades, con la excepción de que se acceden utilizando un índice en lugar del nombre de la propiedad. Son adecuados por tanto para colecciones.

class Departamento {
  private string[] trabajadores = new string[100];

  public string this[int indice] {
    get { return trabajadores[indice]; }
    set { trabajadores[indice] = value; }
  }
}

class Ejemplo {
  static void Main() {
    Departamento d = new Departamento();
    d[0] = "Raúl González";
    System.Console.WriteLine(d[0]);
  }
}

Los indizadores no están limitados a índices de tipo int, ni a un solo índice.

Otro tipo de método interesante son los destructores, que se declaran de la misma forma que los constructores añadiendo un ~ antes del nombre de la clase.

class BaseDatos {
  ~BaseDatos() {
    System.Console.WriteLine("Cerrando conexión");
  }
}

Como ya hemos comentado las clases pueden extender otras clases, pero en lugar de utilizar la palabra clave extends se utiliza el operador :.

class Persona {
  }

  class Usuario : Persona {
  }
}

También se utiliza el mismo operador para indicar las interfaces que implementa una clase.

class Clase : Interfaz1, Interfaz2 {
}


29 comentarios en «Introducción a C# para programadores Java»

  1. Muy buen Zootropo. A ver si el personal se va animando un poco más con C# 😛

    Y a ver si termino de leerme el WPF Unleashed y me miro el C# in Depth que recomendastes, que hay 2 o 3 asuntos nuevos de c# que desconozco.

    Por otro lado.. que plugin de wordpress usas? me parece bastante curioso con lo de la barra de desplazamiento horizontal. En mi blog pues si la linea de codigo es muy larga, se va para abajo. Y si además esto coloreara xaml… aunque fijo que eso lleva por debajo el geshi, asi que no 😛

    Al resto, animaros con C#, y sobretodo WPF 😛

    Un saludo.

  2. ¿Y cómo lo puedo poner en blogspot? Porque intenté poner el código en html cuando lo de «ministro de cultura» (¡Ya sale en segundo puesto!) y me salía el link…

  3. Pues llevo trabajando con este lenguaje desde hace como 6 Mese debido a un trabajito que estoy haciendo, y es de las pocas cosas decentes q ha hecho MS; un lenguaje potente de alto nivel y bien estructurado.

  4. Vaya, no parece haber muchos interesados en C#.

    Yo os animo a que os animeis (valga la redundancia). Es muy buen lenguaje, libre, y bastante bien hecho.

    1. fox sabes porq mucha gente no usa C# te lo planteo.

      1. C# no es multiplataforma ya q el framework (la maquina virtual de MS) no es multi baja un poco el nivel, trae unicamente para windows y si es para linux unicamente el mono nose si se puede con el proyecto lucas de Linux y Mac no tiene plataforma para framework entro otros SO.

      2. Java es el rey en juegos para moviles, entre otras aplicaciones, C# no es usado en los moviles.

      3. C# es de MS asi q el codigo es privado, a pesar de q Java fue adquirida por Oracle ya dijeron q van a seguir con el codigo FREE de java de incluso dijeron q van a deguir avanzando con la tecnologia de Java.

      4. Java tiene opcion para Webs C# no, MS si con ASP pero igual C# no, ademas Java tiene 2 IDES muy potentes Netbeans mi favorito y Eclipse y para C# tienes q pagar por un IDE y si consigues IDES gratis no van a ser potentes como los q tienes q comprar.

      5. todo lo q es de MS en algo se tiene q pagar pueda q no pagues por usar c# (la licencia) pero en algo tendras q gastar en usar C# como te dije en los IDES q MS siempre quiere tener ingresos.

      ——————————————–

      la venta de C# es q es un poco mas rapido q Java un poco pero se trabaja en hacerlo mas rapido a la hora de compilar y en las mejoras de el futuro un claro ejemplo es la creacion de JAVAFX compila mucho mejor entre otras opciones q da!.

      Igual yo se programar en C# pero prefiero Java ya q con el empece y me gusta muchu mucho todo lo q tenga q ver con OpenSource o bien FREE, no quiero pagar por una estupida licencia y mas a un q todo lo q es de MS siempre se tiene q pagar por algo y MS pueda q tenga mucha mucha fama pero ahora es Google la empresa mas famosa y ya esta dejando atras a MS bueno yo creo q ya dejo atras a MicroShit = MS HAHA.

      POST para el idiota q dijo q C# es mas popular en Linux ni idea de donde leeo eso un blog amante de MS de plano, linux todo es FREE o OpenSource, Linux usa lenguajes como Phyton, C, C++, Java, Perl, Gambas entre otros no de MS.

  5. Sé de amigos que se sacaron su titulo en Visual Basic, hacían sus pinitos y sus cosas, y ahora, como a Microsoft no le interesaba más el tema, deshizo VB, dejandoles en la ******. ¿Quién se lo podía negar? Es su lenguaje, pueden hacer lo que quieran.

    ¿Quién dice que no ocurrirá lo mismo con C#? Lo siento, pero prefiero lenguajes de programación que estén mantenidos por la comunidad, y que sean quienes desarrollan en el lenguaje los que decidan su futuro; a lenguajes donde sean quienes llevan los maletines quienes decidirán si mañana seguirá teniendo soporte.

    1. Quien te ha dicho que VB esté muerto?

      http://es.wikipedia.org/wiki/Visual_Basic.NET

      Simplemente evolucionó. Pasó de ser un lenguaje de mentira a ser un lenguaje casi de verdad 😛

      Aun si a unas malísimas MS matara C# dentro de una década, ¿Que mas da? El lenguaje de programación no es el fin, es el medio. Aprovechalo mientras exista, si algun dia deja de existir, pues en dos tardes aprendes otro y san se acabó.

      y @Zoo, sobre que a la gente le llame menos por ser MS es 100% verdad. En Linux, Mono está super mal tratado, creen que es un caballo de troya de MS para atacar linux.

      MS hace cosas bien y cosas mal, y he de reconocer que .NET es una idea muy buena (el hecho de crear una libreria una vez y vale para muchos lenguajes) y C# tiene bastantes features bonitas.

      Un saludo.

  6. Pingback: Introducción a C# para programadores Java « Yo Soy Linux!

  7. No es por ser pesado o radical, pero desde el mismo momento en que Microsoft está metido en algo, lo mejor que se puede hacer es desconfiar, porque justamente cuando van de buenos, es cuando van a aprovechar para metertela doblada en la primera de turno.

    Microsoft es actualmente una de las empresas más poderosas del mundo. Y creo que todos sabemos, que un puesto así no se consigue precisamente siendo honrados. Si están poniendo trabajadores y dinero en el asunto es porque esperan algo a cambio, y porque tienen un plan. En este caso, siendo C# suyo, lo más probable es que cuando vean que hay muchos desarrolladores usando su lenguaje, los trajeados de Redmon, en su insaciable sed de más dinero, impongan una licencia para usar C#.
    A esto sumadle las patentes existentes sobre C#. Yo al menos tendría miedo, porque jugando con el diablo nos podemos quemar todos.

    Como alternativa está Vala… no se como irá 😛

  8. Pingback: Microsoft “libera” C# y CLI

  9. Pingback: Breves | Omeyas Web

  10. Pingback: Mono llega al iPhone con MonoTouch

  11. Saludos Banda Malandra.

    Tengo tiempo desarrollando en Java y recientemente me pase a C#, tengo la impresion que hicieron con C# fue lo mismo que ha hecho MS con otros productos. Tomar un producto (Muy bueno como es el caso de java), retocarlo, maquillarlo, y ofrecerlo con ultima novedad, eso que salvara el mundo. A muchos le desagrada MS por esta forma de trabajar. Pero vamos la neta es que sin MS nada de lo que conocemos actualmente en la industria del software seria como actualmente es.
    Y pues MS tambien ha hecho grandes contribucioes ( quiza no con tanta frecuencia) alli esta HTTPRequest. Linq, y otras mondas muy utiles, en fin, yo vivo de esto y espero que jamas haya que pagar licencias para poder trabajar con c#, vb.net

    Saludos a Xalapa

  12. hola…los interesados en programar en c#…lean el libro Manual de Referencia de C#…de Helbert Scildt…es muy bueno y super explicado…

  13. Pingback: Visual Studio 2010 y .NET 4.0

  14. No le tengan tanto miedo a su Amigo Microsoft, jejeje.

    C# me gusta mas que Java para hacer Interfaces gráficas de manera rápida, pero Java me gusta mas para hacer programas mas técnicos.

    Saludos.

  15. Pingback: StudentClub.ITmina » Visual Studio 2010

  16. Hola,

    Sé que esta entrada lleva muuucho tiempo y bueno trabajo un poco de c# pero nunca he aprendido a usar listas o árboles o algo así y me acordé de esto pensando que acá podría encontrarlo dado que en java es un tipo de dato muy útil y natural ¿Sabes algo al respecto de esto? Buscar en google (he hecho nada más como 2 búsquedas) no me ha arrojado nada interesante.

    1. Para listas tienes System.Collections.Generic.List. Para árboles, creo que no hay nada en las librerías estándares, o al menos recuerdo haber creado una pequeña implementación propia. No te sé decir seguro porque hace meses que no toco nada de C#.

  17. Tengo la siguiente función en java y quiero convertirla a C# pero no se cuales son los equivalentes de Character, Iterator y Collections

    private static char[] obtenerUnicosOrdenados(char[] original)
    {
    ArrayList lista = new ArrayList();
    for (int i = 0; i < original.Length; i++)
    {
    char caracter = original[i];
    Character cObj = new Character(caracter);
    if (!lista.Contains(cObj))
    {
    lista.Add(cObj);
    }
    }
    Collections.sort(lista);
    char[] caracteresUnicos = new char[lista.size()];
    int n = 0;
    for (Iterator iter = lista.iterator(); iter.hasNext(); n++)
    {
    Character cObject = (Character)iter.next();
    caracteresUnicos[n] = cObject.charValue();
    }
    return caracteresUnicos;
    }

    Alguien me puede ayudar??

  18. Sin duda C# es un gran lenguaje yo empeze programando en java pero desde que conocí C# lo uso a diario, ademas c# se puede usar tranquilamente en linux con mono que es un proyecto libre.

    Ademas recordemos que java ya no sigue siendo tan libre oracle lo compro.

    Yo pienso que ambos lenguajes se basan en el mismo concepto de programación y la sintaxis de ambos lenguajes son muy parecidas.

    Pero en opinion personal prefiero c#, en java no existe nada igual a linq que los invito a que conozcan esta tecnología de .Net es una gran cosa

Responder a nintux Cancelar respuesta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.