curso de c#

Upload: miguel-angel-olvera-garcia

Post on 16-Oct-2015

129 views

Category:

Documents


2 download

TRANSCRIPT

  • Curso de C#

    Introduccin al lenguaje de programacin C#

    -

    Caractersticas del lenguaje C#

    Aspectos Lxicos

    E/S bsica

    Tipos de datos

    Variables y constantes

    Operadores y expresiones Estructuras de control

    C# (ledo en ingls "C Sharp" y en espaol "C Almohadilla") es el nuevo lenguaje de propsito general diseado por Microsoft para su plataforma .NET.

    Aunque es posible escribir cdigo para la plataforma .NET en muchos otros lenguajes,

    C# es el nico que ha sido diseado especficamente para ser utilizado en ella, por lo

    que programarla usando C# es mucho ms sencillo e intuitivo que hacerlo con

    cualquiera de los otros lenguajes ya que C# carece de elementos heredados

    innecesarios en .NET. Por esta razn, se suele decir que C# es el lenguaje nativo de .NET

    Caractersticas del lenguaje C#

    Aunque es pronto para entrar con detenimiento en el lenguaje C# podemos adelantar

    las caractersticas ms relevantes de este lenguaje, caractersticas que se describen

    con profundidad posteriormente, durante el estudio detallado de los elementos del

    lenguaje.

    Es autocontenido. Un programa en C# no necesita de ficheros

    adicionales al propio cdigo fuente, como los ficheros de cabecera

    (.h) de C++, lo que simplifica la arquitectura de los proyectos

    software desarrollados con C++.

    Es homogneo. El tamao de los tipos de datos bsicos es fijo e

    independiente del compilador, sistema operativo o mquina en la

    que se compile (no ocurre lo que en C++), lo que facilita la

    portabilidad del cdigo.

  • Es actual. C# incorpora en el propio lenguaje elementos que se han

    demostrado ser muy tiles para el desarrollo de aplicaciones como

    el tipo bsico decimal que representa valores decimales con 128

    bits, lo que le hace adecuado para clculos financieros y

    monetarios, incorpora la instruccin foreach, que permite una

    cmoda iteracin por colecciones de datos, proporciona el tipo

    bsico string, permite definir cmodamente propiedades

    (campos de acceso controlado), etc.

    Est orientado a objetos. C# soporta todas las caractersticas

    propias del paradigma de la programacin orientada a objetos:

    encapsulacin, herencia y polimorfismo.

    o Encapsulacin: adems de los modificadores de accceso

    convencionales: public, private y protected, C# aade el

    modificador internal, que limita el acceso al proyecto actual.

    o C# slo admite herencia simple.

    o Todos los mtodos son, por defecto, sellados, y los mtodos

    redefinibles han de marcarse, obligatoriamente, con el

    modificador virtual.

    Delega la gestin de memoria. Como todo lenguaje de .NET, la

    gestin de la memoria se realiza automticamente ya que tiene a

    su disposicin el recolector de basura del CLR. Esto hace que el

    programador se desentienda de la gestin directa de la memoria

    (peticin y liberacin explcita) evitando que se cometan los errores habituales de este tipo de gestin en C++, por ejemplo.

    En principio, en C# todo el cdigo incluye numerosas restricciones

    para asegurar su seguridad no permite el uso de punteros, por

    ejemplo. Sin embargo, y a diferencia de Java, en C# es posible

    saltarse dichas restricciones manipulando objetos a travs de

    punteros. Para ello basta marcar regiones de cdigo como

    inseguras (modificador unsafe) y podrn usarse en ellas punteros

    de forma similar a cmo se hace en C++, lo que puede resultar

    vital para situaciones donde se necesite una eficiencia y velocidad procesamiento muy grandes.

    Emplea un sistema de tipos unificado. Todos los tipos de datos

    (incluidos los definidos por el usuario) siempre derivarn, aunque

    sea de manera implcita, de una clase base comn llamada

    System.Object, por lo que dispondrn de todos los miembros

    definidos en sta clase. Esto tambin es aplicable, lgicamente, a

    los tipos de datos bsicos.

    Proporciona seguridad con los tipos de datos. C# no admiten ni

    funciones ni variables globales sino que todo el cdigo y datos han

    de definirse dentro de definiciones de tipos de datos, lo que reduce

    problemas por conflictos de nombres y facilita la legibilidad del cdigo.

  • C# incluye mecanismos que permiten asegurar que los accesos a

    tipos de datos siempre se realicen correctamente:

    o No pueden usarse variables que no hayan sido inicializadas.

    o Slo se admiten conversiones entre tipos compatibles

    o Siempre se comprueba que los ndices empleados para acceder

    a los elementos de una tabla (vector o matriz) se encuentran

    en el rango de valores vlidos.

    o Siempre se comprueba que los valores que se pasan en una

    llamada a mtodos que pueden admitir un nmero indefinido

    de parmetros (de un cierto tipo) sean del tipo apropiado.

    Proporciona instrucciones seguras. En C# se han impuesto una

    serie de restricciones para usar las instrucciones de control ms

    comunes. Por ejemplo, toda condicin est controlada por una

    expresin condicional, los casos de una instruccin condicional

    mltiple (switch) han de terminar con una instruccin break o

    goto, etc.

    Facilita la extensibilidad de los operadores. C# permite redefinir

    el significado de la mayora de los operadores -incluidos los de

    conversin, tanto para conversiones implcitas como explcitas-

    cuando se aplican a diferentes tipos de objetos.

    Permite incorporar modificadores informativos sobre un tipo o

    sus miembros. C# ofrece, a travs del concepto de atributos, la

    posibilidad de aadir, a los metadatos del mdulo resultante de la

    compilacin de cualquier fuente, informacin sobre un tipo o sus

    miembros a la generada por el compilador que luego podr ser

    consultada en tiempo ejecucin a travs de la biblioteca de

    reflexin de .NET. Esto, que ms bien es una caracterstica propia

    de la plataforma .NET y no de C#, puede usarse como un

    mecanismo para definir nuevos modificadores.

    Facilita el mantenimiento (es "versionable"). C# incluye una

    poltica de versionado que permite crear nuevas versiones de tipos

    sin temor a que la introduccin de nuevos miembros provoquen

    errores difciles de detectar en tipos hijos previamente

    desarrollados y ya extendidos con miembros de igual nombre a los

    recin introducidos.

    Apuesta por la compatibilidad. C# mantiene una sintaxis muy

    similar a C++ o Java que permite, bajo ciertas condiciones, incluir

    directamente en cdigo escrito en C# fragmentos de cdigo escrito

    en estos lenguajes.

    En resumen, podemos concluir que:

    Es un lenguaje orientado al desarrollo de componentes (mdulos

    independientes de granularidad mayor que los objetos) ya que los

    componentes son objetos que se caracterizan por sus

    propiedades, mtodos y eventos y estos aspectos de los

    componentes estn presentes de manera natural en C#.

    En C# todo son objetos: desaparece la distincin entre tipos

    primitivos y objetos de lenguajes como Java o C++ (sin penalizar la

    eficiencia como en LISP o Smalltalk).

  • El software es robusto y duradero: el mecanismo automtico de

    recoleccin de basura, la gestin de excepciones, la comprobacin

    de tipos, la imposibilidad de usar variables sin inicializar y hacer

    conversiones de tipo (castings) no seguras, gestin de versiones,

    etc. ayudan a desarrollar software fcilmente mantenible y poco

    propenso a errores.

    Adems, no hay que olvidar el aspecto econmico: la posibilidad de

    utilizar C++ puro (cdigo no gestionado o inseguro), la facilidad de

    interoperabilidad (XML, SOAP, COM, DLLs...) junto con un

    aprendizaje relativamente sencillo (para los que ya conocen otros

    lenguajes de programacin) hace que el dominio y uso del lenguaje junto a otras tecnologas sea muy apreciado.

    Aspectos Lxicos

    En esta seccin presentaremos las reglas sintcticas bsicas que deben cumplir los

    programas escritos en C# y veremos los elementos fundamentales de cualquier

    programa en C# (identificadores, comentarios, palabras reservadas, etc.). Se trata, en

    definitiva, de la parte instrumental y bsica, adems de imprescindible, de cualquier manual de programacin.

    Es costumbre desde la poca dorada del lenguaje C (quiz una de las pocas

    costumbres que se mantienen en el mundo de la informtica) que se presente un

    lenguaje de programacin empleando un programa que muestra en la consola el

    mensaje Hola, mundo! (para ser ms precisos deberamos decir Hello,

    world!). Sigamos manteniendo esta costumbre:

    Hola, mundo!

    /*

    Fichero: Saludo.cs

    Fecha: Enero de 2004

    Autores: F. Berzal, F.J. Cortijo y J.C.Cubero

    Comentarios:

    Primer programa escrito en C#

    */

    using System;

    public class SaludoAlMundo

    {

    public static void Main( )

    {

    // Mostrar en la consola el mensaje: Hola, mundo!

    Console.WriteLine("Hola, mundo!");

    Console.ReadLine(); // Enter para terminar.

    }

    }

  • Lo primero que hay que resaltar es que C# es un lenguaje sensible a las

    maysculas, por lo que, por ejemplo, Main es diferente a main, por lo que deber

    prestar atencin a la hora de escribir el cdigo ya que la confusin entre maysculas y minsculas provocar errores de compilacin.

    Todas las rdenes acaban con el smbolo del punto y coma (;). Los bloques de rdenes

    (parte iterativa de un ciclo, partes dependientes de una instruccin condicional -parte

    if y parte else-, cdigo de un mtodo, etc.) se encierran entre llaves { } y no se

    escribe el ; despus de la llave de cierre (observar en el ejemplo el mtodo Main).

    Si el lector ha programado en C++ no habr tenido dificultad en localizar los

    comentarios que hemos insertado en el programa ya que la sintaxis es idntica en

    ambos lenguajes: existen comentarios de lnea, cuyo comienzo se especifica con los

    caracteres // y comentarios de formato libre, delimitados por /* y */.

    C# es un lenguaje orientado a objetos y todo est encapsulado en clases, incluso la

    funcin Main que es un mtodo (especial) del objeto aplicacin. En el ejemplo la clase

    se llama SaludoAlMundo.

    La lnea using System declara que se va a usar el espacio de nombres (namespace)

    llamado System. Esta declaracin no es igual a un #include de C#, tan solo evita

    escribir el prefijo System cada vez que se use un elemento de ese espacio de

    nombres. Por ejemplo, Console es un objeto del espacio de nombres System; en

    lugar de escribir su nombre completo (System.Console) podemos escribir solamente

    Console al haber declarado que se va a emplear el espacio de nombres System.

    Cuando este programa se compile y se proceda a su ejecucin, la primera funcin

    (estrictamente hablando, mtodo) en ejecutarse ser Main. Los programadores de

    C++ debern tener especial cuidado y no confundirlo con main().

    La funcin Main() tiene los siguientes prototipos vlidos:

    Si la funcin no devuelve ningn valor, puede usarse:

    public static void Main( )

    public static void Main(string [] args)

    La diferencia est en la posibilidad de suministrar argumentos en la

    llamada a la ejecucin del programa. Main() procesan los

    argumentos tomndolos de la lista de cadenas args (ms adelante

    se detalla cmo).

    Si la funcin devuelve un valor al proceso que invoca la ejecucin del

    programa, el valor debe ser entero (int) y, como en el caso

    anterior, puede usarse:

    public static int Main( )

    public static int Main(string [] args)

    La convencin es que el valor 0 indica que el programa termina

    correctamente.

  • En cuanto a las instrucciones que efectivamente se ejecutan, el mtodo Main() llama

    a los mtodos WriteLine() y ReadLine() del objeto Console. El primero se

    encargan de mostrar una cadena en la consola (Smbolo de Sistema, en Windows XP) y

    el segundo de tomar una cadena de la consola (teclado). Aunque esta ltima

    instruccin pueda parecer innecesaria, de no escribirla se mostrara la cadena Hola,

    mundo! y se cerrara inmediatamente la consola, por lo que no podramos contemplar

    el resultado de la ejecucin. La ltima instruccin detiene la ejecucin del programa

    hasta que se introduce una cadena (pulsar ENTER es suficiente) y a continuacin

    termina la ejecucin del programa y se cierra la consola. As, cuando usemos aplicaciones de consola siempre terminaremos con esta instruccin.

    A continuacn detallaremos ciertos aspectos lxicos importantes de los programas

    escritos en C#, algunos de los cuales ya se han comentado brevemente como

    explicacin al programa introductorio.

    Comentarios

    Los comentarios tienen como finalidad ayudar a comprender el cdigo fuente y estn

    destinados, por lo tanto, a los programadores. No tienen efecto sobre el cdigo

    ejecutable ya que su contenido es ignorado por el compilador (no se procesa). La

    sintaxis de los comentarios en C# es idntica a la de C++ y se distinguen dos tipos de comentarios:

    Comentarios de lnea. Estn precedidos de la construccin // y su

    efecto (mbito) termina en la lnea en la que est inmerso.

    Comentarios de formato libre. Estn delimitados por las

    construcciones /* y */ y pueden extenderse por varias lneas.

    Ejemplos de comentarios

    // En una lnea, al estilo de C++

    /*

    En mltiples lneas, como se viene

    haciendo desde "los tiempos de C"

    */

    /* Este tipo de comentario ya no es habitual */

    Identificadores

    Un identificador es un nombre con el que nos referimos a algn elemento de nuestro

    programa: una clase, un objeto, una variable, un mtodo, etc. Se imponen algunas restricciones acerca de los nombres que pueden emplearse:

    Deben comenzar por una letra letra o con el carcter de subrayado

    (_), que est permitido como carcter inicial (como era tradicional

    en el lenguaje C).

    No pueden contener espacios en blanco.

  • Pueden contener caracteres Unicode, en particular secuencias de

    escape Unicode.

    Son sensibles a maysculas/minsculas.

    No pueden coincidir con palabras reservadas (a no ser que tengan el

    prefijo @ que habilita el uso de palabras clave como identificadores).

    Los identificadores con prefijo @ se conocen como identificadores

    literales. Aunque el uso del prefijo @ para los identificadores que no

    son palabras clave est permitido, no se recomienda por regla de estilo.

    Palabras reservadas

    Las palabras reservadas son identificadores predefinidos reservados que tienen un

    significado especial para el compilador por lo que no se pueden utilizar como

    identificadores en un programa a menos que incluyan el carcter @ como prefijo.

    Las palabras reservadas en C# son, por orden alfabtico:

    abstract, as, base, bool, break, byte, case, catch, char, checked, class,

    const, continue, decimal, default, delegate, do, double, else, enum, event,

    explicit, extern, false, finally, fixed, float, for, foreach, goto, if,

    implicit, in, int, interface, internal, is, lock, long, namespace, new,

    null, object, operator, out, override, params, private, protected, public,

    readonly, ref, return, sbyte, sealed, short, sizeof, stackalloc, static,

    string, struct, switch, this, throw, true, try, typeof, uint, ulong,

    unchecked, unsafe, ushort, using, virtual, void, volatile, while

    Literales

    Un literal es una representacin en cdigo fuente de un valor. Todo literal tiene

    asociado un tipo, que puede ser explcito (si se indica en el literal, mediante algn sufijo, por ejemplo) o implcito (se asume uno por defecto).

    Los literales pueden ser:

    Literales lgicos.

    Existen dos valores literales lgicos: true y false. El tipo de un

    literal lgico es bool.

    Literales enteros.

    Permiten escribir valores de los tipos enteros: int, uint, long y

    ulong. Los literales enteros tienen dos formatos posibles: decimal

    y hexadecimal. Los literales hexadecimales tienen el sufijo 0x.

  • El tipo de un literal entero se determina como sigue:

    o Si no tiene sufijo, su tipo es int.

    o Si tiene el sufijo U o u, su tipo es uint o ulong.

    o Si tiene el sufijo L o l, su tipo es long o ulong.

    o Si tiene el sufijo UL, Ul, uL, ul, LU, Lu, lU o lu es de tipo

    ulong.

    A la hora de escribir literales de tipo long se recomienda usar L en

    lugar de l para evitar confundir la letra l con el dgito 1.

    Literales enteros

    123 // int

    0x7B // hexadecimal

    123U // unsigned

    123ul // unsigned long

    123L // long

    Literales reales.

    Los literales reales permiten escribir valores de los tipos float,

    double y decimal.

    El tipo de un literal real se determina como sigue:

    o Si no se especifica sufijo, el tipo es double.

    o Si el sufijo es F o f es de tipo float.

    o Si el sufijo es D o d es de tipo double.

    o Si el sufijo es M o m es de tipo decimal.

    Hay que tener en cuenta que, en un literal real, siempre son

    necesarios dgitos decimales tras el punto decimal. Por ejemplo,

    3.1F es un literal real, pero no as 1.F.

    Literales reales

    1f, 1.5f, 1e10f, 123.456F, 123f y 1.23e2f // float

    1d, 1.5d, 1e10d, 123.456D, 123.0 y 123D // double

    1m, 1.5m, 1e10m, 123.456M, 123.456m y 12.3E1M //

    decimal.

    Literales de caracteres.

    Un literal de caracteres representa un carcter nico y

    normalmente est compuesto por un carcter entre comillas

    simples, por ejemplo 'A'.

  • Una secuencia de escape sencilla representa una codificacin de

    caracteres Unicode y est formada por el carcter \ seguido de otro

    carcter. Las secuencias vlidas se describe en la siguiente tabla.

    Secuencia de

    escape

    Nombre del

    carcter

    Codificacin

    Unicode

    \' Comilla simple 0x0027

    \" Comilla doble 0x0022

    \\ Barra invertida 0x005C

    \0 Null 0x0000

    \a Alerta 0x0007

    \b Retroceso 0x0008

    \f Avance de pgina 0x000C

    \n Nueva lnea 0x000A

    \r Retorno de carro 0x000D

    \t Tabulacin

    horizontal 0x0009

    \v Tabulacin vertical 0x000B

    El tipo de un literal de caracteres es char.

    Literales de caracteres

    'A' // caracter sencillo

    '\u0041' // caracter Unicode

    '\x0041' // unsigned short hexadecimal

    '\n' // caracter de escape: CR+LF

    Literales de cadena.

    C# admite dos formatos de literales de cadena: literales de cadena

    tpicos y literales de cadena textuales. El tipo de un literal de

    cadena es string.

    Un literal tpico de cadena consta de cero o ms caracteres entre

    comillas dobles y puede incluir secuencias de escape sencillas y secuencias de escape hexadecimales y Unicode.

  • Literales tipicos de cadena

    "!Hola, mundo!" // !Hola, mundo!

    "!Hola, \t mundo!" // !Hola, mundo!

    "" // La cadena vacia

    Un literal de cadena textual consta del carcter @ seguido de un

    carcter de comillas dobles, cero o ms caracteres y un carcter de

    comillas dobles de cierre. Por ejemplo, @"Hola". En estos literales

    los caracteres se interpretan de manera literal y no se procesan las

    secuencias de escape, con la nica excepcin de la secuencia \".

    Un literal de cadena textual puede estar en varias lneas.

    Literales de cadena textuales

    @"!Hola, \t mundo!" // !Hola, \t mundo!

    "Me dijo \"Hola\" y me asust" // Me dijo "Hola" y

    me asust

    @"Me dijo ""Hola"" y me asust" // Me dijo "Hola" y

    me asust

    "\\\\servidor\\share\\file.txt" //

    \\servidor\share\file.txt

    @"\\servidor\share\file.txt" //

    \\servidor\share\file.txt

    @"uno // Esta es una

    cadena distribuida

    dos" // en dos lineas.

    Literal null.

    Su nico valor es null y su tipo es el tipo null.

    rdenes

    Delimitadas por punto y coma (;) como en C, C++ y Java. Los bloques { ... } no necesitan punto y coma al final.

    E/S bsica

    Las operaciones de entrada y salida tienen como objetivo permitir que el usuario pueda

    introducir informacin al programa (operaciones de entrada) y que pueda obtener

    informacin de ste (operaciones de salida). En definitiva, tratan de la comunicacin entre el usuario y el programa.

  • La manera ms simple de comunicacin es mediante la consola. La consola ha sido el

    modo tradicional de comunicacin entre los programas y el usuario por su simplicidad.

    Las aplicaciones basadas en ventanas resultan mucho ms atractivas y cmodas para

    el usuario y es ste, sin duda, el tipo de comunicacin que deberemos emplear para

    productos finales. Los programas que no requieran una mucha interaccin con el

    usuario, no obstante, se construyen y se ponen en explotacin mucho ms rpidamente si se utiliza la consola como medio de comunicacin.

    Aplicaciones en modo consola

    Estas aplicaciones emplean la consola para representar las secuencias de entrada,

    salida (y error) estndar.

    Una aplicacin de consola se crea en Visual Studio .NET seleccionando Archivo,

    Nuevo y Proyecto. Cuando aparece la ventana Nuevo proyecto se selecciona

    Proyectos de Visual C# y Aplicacin de consola:

    El acceso a la consola lo facilita la clase Console, declarada en el espacio de nombres

    System. Esa clase proporciona la compatibilidad bsica para aplicaciones que leen y

    escriben caracteres en la consola. No es necesario realizar ninguna accin para poder

    obtener datos de la consola a partir de la entrada estndar (teclado) o presentarlos en

    la salida estndar (consola) ya que estos flujos (junto con el del error estndar) se

    asocian a la consola de manera automtica, como ocurre en C++, por ejemplo, con

    cin, cout y cerr.

  • Los mtodos bsicos de la clase Console son WriteLine y ReadLine, junto con sus

    variantes Write y Read:

    WriteLine escribe una lnea en la salida estndar, entendiendo que

    escribe el terminador de lnea actual (por defecto la cadena

    "\r\n").

    La versin ms simple de este mtodo recibe un nico argumento

    (una cadena) cuyo valor es el que se muestra:

    Console.WriteLine ("!Hola, " + "mundo!");

    // Escribe: !Hola, mundo!

    Otra versin permite mostrar variables de diferentes tipos (sin

    necesidad de convertirlas a string. La llamada tiene un nmero

    indeterminado de argumentos: el primero es una cadena de

    formato en la que las variables a mostrar se indican con {0}, {1},

    etc. y a continuacin se enumeran las variables a mostrar,

    entendiendo que la primera se "casa" con {0}, la segunda con {1},

    etc. Esta manera de mostrar los datos recuerda a la instruccin

    printf de C, que cay en desuso con C++ ...

    int TuEdad = 25;

    string TuNombre = "Pepe";

    Console.WriteLine ("Tienes {0} aos, {1}.", TuEdad,

    TuNombre);

    // Escribe: Tienes 25 aos, Pepe.

    El mtodo Write hace lo mismo que WriteLine aunque no escribe

    el terminador de lnea.

    ReadLine lee la siguiente lnea de caracteres de la secuencia de

    entrada estndar (el teclado, por defecto), eliminando del buffer de

    entrada el terminador de lnea. Devuelve la cadena leida, que no

    contiene el carcter o los caracteres de terminacin.

    Read lee el siguiente carcter de la secuencia de entrada estndar y

    devuelve un valor de tipo int. La lectura se realiza del buffer de

    entrada y no se termina (no devuelve ningn valor) hasta que se

    encuentra al caracter de terminacin (cuando el usuario presion la

    tecla ENTER). Si existen datos disponibles en el buffer, la secuencia

    de entrada contiene los datos introducidos por el usuario, seguidos del carcter de terminacin.

  • Veamos un sencillo ejemplo sobre el uso de estos mtodos.

    E/S simple

    using System;

    class PideNombre

    {

    static void Main(string[] args)

    {

    Console.Write ("Introduzca su nombre: ");

    // 1

    string nombre = Console.ReadLine();

    // 2

    Console.WriteLine ("Su nombre es: " + nombre);

    // 3

    Console.ReadLine();

    // 4

    }

    }

    La instruccin 1 muestra la cadena Introduzca su nombre: pero no avanza a la

    siguiente lnea de la consola, por lo que cuando se ejecuta la instruccin 2 lo que

    escribe el usuario se muestra a continuacin, en la misma lnea. La cadena que escribe

    el usuario se guarda en la variable nombre y se elimina del buffer de entrada el

    terminador de lnea. Cuando se valida la entrada (al pulsar ENTER) se avanza a la

    siguiente lnea. La instruccin 3 muestra una cadena, resultado de concatenar un

    literal y la cadena introducida por el usuario. Finalmente, la instruccin 4 es necesaria

    para detener la ejecucin del programa (realmente, la finalizacin del mismo) hasta

    que el usuario pulse ENTER. Observar que aunque el mtodo Readline devuelva una

    cadena, ste valor devuelto no es usado. En la siguiente figura mostramos dos

    ejemplos de ejecucin.

  • Aplicaciones Windows

    Una aplicacin basada en ventanas (aplicacin Windows, en lo que sigue) utilizan

    ventanas y componentes especficos para interactuar con el usuario. Las peticiones de

    datos se realizan con componentes de entrada de texto (por ejemplo, con un

    TextBox) o mediante la seleccin en una lista de posibilidades (por ejemplo, con un

    ComboBox). Las salidas pueden realizarse de mltiples maneras, empleando

    componentes Label, ventanas de mensajes MessageBox, etc.

    Por ejemplo, en la figura siguiente mostramos una aplicacin que responde mostrando

    una ventana de mensaje (MessageBox) cuando se pincha sobre el botn titulado

    Saludo. Basta con ejecutar este cdigo cada vez que se pinche en dicho botn:

    MessageBox.Show ("Hola, mundo!", "Un saludo tpico");

    (en realidad, System.Windows.Forms.MessageBox.Show (...);)

    Una aplicacin ms compleja podra pedir el nombre del usuario en un componente

    TextBox y mostrarlo empleando un componente Label cuando se pincha en el botn

    titulado Saludo:

    Una aplicacin de ventanas se crea fcilmente en Visual Studio .NET seleccionando

    Archivo, Nuevo y Proyecto. En la ventana Nuevo proyecto se selecciona ahora

    Proyectos de Visual C# y Aplicacin para Windows.

  • Tipos de datos

    Los tipos de datos ofrecidos por C# al programador forman parte de un sistema

    unificado en el que todos los tipos de datos (incluidos los definidos por el usuario)

    derivan, aunque sea de manera implcita, de la clase System.Object. Por herencia

    dispondrn de todos los miembros definidos en sta clase, en particular los tiles

    mtodos Equals(), GetHashCode(), GetType() y ToString() que describiremnos

    ms adelante. C# proporciona seguridad con los tipos de datos. C# no admiten ni

    funciones ni variables globales sino que todo el cdigo y datos han de definirse dentro

    de definiciones de tipos de datos, lo que reduce problemas por conflictos de nombres y

    facilita la legibilidad del cdigo. C# incluye mecanismos que permiten asegurar que los

    accesos a tipos de datos siempre se realicen correctamente:

    No pueden usarse variables que no hayan sido iniciadas.

    El tipo asignado restringe los valores que puede almacenar y las

    operaciones en las que puede intervenir.

    Siempre se comprueba que los ndices empleados para acceder a los

    elementos de una tabla (vector o matriz) se encuentran en el rango

    de valores vlidos.

    Slo se admiten conversiones de tipo entre tipos compatibles y entre

    aquellos que se hayan definido explcitamente el mecanismo de

    conversin (En C# puede implementarse la manera en que se realiza la conversin implcita y explcita entre tipos)

    Los tipos de datos en C# pueden clasificarse en dos grandes categoras:

    tipos valor

    tipos referencia

    y pueden caracterizarse como sigue:

    Tipos valor Tipos referencia

    La variable contiene un valor La variable contiene una

    referencia

    El dato se almacena en la

    pila El dato se almacena en el heap

    El dato siempre tiene valor El dato puede no tener valor null

    Una asignacin copia el valor Una asignacin copia la referencia

    int i = 123; // tipo valor

    string s = "Hello world"; // tipo referencia

  • El comportamiento cuando se copian o modifican objetos de estos tipos es muy

    diferente.

    Tipos valor

    Los tipos bsicos son tipos valor. Si una variable es de un tipo valor contiene

    nicamente un valor del tipo del que se ha declarado. Los tipos predefinidos de C# son

    tipos disponibles en la plataforma .NET y que, por comodidad, en C# se emplean

    usando un alias. En la tabla siguiente enumeramos los tipos simples detallando su

    nombre completo, su alias, una breve descripcin, el nmero de bytes que ocupan y el rango de valores.

    Nombre (.NET

    Framework) Alias Descripcin

    Tamao

    (bytes) Rango

    System.Sbyte sbyte Bytes con

    signo 1 -128 ... 127

    System.Int16 short Enteros

    cortos 2 -32.768 ... 32.767

    System.Int32 int Enteros 4 -2.147.483.648 ...

    2.147.483.647

    System.Int64 long Enteros

    largos 8

    -9.223.372.036.854.775.808

    ...

    9.223.372.036.854.775.807

    System.Byte byte Bytes (sin

    signo) 1 0 ... 255

    System.Uint16 ushort Enteros

    cortos (sin

    signo)

    2 0 ... 65.535

    System.UInt32 uint Enteros (sin

    signo) 4

    0 ...

    18.446.744.073.709.551.615

    System.Uint64 ulong Enteros

    largos (sin

    signo)

    8 0 ...

    18.446.744.073.709.551.615

    System.Single float Reales (7

    decimales) 4

    1.5 x 10-45 ... 3.4 x

    10+38

    System.Double double Reales (15-

    16

    decimales)

    8 5.0 x 10-324 ... 1.7 x

    10+308

    System.Decimal decimal Reales (28-

    29

    decimales)

    12 1.0 x 10-28 ... 7.9 x

    10+28

    System.Char char Caracteres

    Unicode 2 Cualquier carcter Unicode

  • System.Boolean bool Valores

    lgicos 1 true false

    El comportamiento de los datos de tipos valor es el esperado cuando se inician o

    reciben un valor por asignacin a partir de otro dato de tipo valor (son independientes).

    Tipos referencia

    Si un dato es de un tipo referencia contiene la direccin de la informacin, en

    definitiva, una referencia al objeto que contiene los datos y/o mtodos. En definitiva, distinguimos:

    La referencia o un nombre por el que nos referimos al objeto y que

    utilizamos para manipularlo.

    El objeto referenciado, que ocupa lugar en memoria (en el heap) y que almacenar el valor efectivo del objeto.

    En definitiva: la variable y su contenido "lgico" estn en posiciones de memoria

    diferentes. El valor almacenado en una variable de tipo referencia es la direccin de

    memoria del objeto referenciado (es una referencia) o tiene el valor null (no

    referencia a nada). Observe que pueden existir dos variables que referencien al mismo objeto (pueden existir dos referencias a la misma zona de memoria).

    C# proporciona dos tipos referencia predefinidos: object y string. Todos los dems

    tipos predefinidos son tipos valor.

    El tipo object es el tipo base del cual derivan todos los tipos bsicos predefinidos y

    los creados por el usuario. Pueden crearse nuevos tipos referencia usando

    declaraciones de clases (class), interfaces (interface) y delegados (delegate), y

    nuevos tipos valor usando estructuras struct.

    Los objetos de las clases creadas por el usuario son siempre de tipo referencia. El

    operador new permite la creacin de instancias de clases definidas por el usuario. new

    es muy diferente en C# y en C++:

    En C++ indica que se pide memoria dinmica. En C# indica que se llama al constructor de una clase.

    El efecto, no obstante, es similar ya que como la variable es de un tipo referencia, al

    llamar al constructor se aloja memoria en el heap de manera implcita.

    Considere el siguiente fragmento de cdigo, en el que todas las variables son del

    mismo tipo: ObjetoDemo).

  • Tipos referencia

    class ObjetoDemo

    {

    public int Valor;

    }

    class AppDemoRef

    {

    static void Main(string[] args)

    {

    ObjetoDemo o1 = new ObjetoDemo(); // new llama a

    un constructor

    o1.Valor = 10;

    ObjetoDemo o2 = new ObjetoDemo(); // new llama a

    un constructor

    o2 = o1; // La memoria que ocupaba el objeto

    refernciado por "o2"

    // se pierde: actuar el recolector de

    basura.

    PintaDatos ("o1", "o2", o1, o2);

    ObjetoDemo o3 = new ObjetoDemo();// new llama a

    un constructor

    o3.Valor = 10;

    ObjetoDemo o4 = o3; // "o4" contiene la misma

    direccion de memoria que "o3"

    o4.Valor = 20; // Igual que hacer o3.Valor

    = 20;

    PintaDatos ("o3", "o4", o3, o4);

    ObjetoDemo o5 = new ObjetoDemo(); // new llama a

    un constructor

    o5.Valor = 10;

    ObjetoDemo o6 = new ObjetoDemo(); // new llama a

    un constructor

    o6.Valor = o5.Valor;

    PintaDatos ("o5", "o6", o5, o6);

    Console.ReadLine();

    }

    static void PintaDatos (string st1, string st2,

    ObjetoDemo ob1, ObjetoDemo ob2)

    {

    Console.Write ("{0} = {1}, {2} = {3} ", st1,

    ob1.Valor, st2, ob2.Valor);

    if (ob1==ob2)

    Console.WriteLine ("{0} == {1}", st1, st2);

    else

    Console.WriteLine ("{0} != {1}", st1, st2);

    }

    }

  • El tipo string es un tipo especial de tipo referencia. De hecho, parece ms un tipo

    valor ante la asignacin. Observe el ejemplo:

    string s1 = "Hola";

    string s2 = s1;

    En este punto s2 referencia al mismo objeto que s1. Sin embargo, cuando el valor de

    s1 es modificado, por ejemplo con:

    s1 = "Adios";

    lo que ocurre es que se crea un nuevo objeto string referenciado por s1. De esta

    forma, s1 contiene "Adios" mientras que s2 mantiene el valor "Hola". Esto es as

    porque los objetos string son immutables, por lo que, para cambiar lo que

    referencia una variable string debe crearse un nuevo objeto string.

    Variables y constantes

    Variables

    Una variable permite el almacenamiento de datos en la memoria. Es una abstraccin

    que permite referirnos a una zona de memoria mediante un nombre (su identificador).

    Todas las variables tienen asociadas un tipo que determina los valores que pueden

    almacenarse y las operaciones que pueden efectuarse con los datos de ese tipo.

    Adems, el trmino variable indica que el contenido de esa zona de memoria puede modificarse durante la ejecucin del programa.

    Nombres de variables

    Los nombres que pueden asignarse a las variables deben regirse por unas normas bsicas:

    Pueden contener letras, dgitos y el caracter de subrayado (_).

    No pueden empezar con un nmero: deben comenzar por una letra

    letra o con el carcter de subrayado (_).

  • Finalmente, recordar que, como identificador que es, el nombre de una variable es

    sensible a las maysculas y no pueden coincidir con una palabra reservada a no ser

    que tenga el prefijo @, aunque no es una prctica recomendada.

    Declaracin de variables

    Antes de usar una variable se debe declarar. La declaracin de una variable indica

    al compilador el nombre de la variable y su tipo. Una declaracin permite que se pueda

    reservar memoria para esa variable y restringir el espacio (cantidad de memoria) que

    requiere, los valores que pueden asignarsele y las operaciones en las que puede intervenir.

    La sintaxis de una declaracin es sencilla: tan slo hay que especificar el tipo de la

    variable y el nombre que se le asocia. La declaracin debe concluir con el carcter

    punto y coma. Por ejemplo, si vamos a emplear una variable para guardar en ella el valor del rea de un crculo debemos:

    Darle un nombre significativo: Area

    Asociarle un tipo: dado que puede tener decimales y no se requiere

    una gran precisin, bastar con el tipo float.

    float Area;

    Cuando se van a declarar mltiples variables del mismo tipo no es necesario que cada

    declaracin se haga por separado, pueden agruparse en la misma lnea compartiendo

    el tipo. Por ejemplo, las declaraciones:

    float Radio;

    float Area;

    pueden simplificarse en una lnea:

    float Radio, Area;

    De la misma manera pueden declararse e inicializarse variables en una sola lnea:

    int a=1, b=2, c, d=4;

    No existe ninguna zona predeterminada en el cdigo para la declaracin de variables,

    la nica restriccin es que la declaracin debe realizarse antes de su uso.

  • No es conveniente abusar de la declaracin mltiple de variables en una lnea. Desde

    el punto de vista de la legibilidad es preferible, por regla general, que cada variable se

    declare separadamente y que la declaracin vaya acompaada de un breve comentario:

    float Radio; // Radio del circulo del cual se calcula

    el area.

    float Area; // Area del circulo

    Acceso a variables

    Una variable se usa para asignarle un valor (acceso de escritura) o para utilizar el valor almacenado (acceso de lectura).

    Una vez declarada una variable debe recibir algn valor (es su misin, despus de

    todo). Este valor lo puede recibir de algn dispositivo (flujo de entrada) o como

    resultado de evaluar una expresin. La manera ms simple de proporcionar un valor a una variable es emplear la instruccin de asignacin:

    Radio = 10.0F;

    En el ejemplo se asigna el valor (literal entero) 10 a la variable Radio. El valor que

    tuviera almacenado la variable Radio se pierde, quedando fijado a 10.

    En la misma lnea de la declaracin puede asignarse un valor a la variable, por lo que declaracin e inicializacin:

    float Radio; // Declaracion

    Radio = 10.0F; // Inicializacion

    pueden simplificarse en una sola lnea:

    float Radio = 10.0F; // Declaracion e Inicializacion

    La manera ms simple de leer el valor de una variable es emplearla como parte de una expresin, por ejemplo, en la parte derecha de una instruccin de asignacin:

    Area = 2 * 3.1416F * Radio * Radio;

    La variable Radio (su valor) se emplea en la expresin 2 * 3.1416 * Radio *

    Radio para calcular el rea de un crculo de radio Radio. Una vez calculado el valor

    de la expresin, ste se asigna a la variable Area.

  • Otra manera de acceder al valor de una variable para lectura es emplearla como el

    argumento de una instruccin de escritura WriteLine. Por ejemplo,

    Console.WriteLine(Area);

    mostrar en la consola el valor de la variable Area.

    Leer el valor de una variable no modifica el contenido de la variable.

    A modo de resumen, un programa que calcula y muestra el rea de un crulo de radio

    10 es el siguiente:

    Calculo del rea de un crculo (1)

    using System;

    class Area1

    {

    static void Main(string[] args)

    {

    float Radio = 10.0F;

    float Area = 2 * 3.1416F * Radio * Radio;

    Console.WriteLine(Area);

    Console.ReadLine();

    }

    }

    Como puede parecer evidente, emplear una variable que no ha sido declarada produce

    un error en tiempo de compilacin. En C#, adems, hay que asignarle un valor antes

    de utilizarla. Si no se hace se genera un error en tiempo de compilacin ya que esta

    comprobacin (igual que ocurre en Java) se efecta por el compilador.

    void f()

    {

    int i;

    Console.WriteLine(i); // Error: uso de la variable

    local no asignada 'i'

    }

  • Constantes

    Una constante se define de manera parecida a una variable: modeliza una zona de

    memoria que puede almacenar un valor de un tipo determinado. La diferencia reside

    en que esa zona de memoria (su contenido) no puede modificarse en la ejecucin del

    programa. El valor de la constante se asigna en la declaracin.

    Sintcticamente se especifica que un dato es constante al preceder con la palabra

    reservada const su declaracin. Por ejemplo, para declarar un a constante de tipo

    float llamada PI y asignarle el valor (constante) 3.1416 se escribir:

    const float PI = 3.1416F;

    Solo se puede consultar el valor de una constante, nunca se debe intentar modificarlo

    porque se producira un error en tiempo de compilacin. Por ejemplo, la siguiente instruccin:

    Area = 2 * PI * Radio * Radio;

    utiliza la constante PI declarada anteriormente, usando su valor para evaluar una

    expresin.

    Podemos modificar el programa anterior para que utilice la constante PI:

    Calculo del rea de un crculo (2)

    using System;

    class Area2

    {

    static void Main(string[] args)

    {

    const float PI = 3.1416F;

    float Radio = 10.0F;

    float Area = 2 * PI * Radio * Radio;

    Console.WriteLine(Area);

    Console.ReadLine();

    }

    }

    mbito de variables y constantes

    El mbito (del ingls scope) de una variable y/o constante indica en qu partes del

    cdigo es lcito su uso.

    En C# el mbito abarca desde el lugar de su declaracin hasta donde termina el bloque en el que fue declarada.

  • En el mbito de una variable no puede declararse otra variable con el mismo nombre

    (aunque sea en un bloque interno, algo que si est permitido en C++):

    static void Main(string[] args)

    {

    float Radio = 10.0F;

    ...

    if (Radio > 0){

    float Radio = 20.0F; // Error: No se puede

    declarar una variable

    // local denominada

    'Radio' en este mbito.

    }

    ...

    }

    Operadores y expresiones

    Un operador est formado por uno o ms caracteres y permite realizar una

    determinada operacin entre uno o ms datos y produce un resultado. Es una manera simblica de expresar una operacin sobre unos operandos.

    C# proporciona un conjunto fijo, suficiente y completo de operadores. El significado de

    cada operador est perfectamente definido para los tipos predefinidos, aunque algunos

    de ellos pueden sobrecargarse, es decir, cambiar su significado al aplicarlos a un tipo definido por el usuario.

    C# dispone de operadores aritmticos, lgicos, relacionales, de manipulacin de bits,

    asignacin, para acceso a tablas y objetos, etc. Los operadores pueden presentarse por diferentes criterios, por ejemplo, por su funcionalidad:

    Categoras Operadores

    Aritmticos + - * /

    %

    Lgicos (booleanos y bit a bit) & | ^ ! ~ &&

    ||

    Concatenacin de cadenas +

    Incremento y decremento ++ --

    Desplazamiento >

    Relacionales == != < > =

    Asignacin

    = += -= *= /=

    %= &=

    |= ^= =

  • Acceso a miembros .

    Acceso por ndices []

    Conversin de tipos explcita ()

    Conditional ? :

    Creacin de objetos new

    Informacin de tipos as is sizeof

    typeof

    Control de excepciones de

    desbordamiento checked unchecked

    Direccionamiento indirecto y

    direccin * -> [] &

    Los operadores aritmticos de C# son los que se emplean

    comnmente en otros lenguajes: + (suma), - (resta), *

    (multiplicacin), / (divisin) y % (mdulo o resto de la divisin).

    Son operadores binarios y se colocan entre los argumentos sobre

    los que se aplican, proporcionando un resultado numrico (Por

    ejemplo, 7+3.5, 66 % 4).

    Los operadores lgicos proporcionan un resultado de tipo lgico

    (bool) y los operadores a nivel de bit actan sobre la

    representacin interna de sus operandos (de tipos enteros) y proporcionan resultados de tipo numrico.

    Los operadores binarios son: & (operacin Y lgica entre

    argumentos lgicos u operacin Y bit a bit entre operandos

    numricos), | (operacin O, lgica bit a bit, dependiendo del tipo

    de los argumentos) , ^ (O exclusivo, lgico bit a bit), && (Y lgico,

    que evala el segundo operando solo cuando es necesario) y || (O

    lgico, que evala el segundo operando solo cuando es necesario).

    Los operadores unarios son: ! (negacin o complemento de un

    argumento lgico) y ~ (complemento bit a bit de un argumento

    numrico).

    El operador + para la concatenacin de cadenas es un operador

    binario. Cuando al menos uno de los operandos es de tipo string

    este operador acta uniendo las representaciones de tipo string

    de los operandos.

    Operadores de incremento y decremento. El operador de

    incremento (++) incrementa su operando en 1 mientras que el de

    decremento (--) decrementa su operando en 1. Puede aparecer

  • antes de su operando: ++v (incremento prefijo) o despus: v++

    (incremento postfijo).

    El incremento prefijo hace que el resultado sea el valor del

    operando despus de haber sido incrementado y el postfijo hace

    que el resultado sea valor del operando antes de haber sido

    incrementado.

    Los tipos numricos y de enumeracin poseen operadores de

    incremento y decremento predefinidos.

    Los operadores de desplazamiento son operadores binarios.

    Producen un desplazamiento a nivel de bits de la representacin

    interna del primer operando (de un tipo entero), a la izquierda () el nmero de bits especificado por su segundo

    operando.

    Los operadores relacionales proporcionan un resultado lgico,

    dependiendo de si sus argumentos son iguales (==), diferentes

    (!=), o del orden relativo entre ellos (, =).

    La asignacin simple (=) almacena el valor del operando situado a su

    derecha en una variable (posicin de memoria) indicada por el

    operando situado a su izquierda.

    Los operandos deben ser del mismo tipo o el operando de la

    derecha se debe poder convertir implcitamente al tipo del operando de la izquierda).

    El operador de asignacin = produce los siguientes resultados:

    o En tipos simples el funcionamiento es similar al de C++, copia

    el contenido de la expresin de la derecha en el objeto que

    recibe el valor.

    o En datos struct realiza una copia directa del contenido, como

    en C++.

    o En clases se copia la referencia, esto es, la direccin del

    objeto, provocando que el objeto sea referenciado por ms de una referencia.

    Este comportamiento es distinto al que se produce en C++, en

    el que se copia el contenido del objeto. Si el objeto contiene

    estructuras ms complejas, C++ requiere normalmente la

    sobrecarga del operador para personalizar la manera en que se

    realiza la copia para que cada instancia de la clase (fuente y

    destino) maneje su propia zona de memoria. En C# no se

    permite la sobrecarga del operador =

    Los otros operadores de esta categora realizan, adems de la asignacin otra operacin previa a la asignacin. Por ejemplo,

    a += 22;

  • equivale a

    a = a + 22;

    o sea, primero se calcula la expresin a+22 y posteriormente, ese

    valor se almacena en a.

    De la misma manera actan los dems operadores de asignacin: -

    =, *=, /=, %=, &=, |=, ^=, >=.

    Para asignar instancias de clases (en el sentido clsico de C++) se

    debe redefinir el mtodo MemberwiseCopy() que es heredado por

    todas las clases desde System.Object (todas las clases heredan, en ltima instancia de System.Object).

    El operador de acceso a miembros es el operador punto (.) y se

    emplea para acceder a los miembros (componentes) de una clase,

    estructura o espacio de nombres.

    El operador de acceso por ndices es el tradicional, formado por la

    pareja de caracteres [ y ]. En C# tambin se emplea para

    especificar atributos.

    El operador de conversin explcita de tipos (casting) es el clsico,

    formado por la pareja de caracteres ( y ).

    El operador ternario condicional evala una condicin lgica y devuelve uno de dos valores.

    Se utiliza en expresiones de la forma:

    cond ? expr1 : expr2

    de manera que si cond es verdad, se evala expr1 y se devuelve

    como resultado; si cond es falsa se evala expr1 y se devuelve

    como resultado.

    Creacin de objetos (new). El operador new permite crear instancias

    de una clase definida por el usuario. Por ejemplo:

    ObjetoDemo o1 = new ObjetoDemo() declara una referencia

    (llamada o1) a un objeto de la clase ObjetoDemo y crea una

    instancia de esa clase, referenciada por o1. En realidad, la creacin

    de un objeto implica la llamada a un constructor de la clase.

    Control de excepciones de desbordamiento: checked y unchecked

    C# proporciona la posibilidad de realizar operaciones de moldeado

    (casting) y aritmticas en un contexto verificado. En otras palabras,

    el entorno de ejecucin .NET detecta cualquier situacin de

    desbordamiento y lanza una excepcin (OverFlowException) si

    sta se manifiesta.

  • En un contexto verificado (checked), si una expresin produce un

    valor fuera del rango del tipo de destino, el resultado depende de si

    la expresin es constante o no. Las expresiones constantes

    producen errores de compilacin, mientras que las expresiones no

    constantes se evalan en tiempo de ejecucin y producen excepciones.

    Si no se especifican ni checked ni unchecked, las expresiones

    constantes utilizan la verificacin de desbordamiento

    predeterminada en tiempo de compilacin, que es checked. De lo

    contrario, si la expresin no es constante, la verificacin de

    desbordamiento en tiempo de ejecucin depende de otros factores

    tales como las opciones del compilador y la configuracin del

    entorno. En el siguiente ejemplo, el valor por defecto es

    unchecked:

    using System;

    class PruebaDesbordamiento

    {

    static short x = 32767; // Maximo valor short

    static short y = 32767;

    public static int UnCh()

    {

    int z = unchecked((short)(x + y));

    return z; // -2

    }

    public static int UnCh2()

    {

    int z = (short)(x + y); // Por defecto es

    unchecked

    return z; // -2

    }

    public static void Main()

    {

    Console.WriteLine("Valor -unchecked-: {0}",

    UnCh());

    Console.WriteLine("Valor por defecto: {0}",

    UnCh2());

    Console.ReadLine();

    }

    }

    El resultado es:

    Valor -unchecked-: -2

    Valor por defecto: -2

    Si aadimos la funcin:

  • public static int Ch()

    {

    int z = checked((short)(x + y));

    return z;

    }

    y la llamada:

    Console.WriteLine("Valor -checked- : {0}", Ch());

    la ejecucin del programa provoca el lanzamiento de una excepcin

    System.OverflowException que detiene la ejecucin del

    programa, al no estar controlada.

    Operadores especiales: as is typeof

    El operador as

    El operador as se utiliza para realizar conversiones entre tipos compatibles (al estilo de

    los casts dinmicos de C++). El operador as se utiliza en expresiones de la forma:

    as type

    donde es una expresin de un tipo de referencia, y type es un tipo

    de referencia. Si la conversin de tipo no es posible, el resultado es null.

    // Ejempo de uso del operador as

    using System;

    class Clase1 {}

    class Clase2 {}

    public class Demo

    {

    public static void Main()

    {

    object [] Objetos = new object[6];

    Objetos[0] = new Clase1();

    Objetos[1] = new Clase1();

    Objetos[2] = "Hola";

    Objetos[3] = 123;

    Objetos[4] = 123.4;

    Objetos[5] = null;

    for (int i=0; i

  • Console.Write ("{0}:", i);

    if (s != null)

    Console.WriteLine ( "'" + s + "'" );

    else

    Console.WriteLine ( "no es string" );

    }

    Console.ReadLine();

    }

    }

    El resultado es:

    0:no es string

    1:no es string

    2:'Hola'

    3:no es string

    4:no es string

    5:no es string

    En el siguiente ejemplo, la funcin DoSomething recibe cualquier argumento, pero

    slo cuando es de tipo Car se ejecuta el mtodo Drive sobre el objeto c (de clase

    Car).

    static void DoSomething(object o)

    {

    Car c = o as Car;

    if (c != null) c.Drive();

    }

    El operador is

    El operador is se utiliza para comprobar en tiempo de ejecucin si el tipo de un objeto

    es compatible con un tipo dado. El operador is se utiliza en expresiones de la forma:

    is type

    donde es una expresin de un tipo de referencia, y type es un tipo

    de referencia.

    El siguiente ejemplo realiza la misma tarea que comentamos en el ejemplo sobre el

    operador as solo que ahora no hay ningn objeto local con referencia explcita sobre el

    que se ejecute el mtodo Drive.

    static void DoSomething(object o)

    {

    if (o is Car) ((Car)o).Drive();

    }

  • El operador typeof

    El operador typeof devuelve el objeto derivado de System.Type correspondiente al

    tipo especificado.

    Una expresin typeof se presenta de la siguiente forma:

    typeof (tipo)

    donde tipo es el tipo cuyo objeto System.Type se desea obtener.

    De esta forma se puede hacer reflexin para obtener dinmicamente informacin sobre los tipos (como en Java).

    ...

    Console.WriteLine(typeof(int).FullName);

    Console.WriteLine(typeof(System.Int).Name);

    Console.WriteLine(typeof(float).Module);

    Console.WriteLine(typeof(double).IsPublic);

    Console.WriteLine(typeof(Point).MemberType);

    ...

    Un ejemplo en el que se emplean los operadores is, as y typeof para discriminar el

    tipo del argumento recibido en una funcin polimrfica y trabajar con l es el siguiente:

    // Ejempo de uso de los operadores is, as y typeof

    using System;

    class Clase1 {}

    class Clase2 {}

    public class Demo

    {

    public static void Prueba (object o)

    {

    Clase1 a;

    Clase2 b;

  • Type t;

    if (o is Clase1)

    {

    Console.WriteLine ("\no es de Clase1");

    a = (Clase1)o;

    Console.WriteLine ("--> {0}",

    typeof(Clase1).FullName);

    t = typeof(Clase1);

    }

    else if (o is Clase2)

    {

    Console.WriteLine ("\no es de Clase2");

    b = o as Clase2;

    t = typeof(Clase2);

    }

    else

    {

    Console.WriteLine ("\no no es ni de Clase1 ni

    de Clase2.");

    t = o.GetType();

    }

    Console.WriteLine ("Su tipo es " + t.FullName);

    }

    public static void Main()

    {

    Clase1 c1 = new Clase1();

    Clase2 c2 = new Clase2();

    Prueba (c1);

    Prueba (c2);

    Prueba ("Un string");

    Console.ReadLine();

    }

    }

    El resultado es:

    o es de Clase1

    --> Clase1

    Su tipo es Clase1

    o es de Clase2

    Su tipo es Clase2

    o no es ni de Clase1 ni de Clase2.

    Su tipo es System.String

  • Precedencia

    Tambin podran presentarse por precedencia. En la tabla siguiente los enumeramos de mayor a menor precedencia:

    Categoras Operadores

    Primarios

    Parntesis: (x)

    Acceso a miembros: x.y

    Llamada a mtodos: f(x)

    Acceso con ndices: a[x]

    Post-incremento: x++

    Post-decremento: x--

    Llamada a un constructor: new

    Consulta de tipo: typeof

    Control de desbordamiento activo: checked

    Control de desbordamiento inactivo: unchecked

    Unarios

    Valor positivo: +

    Valor negative: -

    No: !

    Complemento a nivel de bit: ~

    Pre-incremento: ++x

    Post-decremento: --x

    Conversin de tipo -cast-: (T)x

    Multiplicativos

    Multiplicacin: *

    Divisin: /

    Resto: %

  • Aditivos

    Suma: +

    Resta: -

    Desplazamiento

    Desplazamiento de bits a la izquierda: >

    Relacionales

    Menor: <

    Mayor: >

    Menor o igual: =

    Igualdad o compatibilidad de tipo: is

    Conversin de tipo: as

    Igualdad ==

    Desigualdad !=

    Bitwise AND &

    Bitwise XOR ^

    Bitwise OR |

    Logical AND &&

    Logical OR ||

    Condicional

    ternario ?:

    Asignacin =, *=, /=, %=, +=, -=, =, &=, ^=,

    |=

  • Asociatividad

    Como siempre, es mejor utilizar parntesis para controlar el orden de evaluacin

    x = y = z se evala como x = (y = z)

    x + y + z se evala como (x + y) + z

    Estructuras de control

    Las estructuras de control de C# son similares a las de C y C++. La diferencia ms

    notable radica en que la instruccin condicional if y los ciclos while y do estn

    controlados por una expresin lgica (tipo Boolean).

    Esta restriccin hace que las instrucciones sean ms seguras al evitar posibles fuentes

    de error, o al menos, facilitan la legibilidad del cdigo. Por ejemplo, en la siguiente instruccin (vlida en C++):

    if (a)

    la expresin a podra ser una expresin boolean pero tambin de tipo int, char,

    float *... y la condicin se evala como true cuando a es distinto de cero (valor

    entero 0, carcter 0 puntero nulo, en los ejemplos). En C# se clarifica esta

    ambigedad y slo se admiten expresiones lgicas. De esta manera, la instruccin

    anterior ser vlida slo cuando a sea una expresin boolean.

    A modo de resumen, las caractersticas propias de las estructuras de control de C# son:

    goto no puede saltar dentro de un bloque (da igual, de todas formas

    no lo usaremos NUNCA).

    switch funciona como en Pascal (no como en C).

    Se aade una nueva estructura de control iterativa: foreach.

    Estructuras condicionales

    if, if-else

    La estructura condicional tiene la sintaxis clsica, con la diferencia indicada

    anteriormente acerca del tipo de la expresin. Si debe ejecutar ms de una instruccin,

    se encierran en un bloque, delimitado por las llaves { y }.

  • Si slo se acta cuando la condicin es cierta:

    if (a > 0) if (a > 0)

    {

    Console.WriteLine ("Positivo");

    Console.WriteLine ("Positivo");

    ContPositivos++;

    }

    Si se acta cuando la condicin es falsa se emplea la palabra reservada else:

    if (a > 0) if (a > 0)

    {

    Console.WriteLine ("Positivo");

    Console.WriteLine ("Positivo");

    else

    ContPositivos++;

    Console.WriteLine ("No Positivo"); }

    else {

    Console.WriteLine ("No Positivo");

    ContNoPositivos++;

    }

    Puede escribirse una instruccin condicional dentro de otra instruccin condicional,

    lgicamente:

    if (a > 0) {

    Console.WriteLine ("Positivo");

    ContPositivos++;

    }

    else {

    if (a < 0) {

    Console.WriteLine ("Negativo");

    ContNegativos++;

    }

    else {

    Console.WriteLine ("Cero");

    ContCeros++;

    }

    }

    La concordancia entre if y else se establece de manera sencilla: cada else se asocia

    al ltimo if que no tenga asociado un bloque else.

  • switch

    La estructura de seleccin mltiple switch funciona sobre cualquier tipo predefinido

    (incluyendo string) o enumerado (enum) y debe indicar explcitamente cmo

    terminar cada caso (generalmente, con break en situaciones "normales" throw

    en situaciones "anormales", aunque es posible -pero no recomendable- emplear goto

    case return ):

    using System;

    class HolaMundoSwitch

    {

    public static void Main(String[] args)

    {

    if (args.Length > 0)

    switch(args[0])

    {

    case "Jos":

    Console.WriteLine("Hola Jos. Buenos

    das");

    break;

    case "Paco":

    Console.WriteLine("Hola Paco. Me alegro de

    verte");

    break;

    default: Console.WriteLine("Hola {0}",

    args[0]);

    break;

    }

    else

    Console.WriteLine("Hola Mundo");

    }

    }

    Especificar los parmetros al programa en Visual Studio: Utilizar el explorador de

    soluciones para configurar las propiedades del proyecto.

  • Un ejemplo que usa un datos string para controlar la seleccin:

    using System;

    namespace ConsoleApplication14

    {

    class Class1

    {

    static int Test(string label)

    {

    int res;

    switch(label)

    {

    case null:

    goto case "A"; // idem case "B" o case

    "A"

    case "B":

    case "C":

    res = 1;

    break;

    case "A":

    res = 2;

    break;

    default:

    res = 0;

    break;

    }

    return res;

    }

    static void Main(string[] args)

    {

    Console.WriteLine (Test("")); // 0

    Console.WriteLine (Test("A")); // 2

    Console.WriteLine (Test("B")); // 1

    Console.WriteLine (Test("C")); // 1

    Console.WriteLine (Test("?")); // 0

    Console.ReadLine();

    }

    }

    }

  • Estructuras repetitivas

    Las estructuras repetitivas de C# (while, do...while, for) no presentan grandes

    diferencias respecto a las de otros lenguajes, como C++. La aportacin fundamental es

    la de la estructura iterativa en colecciones foreach.

    while

    int i = 0;

    while (i < 5) {

    ...

    i++;

    }

    do...while

    int i = 0;

    do {

    ...

    i++;

    } while (i < 5);

    for

    int i;

    for (i=0; i < 5; i++) {

    ...

    }

  • foreach

    Un ciclo foreach itera seleccionando todos los miembros de un vector, matriz u otra

    coleccin sin que se requiera explicitar los ndices que permiten acceder a los

    miembros. El siguiente ejemplo muestra todos los argumentos recibidos por el programa cuando se invoca su ejecucin (argumentos en la lnea de rdenes):

    public static void Main(string[] args)

    {

    foreach (string s in args)

    Console.WriteLine(s);

    }

    El vector (la coleccin) que se utiliza para iterar es args. Es un vector de datos

    string. El ciclo foreach realiza tantas iteraciones como cadenas contenga el vector

    args, y en cada iteracin toma una y la procesa a travs de la variable de control s.

    El ejemplo siguiente realiza la misma funcin:

    public static void Main(string[] args)

    {

    for (int i=0; i < args.Lenght; i++)

    Console.WriteLine(args[i]);

    }

    El ciclo foreach proporciona acceso de slo lectura a los elementos de la coleccin

    sobre la que se itera. Por ejemplo, el cdigo de la izquierda no compilar, aunque el de

    la derecha s lo har (v es un vector de int):

    foreach (int i in v) for (int i=0; i <

    v.Length; i++)

    i *= 2; v[i] *= 2;

    El ciclo foreach puede emplearse en vectores y colecciones. Una coleccin es una

    clase que implementa el interfaz IEnumerable. Sobre las colecciones dicutiremos ms

    adelante.

  • Saltos

    goto

    Aunque el lenguaje lo permita, nunca escribiremos algo como lo que aparece a continuacin:

    using System;

    namespace DemoGoto

    {

    class MainClass

    {

    static void Busca(int val, int[,] vector, out

    int fil, out int col)

    {

    int i, j;

    for (i = 0; i < vector.GetLength(0); i++)

    for (j = 0; j < vector.GetLength(1); j++)

    if (vector[i, j] == val) goto OK;

    throw new InvalidOperationException("Valor no

    encontrado");

    OK:

    fil = i; col = j;

    }

    static void Main(string[] args)

    {

    int [,] coleccion = new int [2,3]

    {{1,0,4},{3,2,5}};

    int f,c;

    int valor = Convert.ToInt32(args[0]);

    Busca (valor, coleccion, out f, out c);

    Console.WriteLine ("El valor {0} esta en

    [{1},{2}]", valor,f,c);

    Console.ReadLine();

    }

    }

    }

    break

    Lo usaremos nicamente en sentencias switch.

    continue

    Mejor no lo usamos.

    return

    Procuraremos emplearlo slo al final de un mtodo para facilitar la legibilidad del cdigo.

  • Tipos de datos

    Tipos bsicos

    El sistema unificado de tipos. El tipo Object

    Cadenas de caracteres

    Vectores y matrices

    Estructuras

    Enumeraciones

    Cuando definimos un objeto debemos especificar su tipo. El tipo determina qu valores

    puede almacenar ese objeto (clase y rango) y las operaciones que pueden efectuarse con l.

    Como cualquier lenguaje de programacin, C# proporciona una serie de tipos

    predefinidos (int, byte, char, string, ...) y mecanismos para que el usuario cree

    sus propios tipos (class y struct).

    La estructura de tipos de C# es una gran novedad ya que establece una relacin

    jerrquica entre stos, de manera que todos los tipos son clases y se construyen por

    herencia de la clase base Objet. Esta particularidad hace que la creacin y gestin de

    tipos de datos en C# sea una de las principales novedades y potencialidades del lenguaje.

    Tipos bsicos

    Los tipos de datos bsicos son los tipos de datos ms comnmente utilizados en

    programacin.

    Los tipos predefinidos en C# estn definidos en el espacio de nombres System, que es

    el espacio de nombres ms numeroso (e importante) de la plataforma .NET. Por

    ejemplo, para representar nmeros enteros de 32 bits con signo se utiliza el tipo de

    dato System.Int32 y a la hora de crear un objeto a de este tipo que represente el

    valor 2 se usa la siguiente sintaxis:

    System.Int32 a = 2;

    Al ser un tipo valor no se utiliza el operador new para crear objetos System.Int32,

    sino que directamente se indica el literal que representa el valor a crear, con lo que la

    sintaxis necesaria para crear entero de este tipo se reduce considerablemente. Es ms,

    dado lo frecuente que es el uso de este tipo tambin se ha predefinido en C# el alias

    int para el mismo, por lo que la definicin de variable anterior queda as de

    compacta:

    int a = 2;

  • System.Int32 no es el nico tipo de dato bsico incluido en C#. En el espacio de

    nombres System se han incluido los siguientes tipos:

    C# Tipo en System Caractersticas Smbolo

    sbyte System.Sbyte entero, 1 byte con signo

    byte System.Byte entero, 1 byte sin signo

    short System.Short entero, 2 bytes con signo

    ushort System.UShort entero, 2 bytes sin signo

    int System.Int32 entero, 4 bytes con signo

    uint System.UInt32 entero, 4 bytes sin signo U

    long System.Int64 entero, 8 bytes con signo L

    ulong System.ULong64 entero, 8 bytes sin signo UL

    float System.Single real, IEEE 754, 32 bits F

    double System.Double real, IEEE 754, 64 bits D

    decimal System.Decimal real, 128 bits (28 dgitos

    significativos) M

    bool System.Boolean (Verdad/Falso) 1 byte

    char System.Char Carcter Unicode, 2 bytes

    string System.String Cadenas de caracteres

    Unicode " "

    object System.Object Cualquier objeto (ningn

    tipo concreto)

    Los tipos estn definidos de manera muy precisa y no son dependientes del compilador o de la plataforma en la que se usan.

    La tabla anterior incorpora la columna Smbolo para indicar cmo debe interpretarse

    un literal. Por ejemplo, 28UL debe interpretarse como un entero largo sin signo

    (ulong).

    Todos los tipos enumerados son tipos valor, excepto string (que no debe confundirse

    con un vector de caracteres) y Object que son tipos referencia. Recuerde, no

    obstante, que los datos string se comportaban como un tipo valor ante la asgnacin.

  • El sistema unificado de tipos. El tipo Object

    En C# desaparecen las variables y funciones globales: todo el cdigo y todos los

    datos de una aplicacin forman parte de objetos que encapsulan datos y

    cdigo (como ejemplo, recuerde cmo Main() es un mtodo de una clase). Como en

    otros lenguajes orientados a objetos, en C# un tipo puede incluir datos y mtodos.

    De hecho, hasta los tipos bsicos predefinidos incluyen mtodos, que, como veremos,

    heredan de la clase base object, a partir de la cual se construyen implcita o

    explcitamente todos los tipos de datos. Por ejemplo:

    int i = 10;

    string c = i.ToString();

    e incluso: string c = 10.ToString();

    Esta manera por la que podemos manipular los datos bsicos refleja la ntima relacin

    entre C# y la biblioteca de clase de .NET. De hecho, C# compila sus tipos bsicos

    asocindolos a sus correspondientes en .NET; por ejemplo, hace corresponder al tipo

    string) con la clase System.String, al tipo int) con la clase System.Int32, etc.

    As, se confirma que todo es un objeto en C# (por si an haba alguna duda).

    Aunque no comentaremos todos los mtodos disponibles para los tipos bsicos, destacaremos algunos de ellos.

    Todos los tipos tienen un mtodo ToString() que devuelve una

    cadena (string) que representa su valor textual.

    char tiene propiedades acerca de su contenido (IsLetter,

    IsNumber, etc.) adems de mtodos para realizar conversiones

    (ToUpper(), ToLower(), etc.)

    El tipo bsico string dispone, como puede suponerse, de muchos

    mtodos especficos, an ms que la clase string de la biblioteca

    estndar de C++.

    Algunos mtodos estticos y propiedades particularmente interesantes son:

    Los tipos numricos enteros tipos tienen las propiedades MinValue y

    MaxValue (p.e. int.MaxValue).

    Los tipos float y double tienen la propiedad Epsilon, que indica el

    mnimo valor positivo que puede representarse en un dato de su

    tipo (p.e. float.Epsilon).

    Los tipos float y double tienen definidos los valores NaN (no es un

    nmero, no est definido), PositiveInfinite y

    NegativeInfinity, valores que son pueden ser devueltos al

    realizar ciertos clculos.

    Muchos tipos, incluyendo todos los tipos numricos, proporcionan el

    mtodo Parse() que permite la conversin desde un dato string

    (p.e. double d = double.Parse("20.5"))

  • Conversiones de tipos

    Una conversin de tipo (casting) puede ser implcita o explcita.

    Implcitas Explcitas

    Ocurren automticamente Requieren un casting

    Siempre tienen xito Pueden fallar

    No se pierde informacin Se puede perder informacin

    int x = 123456;

    long y = x; // implicita

    short z = (short) x; // explicita (riesgo)

    float f1 = 40.0F;

    long l1 = (long) f1; // explicita (riesgo por

    redondeo)

    short s1 = (short) l1; // explicita (riesgo por

    desbordamiento)

    int i1 = s1; // implicita, no hay riesgo

    uint i2 = (uint) i1; // explicita (riesgo de error

    por signo)

    En C# las conversiones de tipo (tanto implcitas como explcitas) en las que

    intervengan tipos definidos por el usuario pueden definirse y particularizarse.

    Recordemos que pueden emplearse los operadores checked y unchecked para

    realizar conversiones (y operaciones aritmticas) en un contexto verificado: el entorno

    de ejecucin .NET detecta cualquier situacin de desbordamiento y lanza una

    excepcin OverFlowException si sta se manifiesta.

    El tipo object

    Por el sistema unificado de tipos de C#, todo es un objeto. C# tiene predefinido un

    tipo referencia llamado object y cualquier tipo (valor o referencia, predefinido o

    definido por el usuario) es en ltima instancia, de tipo object (con otras palabras

    puede decirse que hereda todas las caractersticas de ese tipo).

    El tipo object se basa en System.Object de .NET Framework. Las variables de tipo

    object pueden recibir valores de cualquier tipo. Todos los tipos de datos, predefinidos

    y definidos por el usuario, heredan de la clase System.Object. La clase Object es la

    superclase fundamental de todas las clases de .NET Framework; la raz de la jerarqua de tipos.

  • Normalmente, los lenguajes no precisan una clase para declarar la herencia de Object

    porque est implcita.

    Por ejemplo, dada la siguiente declaracin:

    object o;

    todas estas instrucciones son vlidas: o = 10; // int

    o = "Una cadena para el objeto"; // cadena

    o = 3.1415926; // double

    o = new int [24]; // vector de int

    o = false; // boolean

    Dado que todas las clases de .NET Framework se derivan de Object, todos los

    mtodos definidos en la clase Object estn disponibles en todos los objetos del

    sistema. Las clases derivadas pueden reemplazar, y de hecho reemplazan, algunos de estos mtodos, entre los que se incluyen los siguientes:

    public void Object() Inicializa una nueva instancia de la clase

    Object. Los constructores llaman a este constructor en clases

    derivadas, pero ste tambin puede utilizarse para crear una

    instancia de la clase Object directamente.

    public bool Equals(object obj) Determina si el objeto

    especificado es igual al objeto actual.

    protected void Finalize() Realiza operaciones de limpieza

    antes de que un objeto sea reclamado automticamente por el

    recolector de elementos no utilizados.

    public int GetHashCode() Sirve como funcin hash para un tipo

    concreto, apropiado para su utilizacin en algoritmos de hash y

    estructuras de datos como las tablas hash.

    public string ToString() Devuelve un objeto string que

    representa al objeto actual. Se emplea para crear una cadena de

    texto legible para el usuario que describe una instancia de la clase.

    La implementacin predeterminada devuelve el nombre completo

    del tipo del objeto Object. En el ltimo ejemplo, si cada vez que

    asignamos un valor a o ejecutamos Console.WriteLine

    (o.ToString()) o simplemente Console.WriteLine (o);

    obtendremos este resultado:

    10

    Una cadena para el objeto

    3,1415926

    System.Int32[]

    False

  • public Type GetType() Obtiene el objeto Type que representa el

    tipo exacto en tiempo de ejecucin de la instancia actual.

    En el ltimo ejemplo, si cada vez que asignamos un valor a o

    ejecutamos Console.WriteLine (o.getType()) obtendremos

    este resultado:

    System.Int32

    System.String

    System.Double

    System.Int32[]

    System.Boolean

    protected object MemberwiseClone() Crea una copia

    superficial del objeto Object actual. No se puede reemplazar este

    mtodo; una clase derivada debe implementar la interfaz

    ICloneable si una copia superficial no es apropiada.

    MemberwiseClone() est protegido y, por tanto, slo es accesible

    a travs de esta clase o de una clase derivada. Una copia superficial

    crea una nueva instancia del mismo tipo que el objeto original y,

    despus, copia los campos no estticos del objeto original. Si el

    campo es un tipo de valor, se realiza una copia bit a bit del campo.

    Si el campo es un tipo de referencia, la referencia se copia, pero no

    se copia el objeto al que se hace referencia; por lo tanto, la

    referencia del objeto original y la referencia del punto del duplicado

    apuntan al mismo objeto. Por el contrario, una copia profunda de

    un objeto duplica todo aquello a lo que hacen referencia los campos del objeto directa o indirectamente.

    Polimorfismo -boxing y unboxing-

    Boxing (y su operacin inversa, unboxing) permiten tratar a los tipos valor como

    objetos (tipo referencia). Los tipos de valor, incluidos los struct y los predefinidos,

    como int, se pueden convertir al tipo object (boxing) y desde el tipo object

    (unboxing).

    La posibilidad de realizar boxing permite construir funciones polimrficas: pueden realizar una operacin sobre un objeto sin conocer su tipo concreto.

    void Polim(object o)

    {

    Console.WriteLine(o.ToString());

    }

    ...

    Polim(42);

    Polim("abcd");

    Polim(12.345678901234M);

    Polim(new Point(23,45));

  • Boxing

    Boxing es una conversin implcita de un tipo valor al tipo object. Cuando se realiza

    boxing de un valor, se asigna una instancia de objeto y se copia el valor en el nuevo objeto.

    Por ejemplo, considere la siguiente declaracin de una variable de tipo de valor:

    int i = 123;

    La siguiente instruccin aplica implcitamente la operacin de boxing sobre la variable

    i: object o = i;

    El resultado de esta instruccin es crear un objeto o en la pila que hace referencia a un

    valor del tipo int alojado en el heap. Este valor es una copia del valor del tipo de valor

    asignado a la variable i. La diferencia entre las dos variables, i y o se muestra en la

    siguiente figura:

    En definitiva, el efecto del boxing es el de cualquier otro tipo de casting pero:

    el contenido de la variable se copia al heap se crea una referencia a sta copia

    Aunque no es necesario, tambin es posible realizar el boxing explcitamente como en

    el siguiente ejemplo:

    int i = 123;

    object o = (object) i;

    El siguiente ejemplo convierte una variable entera i a un objeto o mediante boxing. A

    continuacin, el valor almacenado en la variable i se cambia de 123 a 456. El ejemplo

    muestra que el objeto mantiene la copia original del contenido, 123.

  • // Boxing de una variable int

    using System;

    class TestBoxing

    {

    public static void Main()

    {

    int i = 123;

    object o = i; // boxing implicito

    i = 456; // Modifica el valor de i

    Console.WriteLine("Valor (tipo valor) = {0}",

    i);

    Console.WriteLine("Valor (tipo object)= {0}",

    o);

    }

    }

    El resultado de su ejecucin es: Valor (tipo valor) = 456

    Valor (tipo object)= 123

    Unboxing

    Una vez que se ha hecho boxing sobre un dato y disponemos de un object no puede

    hacerse demasiado con l ya que no pueden emplearse mtodos o propiedades del tipo original: el compilador no puede conocer el tipo original sobre el que se hizo boxing.

    string s1 = "Hola";

    object o = s1; // boxing

    ...

    if (o.Lenght > 0) // ERROR

    Una vez que se ha hecho boxing puede deshacerse la conversin (unboxing) haciendo

    casting explcito al tipo de dato inicial.

    string s2 = (string) o; // unboxing

    Afortunadamente es posible conocer el tipo, de manera que si la conversin no es

    posible se lanza una excepcin. Pueden utilizarse los operadores is y as para

    determinar la correccin de la conversin:

    string s2;

    if (o is string)

    s2 = (string) o; // unboxing

    o alternativamente: string s2 = o as string; // conversion

    if (s2 != null) // OK, la conversion funciono

  • Conclusiones

    Ventajas del sistema unificado de tipos: las colecciones funcionan sobre cualquier tipo.

    Hashtable t = new Hashtable();

    t.Add(0, "zero");

    t.Add(1, "one");

    t.Add(2, "two");

    string s = string.Format("Your total was {0} on {1}",

    total, date);

    Desventajas del sistema unificado de tipos: Eficiencia.

    La necesidad de utilizar boxing disminuir cuando el CLR permita genricos (algo

    similar a los templates en C++).

    Cadenas de caracteres

    Una cadena de caracteres no es ms que una secuencia de caracteres Unicode. En

    C# se representan mediante objetos del tipo string, que no es ms que un alias del

    tipo System.String incluido en la BCL.

    El tipo string es un tipo referencia. Representa una serie de caracteres inmutable. Se

    dice que una instancia de String es inmutable porque no se puede modificar su valor

    una vez creada. Los mtodos que aparentemente modifican una cadena devuelven en

    realidad una cadena nueva que contiene la modificacin.

    Recuerde la particularidad de este tipo sobre el operador de asignacin: su

    funcionamiento es como si fuera un tipo valor. Este es, realmente, el funcionamiento

    obtenido con el mtodo Copy(). Si no se desea obtener una copia (independiente)

    sino una copia en el sentido de un tipo valor emplee el mtodo Clone().

    Puede accederse a cada uno de los caracteres de la cadena mediante ndice, como

    ocurre habitualmente en otros lenguajes, siendo la primera posicin asociada al ndice cero. Este acceso, no obstante, slo est permitido para lectura.

    string s = "!!Hola, mundo!!";;

    for (int i=0; i < s.Length; i++)

    Console.Write (s[i]);

    Este ejemplo muestra todos los caracteres que componen la cadena, uno a uno. El

    ciclo realiza tantas iteraciones como nmero de caracteres forman la cadena (su

    longitud) que se consulta usando la propiedad Length.

  • Por definicin, un objeto String, incluida la cadena vaca (""), es mayor que una

    referencia nula y dos referencias nulas son iguales entre s. El carcter null se define

    como el hexadecimal 0x00. Puede consultarse si una cadena es vaca empleando la

    propiedad esttica (slo lectura) Empty: el valor de este campo es la cadena de

    longitud cero o cadena vaca, "". Una cadena vaca no es igual que una cadena cuyo

    valor sea null.

    Los procedimientos de comparacin y de bsqueda distinguen maysculas de

    minsculas de forma predeterminada. Pueden emplearse los mtodos Compare() y

    Equals() para realizar referencias combinadas y comparaciones entre valores de

    instancias de Object y String. Los operadores relacionales == y != se implementan

    con el mtodo Equals().

    El mtodo Concat() concatena una o ms instancias de String o las

    representaciones de tipo String de los valores de una o ms instancias de Object. El

    operador + est sobrecargado para realizar la concatenacin. Por ejemplo, el siguiente

    cdigo:

    string s1 = "Esto es una cadena... como en C++";

    string s2 = "Esto es una cadena... ";

    string s3 = "como en C++";

    string s4 = s2 + s3;

    string s5 = String.Concat(s2, s3);

    Console.WriteLine ("s1 = {0}", s1);

    Console.WriteLine ("s4 = {0}", s4);

    Console.WriteLine ("s5 = {0}", s5);

    if ((s1 == s4) && (s1.Equals(s5)))

    Console.WriteLine ("s1 == s4 == s5");

    produce este resultado: s1 = Esto es una cadena... como en C++

    s4 = Esto es una cadena... como en C++

    s5 = Esto es una cadena... como en C++

    s1 == s4 == s5

    Un mtodo particularmente til es Split(), que devuelve un vector de cadenas

    resultante de "partir" la cadena sobre la que se aplica en palabras:

    string linea;

    string [] palabras;

    ...

    palabras = linea.Split (null); // null indica dividir por espacios

  • En definitiva, la clase String incluye numerosos mtodos, que pueden emplease

    para:

    Realizar bsquedas en cadenas de caracteres: IndexOf(),

    LastIndexOf(),

    StartsWith(), EndsWith()

    Eliminar e insertar espacios en blanco: Trim(), PadLeft(),

    PadRight()

    Manipular subcadenas: Insert(), Remove(), Replace(),

    Substring(),

    Join()

    Modificar cadenas de caracteres: ToLower(), ToUpper(),

    Format() (al estilo del printf de C, pero seguro).

    Vectores y matrices

    Un vector (matriz) en C# es radicalmente diferente a un vector (matriz) en C++: ms

    que una coleccin de variables que comparten un nombre y accesibles por ndice, en

    C# se trata de una instancia de la clase System.Array, y en consecuencia se trata de

    una coleccin que se almacena en el heap y que est bajo el control del gestor de memoria.

    Todas las tablas que definamos, sea cual sea el tipo de elementos que contengan, son

    objetos que derivan de System.Array. Ese espacio de nombres proporciona mtodos

    para la creacin, manipulacin, bsqueda y ordenacin de matrices, por lo tanto, sirve como clase base para todas las matrices de la CLR (Common Languag