You are on page 1of 120

Qu es C#?

C# o C Sharp es un lenguaje de programacin que est incluido en la Plataforma .NET y


corre en el Lenguaje Comn en Tiempo de Ejecucin (CLR, Common Language Runtime).
El primer lenguaje en importancia para el CLR es C#, mucho de lo que soporta la
Plataforma .NET est escrito en C#.
C# intenta ser el lenguaje base para escribir aplicaciones .NET
C# deriva de C y C++, es moderno, simple y enteramente orientado a objetos, simplifica y
moderniza a C++ en las reas de clases, namespaces, sobrecarga de mtodos y manejo de
excepciones. Se elimino la complejidad de C++ para hacerlo ms fcil de utilizar y menos
propenso a errores.
Algunas caractersticas de C# son:
C# provee el beneficio de un ambiente elegante y unificado.
No soporta herencia mltiple, solamente el runtime .NET permite la herencia
mltiple en la forma de interfaces, las cuales no pueden contener implementacin.
No maneja apuntadores, para emular la funcin de los apuntadores se utiliza
delegates el cual provee las bases para el .NET event model.
Por default trabaja con cdigo administrado.
La Plataforma .NET provee un colector de basura que es responsable de administrar
la memoria en los programas C#.
El manejo de errores est basado en excepciones.
Soporta los conceptos como encapsulacin, herencia y polimorfismo de la
programacin orientada a objetos.
El Modelo completo de clases est construido en la cima del .NET Virtual Object
System (VOS). El modelo de objetos es parte de la infraestructura y ya no forma
parte del lenguaje de progrmacin.
No existen funciones globales, variables o constantes. Todo deber ser encapsulado
dentro de la clase, como un miembro de la instancia (accesible via una instancia de
clase) o un miembro esttico (via el tipo).
Los mtodos que se definen en las clases son por default no virtuales (no pueden ser
sobre escritos al derivar clases)
Soporta los modificadores de acceso private, protected, public y agrega un
cuarto modificador internal.
Solamente se permite una base clase, si se requiere herencia mltiple es posible
implementar intefaces.
No es posible utilizar variables no inicializadas.
No es posible hacer el cast de un entero a un tipo de referencia (objeto).
Los parmetros que son pasados son type-safe.
El soporte de versiones lo provee el CLR.
Permite acceder a diferentes APIs a travs de .NET Common Language
Specification, el cual define el estdar de interoperabilidad entre lenguajes que se
adhieran a este estndar.
La Plataforma .NET provee un acceso transparente a COM.
Soporta OLE
Permite la interoperabilidad con APIs al estilo C y DLLs, esta caracterstica para
acceder a APIs nativas es llamada Platform Invocation Services (PInvoke)
Por default el cdigo es safe mode, pero es posible declarar clases o slo mtodos
unsafe, esta declaracin permite utilizar apuntadores, estructuras y almacenamiento
de arreglos estticos.
C# depende del runtime que provee la Plataforma .NET, el runtime administra la
ejecucin de cdigo.
Lenguaje Orientado a Objetos
Segn Bjarne Stroustrup autor del lenguaje de programacin C++, para que un lenguaje sea
llamado Orientado a Objetos debe soportar tres conceptos: objetos, clases y herencia.
Aunque los lenguajes orientados a objetos se construyen sobre los conceptos de :
1. Encapsulacin
2. Herencia
3. Polimorfismo
Objeto
Un Objeto es una instancia de un tipo de clase.
La instanciacin es el acto de crear una instancia de un objeto, la instancia es un objeto, la
instanciacin usa el operador new, despus la instanciacin es posible comunicarnos con el
objeto a travs de sus miembros.
Un Objeto es una coleccin de informacin relacionada y funcional.
Un objeto se compone de:
Datos que describen el objeto y
Operaciones que pueden ser realizadas por el objeto
Herencia
La Herencia es la habilidad para heredar datos y funcionalidad de un objeto padre, la
herencia es una caracterstica fundamental de un sistema orientado a objetos.
A travs de la herencia es posible crear o derivar una nueva clase basada en una clase
existente.
Una clase derivada es la nueva clase que esta siendo creada y la clase base es una de las
cuales la nueva clase es derivada. La nueva clase derivada hereda todos los miembros de la
clase base por consiguiente permite reusar el trabajo previo.
En C# se puede asumir que la clase derivada podra heredar todos los miembros de la clase
base.
La herencia es un ejemplo del diseo orientado a objetos conocido como una relacin "is-a"
(es-un), por ejemplo:
"un empleado es una persona".
Al utilizar la herencia la clase base necesita ser diseada teniendo en mente la herencia, si
los objetos no tienen la estructura apropiada la herencia no podra funcionar correctamente.
Una clase derivada no debera requerir ms ni prometer menos que su clase base sobre
cualquiera de sus interfaces heredadas.
Una interfaz de clase es un contrato entre esta y los programadores que usan la clase.
upcasting, cuando un programador tiene una referencia a la clase derivada, el programador
siempre puede tratar a esa clase como si fuera la clase base.
En el lenguaje comn en tiempo de ejecucin .NET todos los objetos heredan de la ltima
clase base llamada object y existe slo una herencia simple de objetos.
Un objeto puede derivar slo de una clase base.
Clase
Una Clase es una plantilla para un objeto.
Una Clase define las operaciones que un objeto puede realizar y define un valor que
mantiene el estado del objeto, los componentes principales de una clase son: mtodos,
eventos y propiedades.
Una instancia de una clase es un objeto, se accede a la funcionalidad de un objeto
invocando sus mtodos y accediendo a sus propiedades, eventos y campos.
Una clase utiliza modificadores para especificar la accesibilidad de la clase y sus
componentes, los componentes de una clase son llamados miembros por lo que existen
diferentes tipos de miembros. Una referencia se refiere a una instancia, una instancia es la
creacin de un objeto del tipo clase que se est declarando. Una clase utiliza ninguno, uno
o ms constructores para ayudar a definir la instancia de una clase. Existe una palabra
reservada llamada this que sirve para hacer referencia a la clase actual en el mbito en el
cual es utilizada. Cuando se hace referencia a una variable de instancia que tiene el mismo
nombre de un parmetro se debe utilizar this.name.
Al crear y manipular objetos no es necesario administrar la memoria que estos ocupan ya
que existe un mecanismo que se encarga de esto llamado garbage collector (recolector de
basura), pero es una buena prctica no olvidar liberar los recursos.
Funciones Miembro
Una Funcin Miembro puede ser un constructor, es decir, una pieza de cdigo que es
invocada en una instancia del objeto.
Campos Estticos
Un Miembro Esttico definine miembros de un objeto que no son asociados con una
instancia de clase especfica.
Un Campo Esttico es el tipo ms simple de un miembro esttico, para declarar un campo
esttico se utiliza el modificador static.
Un campo esttico puede accederse a travs del nombre de la clase, en vez de la instancia
de la clase (objeto):
using System;
class MiContador{
//Campo Esttico
public static int iContador = 0;
public MiContador(){
iContador++;
}
}
class App{
public static void Main(){
MiContador ContadorA = new MiContador();
Console.WriteLine(MiContador.iContador);
MiContador ContadorB = new MiContador();
Console.WriteLine(MiContador.iContador);
}
}
El ejemplo determina cuantas instancias del objeto han sido creadas.
Clase Base
Una Clase base es un objeto padre de donde se basa un nuevo trabajo.
Clase Derivada
Una Clase derivada es un objeto hijo.
Clase Abstracta
Una Clase Abstracta define las funciones que una clase derivada debe implementar.
Una Clase Abstracta define un contrato en donde las clases derivadas deben definir las
funciones que la clase padre marca utilizando la palabra reservada abstract, adems que
la clase padre tambin se define como abstract.
using System;
abstract public class Persona{//Indica que la clase es abstracta
//Propiedades
public string sNombre;
public int iEdad;
//Constructor
public Persona(string sNombre, int iEdad){
this.sNombre = sNombre;
this.iEdad = iEdad;
}
//Mtodos
abstract public string Tipo();//Mtodo que la clase
derivada debe implementar
}
//Herencia Simple
public class Empleado : Persona{
public Empleado(string sNombre, int iEdad):base(sNombre,
iEdad){}
override public string Tipo(){
return "Empleado";
}
}

class App{
//Aplicacin
public static void Main(){
Console.WriteLine("--- Arreglo de Objetos ---");

Empleado[] aProgramadores = new Empleado[2];
aProgramadores[0] = new Empleado("Bill Gates", 50);
aProgramadores[1] = new Empleado("Eric S. Raymond", 60);
for(int i = 0; i < aProgramadores.Length; i++){
Console.WriteLine("aProgramadores["+i+"].sNombre : " +
aProgramadores[i].sNombre);
Console.WriteLine("aProgramadores[" + i + "].iEdad : "
+ aProgramadores[i].iEdad);
Console.WriteLine("aProgramadores[" + i + "].Tipo : " +
aProgramadores[i].Tipo());
}
}
}

Clase Sealed
Una Clase sealed se utiliza para prevenir que una clase sea utilizada como una clase base,
su principal uso es para prevenir la derivacin no planeada.
sealed class ClaseBase{
ClaseBase(){}
}
class ClaseDerivada : ClaseBase{
}
class Sellada{
public static void Main(){
ClaseDerivada CD = new ClaseDerivada();
}
}
Al compilar el cdigo se muestra el siguiente mensaje:


sealed.cs(4,7): error CS0509: 'ClaseDerivada' : cannot inherit
from sealed class 'ClaseBase'
sealed.cs(1,14): (Location of symbol related to previous error)
El error es porque ClaseDerivada no puede utilizar ClaseBase como una clase base
porque ClaseBase es sealed, es decir, no permite derivaciones.
Overloading/Sobrecarga
La Sobrecarga (Overloading) hace posible utilizar dos o ms clases con el mismo nombre,
pero con parmetros diferentes. La sobrecarga es comn especialmente para los
constructores para definir diferentes maneras de crear una instancia nueva.
Cuando una funcin sobrecargada es invocada el compilador selecciona la funcin
apropiada que coincide con los parmetros.
Herencia Simple
La Herencia Simple permite derivar una clase en una clase nueva, que contiene la
definicin de la clase de la cual deriva, es decir, hereda todos los miembros datos de la
clase, aunque pueden existir miembros a los cuales no se pueda tener acceso por ser
private.
Los constructores no pueden ser heredados, por lo que es necesario escribir constructores y
si funcionalmente no existe alguna modificacin se invoca el constructor de la clase que
hereda utilizando la sintaxis base. Si se omite el constructor de la clase base y es invocado
el compilador podra invocar el constructor de la clase base sin parmetros.
using System;
public class Persona{
//Propiedades
public string sNombre;
public int iEdad;
private double dSueldo;
//Constructor
public Persona(string sNombre, int iEdad){
this.sNombre = sNombre;
this.iEdad = iEdad;
}
//Mtodos
public string Tipo(){
return "Persona";
}
public void AsignarSueldo(double dSueldo){
this.dSueldo = dSueldo;
}
public double ObtenerSueldo(){
return this.dSueldo;
}
}
//Herencia Simple
public class Empleado : Persona{
public Empleado(string sNombre, int iEdad):base(sNombre,
iEdad){}
public new string Tipo(){
return "Empleado";
}
double dSueldo;
public new void AsignarSueldo(double dSueldo){
this.dSueldo = dSueldo * dSueldo;
}
public new double ObtenerSueldo(){
return this.dSueldo;
}
}

class App{
//Aplicacin
public static void Main(){
Persona Mexicano = new Persona("Gerado ngeles
Nava", 33);
Console.WriteLine("Mexicano.sNombre : " +
Mexicano.sNombre);
Console.WriteLine("Mexicano.iEdad : " +
Mexicano.iEdad);
double dSueldo = 123.456;
Mexicano.AsignarSueldo(dSueldo);
Console.WriteLine("Mexicano.iSueldo : " +
Mexicano.ObtenerSueldo());
Console.WriteLine("Mexicano.Tipo : " +
Mexicano.Tipo());

Console.WriteLine("--- Herencia Simple ---");

Empleado Programador = new Empleado("Carlos
Salinas G.", 53);
Console.WriteLine("Programador.sNombre : " +
Programador.sNombre);
Console.WriteLine("Programador.iEdad : " +
Programador.iEdad);
Programador.AsignarSueldo(dSueldo);
Console.WriteLine("Programador.iSueldo : " +
Programador.ObtenerSueldo());
Console.WriteLine("Programador.Tipo : " +
Programador.Tipo());
}
}
Polimorfismo y Funciones Virtuales
El polimorfismo es la funcionalidad que permite a cdigo antiguo invocar cdigo nuevo,
tambin permite extender el sistema sin modificar el cdigo existente, esto se logra
sobreescribiendo o redefiniendo el cdigo, para lo cual se utilizan funciones virtuales y la
palabra clave override.
Las funciones abstractas son automaticamente funciones virtuales, las cuales permiten al
programador usar polimorfismo para hacer su cdigo simple.
Virtual significa que cuando una invocacin a funciones miembro, el compilador debera
buscar por el tipo real del objeto y no por el tipo de la referencia, e invocar en base al tipo
la funcin apropiada.
using System;
public class Persona{
//Propiedades
public string sNombre;
public int iEdad;
//Constructor
public Persona(string sNombre, int iEdad){
this.sNombre = sNombre;
this.iEdad = iEdad;
}
//Mtodos
virtual public string Tipo(){
return "Persona";
}
}
//Herencia Simple
public class Empleado : Persona{
public Empleado(string sNombre, int iEdad):base(sNombre,
iEdad){}
override public string Tipo(){
return "Empleado";
}
}

class App{
//Aplicacin
public static void Main(){
Persona Mexicano = new Persona("Gerado ngeles Nava", 33);
Console.WriteLine("Mexicano.sNombre : " +
Mexicano.sNombre);
Console.WriteLine("Mexicano.iEdad : " + Mexicano.iEdad);
Console.WriteLine("Mexicano.Tipo : " + Mexicano.Tipo());

Console.WriteLine("--- Arreglo de Objetos ---");

Empleado[] aProgramadores = new Empleado[2];
aProgramadores[0] = new Empleado("Bill Gates", 50);
aProgramadores[1] = new Empleado("Eric S. Raymond", 60);
for(int i = 0; i < aProgramadores.Length; i++){
Console.WriteLine("aProgramadores["+i+"].sNombre : " +
aProgramadores[i].sNombre);
Console.WriteLine("aProgramadores[" + i + "].iEdad : "
+ aProgramadores[i].iEdad);
Console.WriteLine("aProgramadores[" + i + "].Tipo : " +
aProgramadores[i].Tipo());
}
}
}
Cuando una funcin es declarada con la palabra reservada override significa que es la
misma funcin que fue declarada en la clase base, si la palabra reservada override se
omite el compilador podra asumir que la funcin no est relacionada a la funcin de la
clase base y no despacha la funcin virtual (el compilador podra sugerir omitir override o
agregar new) .
Cuando existe una funcin virtual el programador puede pasar una referencia a la clase
abstracta aunque la clase derivada y el compilador podran escribir cdigo para invocar la
versin apropiada de la funcin en tiempo de ejecucin.
Por ejemplo, el objeto base object tiene una funcin virtual llamada ToString() que
convierte un objeto a string. Si se invoca la funcin ToString() en un objeto que que no la
tiene como versin propia, la versin de la funcin que es parte de la clase object podra
ser invocada.
Encapsulacin y Visibilidad
Encapsulacin (tambin llamada information hiding), habilidad de un objeto para ocultar
sus datos internos o parte interna de sus usuarios y provee una interface que hace las partes
importantes del objeto accesible programaticamente.
La encapsulacin provee los lmites entre una interfaz externa y los detalles de su
implementacin interna.
Al disear objetos el programador decide que objetos son visibles al usuario y que es
privado dentro del objeto, los detalles que no son visibles al usuario son sealados para ser
encapsulados en la clase.
Razones para encapsular y ocultar:
El usuario no puede cambiar lo que es privado en el objeto, lo cual reduce la
oportunidad de que el usuario cambie o dependa de los detalles en el cdigo, si el
usuario hace lode detalles dependientes, los cambios realizados en el objeto quiz
arruinen el cdigo del usuario.
Los cambios realizados en partes pblicas de un objeto deben permanecer
compatibles con la versin previa. Las partes pblicas pueden ser cambiadas sin
arruinar el cdigo del usuario.
Los campos privados pueden slo ser accesados desde la clase, los campos pblicos
pueden ser accesados a travs de cualquier instancia de la clase.
Abstraccin
Una Abstraccin se refiere a como un problema dado es representado en el espacio de
programa.
Como desarrollador de clases es necesario pensar en terminos de hacer el mejor diseo de
abstraccin para los clientes de clase y permitirles enfocarse a la tarea que deben realizar y
no escudriar o indagar en los detalles de como funciona la clase, tambin es necesario
determinar cuales de los miembros de la clase deberan ser accesibles publicamente.
Los beneficios de una buena abstraccin, es disearla de manera tal que las modificaciones
son minimas, si se conoce bien el problema a resolver facilita determinar que mtodos
necesitara el usuario, tambin ser un sistema fcil de entender y mantener.
La interfaz de clase es la implementacin de la abstraccin.
Plataforma .NET
La solucin Microsoft .NET comprende cuatro componentes fundamentales:
1. Servicios de Bloques de Construccin .NET o acceso programtico para ciertos
servicios tales como almacenamiento de archivos, calendario y pasaporte .NET el
cual es un servicio de verificacin de identidad.
2. Dispositivos de Software .NET el cual podra correr sobre nuevos dispositivos
Internet.
3. La Experiencia de Usuario .NET la cual incluye caractersticas tales como interfaz
natural, agentes de informacin y etiquetas inteligentes es decir una tecnologa que
automatiza hiperligas para informacin relacionada a palabras y frases en
documentos creados por el usuario.
4. La Infraestructura .NET la cual comprende la plataforma .NET, Microsoft Studio
.NET, los Servidores Corporativos .NET y Microsoft Windows .NET
La Infraestructura .NET se refiere a todas las tecnologas que constituyen el nuevo
ambiente para crear y ejecutar aplicaciones robustas, escalables y distribuidas. La parte de
.NET que permite desarrollar estas aplicaciones es la plataforma .NET.
La Plataforma .NET consiste de un Lenguaje Comn en Tiempo de Ejecucin (CLR) y la
Biblioteca de Clases de la Plataforma .NET algunas veces llamada la Biblioteca de Clases
Base (CBL).
El CLR es como una mquina virtual (el cdigo que corre dentro del CLR en ejecucin en
un ambiente encapsulado y controlado, separados de otros procesos en la mquina) en la
cual funcionan las aplicaciones .NET, todos los lenguajes .NET tienen la biblioteca de
clases de la Plataforma .NET a su disposicin.
La biblioteca de clases de la Plataforma .NET incluyen soporte para cualquiera de los
archivos de entrada/salida y base de datos de entrada/salida para XML y SOAP.
La Plataforma .NET es una plataforma nueva que simplifica la aplicacin del desarrollo en
ambientes altamente distribuidos de Internet. La Plataforma .NET est diseada para
cumplir los siguientes objetivos:
Proveer un ambiente consistente de programacin orientada a objetos, tanto o si el
cdigo objeto es almacenado y ejecutado localmente, o si es ejecutado localmente
pero distribuido en Internet o si es ejecutado remotamente.
Proveer un ambiente de ejecucin de cdigo que minimice la distribucin de
software y conflictos de versiones.
Proveer un ambiente de ejecucin de cdigo que garantice la ejecucin de cdigo
seguro, incluyendo el cdigo creado por un desconocido o un tercero semiconfiable.
Proveer un ambiente de ejecucin de cdigo que elimine los problemas de
desempeo de ambientes de scripts o interpretes.
Hacer que la experiencia del desarrollador sea consistente a travs de una amplia
variedad de aplicaciones, tal como aplicaciones basadas en Windows y aplicaciones
basadas en Web.
Construir toda la comunicacin sobre estndares industriales para asegurar que el
cdigo basado en la Plataforma .NET pueda integrarse con cualquier otro cdigo.
La Plataforma .NET consiste de dos componentes principales:
1. El Lenguaje Comn en Tiempo de Ejecucin (CLR) el cual es el fundamento de
la Plataforma .NET
2. La Biblioteca de Clases de la Plataforma .NET, es una coleccin orientada a
objetos de tipos reusables que pueden utilizarse para desarrollar aplicaciones en el
rango de aplicaciones tradicionales desde la lnea de comandos o interfaces de
usuario grficas (GUI) hasta aplicaciones basadas en las ltimas inovaciones que
provee ASP.NET tales como Web Forms y servicios web XML.
El runtime es una agente que administra el cdigo en tiempo de ejecucin al proveer de
serviciones principales como la administracin de memoria, administracin de hilos,
tambin implementa tipos estrictos de seguridad y otras formas de verificacin de cdigo
que aseguren la seguridad y robustez.
El concepto de administracin de cdigo es principio fundamental del runtime. El cdigo
que manipular el runtime es conocido como cdigo administrado, mientras que el cdigo
que no ser manipulado por el runtime es conocido como un cdigo no administrado.
La plataforma .NET puede almacenar componentes no administrados que son cargados por
el CLR en sus procesos e inicializados por la ejecucin de cdigo administrado de esta
manera se crea un ambiente de software que puede explotar tanto caractersitcas de cdigo
administrado como las del cdigo no administrado.
.NET Common Language Runtime - CLR
El .NET Common Language Runtime (Lenguage comn en tiempo de ejecucin .NET) es
un ambiente basado en componentes y C# esta diseado para facilitar la creacin de
componentes. Todos los objetos son escritos como componentes y los componentes son el
centro de accin, por ello que reciba el nombre de lenguaje cntrico de componentes
(component-centric).
Los componentes creados en C# son totalmente auto-describibles y pueden ser utilizados
sin un proceso de registro.
C# ayuda en la creacin de componentes mediante el runtime y framework .NET, los cuales
proveen un sistema de tipo unificado en el cual todo puede ser tratado como un objeto.
Caractersticas del CLR
EL CLR no slo soporta el compilador de C#, tambin el de Visual Basic y C++, el cdigo
que generan estos compiladores para ser soportado por CLR es llamado managed code.
Algunos de los beneficios que las aplicaciones obtienen del CLR son:
Integracin de lenguajes a travs del Common Language Specification
Administracin automatica de memoria, a travs del recolector de basura.
Manejo de excepciones de lenguajes.
Seguridad type safety.
Soporte de versiones.
Modelo Simplificado para la interaccin de componentes.
El CLR provee los beneficios anteriores, el compilador debe emitir los metadatos en el
managed code. Los metadatos describen los tipos en el cdigo y son empaquetados en el
cdigo ejecutable.
El CLR administra la memoria, ejecucin de hilos, ejecucin de cdigo, verificacin de
cdigo seguro, compilacin y otros servicios. Estas caractersticas son intrnsecas a la
administracin de cdigo que corre sobre el CLR.
La seguridad y administracin de componentes depende de un nmero de factores que se
incluyen en su origen como Internet red corporativa, computadora local, es decir, quiz o
quiz no estn disponibles para desempear operaciones de acceso a archivos, acceso a
registros o funciones sensitivas, an si comienzan a utilizarse en el misma aplicacin
activa.
El runtime forza el acceso a cdigo seguro, no es posible acceder a datos personales,
sistema de archivos o red.
El runtime tambin forza la robustez del cdigo implementando una infraestrucutra estricta
de verificacin de cdigo llamado Common Type System (CTS), el cual asegura que toda
la administracin de cdigo se describe as misma. La variedad de compiladores Microsoft
y de terceros genera cdigo administrado que conforma el CTS, es decir, que la
administracin de cdigo puede consumir otros tipos e instancias administradas, mientras
que se forza estrictamente la fidelidad de tipo y seguridad de tipo.
La administracin del ambiente del runtime elimina cuestiones de software comunes,
liberando por ejemplo recursos que ya no son utilizados.
El runtime tambin acelera la productividad del desarrollador, no importa el lenguaje que
un programador utilice, puede utilizar las ventajas del runtime, biblioteca de clases, y
componentes escritos por otros programadores, cualquier compilador que utilice el runtime
puede hacer lo mismo,
La interoperabilidad entre cdigo administrado y no administrado permiten a los
desarrolladores continuar utilizando componentes COM y DLLs.
El runtime est diseado para incrementar el desempeo, atravs del CLR que provee
muchos servicios estndar, el cdigo administrado nunca es interpretado, una caracterstica
llamada just-in-time (JIT) permite compilar todo el cdigo administrado para correr en el
lenguaje nativo de la mquina del sistema o de cualquiera que se este ejecutando. El
administrador de memoria elimina las posibilidades de fragmentacin de memoria e
incrementa la referencia de localidad de memoria para impulsar el incremento del
desempeo.
El runtime soporta aplicaciones del lado del servidor como Microsoft SQL Server e
Internet Information Services (IIS), esta infraestructura permite utilizar codigo
administrado para escribir la lgica del negocio.
.NET Runtime Environment
El Lenguaje Comn en Tiempo de Ejecucin provee los servicios de ejecucin bsica. Las
clases base proveen tipos de datos bsicos, clases coleccin y otras clases generales. Las
clases base son clases para tratar datos y XML. En la parte superior de la arquitectura las
clases exponen servicios web y tratramiento de la intefaz de usuario. Una aplicacin puede
hacer invocaciones en cualquier nivel y utilizar clases desde cualquier nivel.
Organizacin .NET Framework:
Servicios Web Interfaz de Usuario
Datos y XML
Clases Base

Lenguaje Comn en Tiempo de Ejecucin
Ambiente/Entorno de Ejecucin
El ambiente o entorno provee un modelo de programacin simple, seguro, soporta de
herramientas potentes y ayuda con la distribucin, empaquetado y soporte:
Modelo de Programacin Simple, todos los servicios son ofrecidos a travs de un
modelo comn que puede ser accedido desde cualquier lenguaje .NET y los
servicios pueden ser escritos en cualquier lenguaje .NET, el entorno o ambiente en
gran parte es un lenguaje agnstico permitiendo la eleccin de lenguaje, esto hace el
cdigo fcil de reusar para el programador y los proveedores de bibliotecas.
En el runtime .NET todos los errores son reportados via excepciones.
El entorno contiene las Bibliotecas de Clase Base (Base Class Libraries - BCL) las
cuales proveen las funciones tradicionales fundadas en bibliotecas en tiempo de
ejecucin, la funcionalidad del BCL incluye:
o Clases coleccin, tales como consultas, arreglos, pilas y tablas hash.
o Clases de acceso a bases de datos
o Clases IO (input-output)
o Clases WinForms, para crear interfaces de usuario
o Clases Network
Fuera de la clase base en tiempo de ejecucin, existen muchos otros componentes
que controlan la interfaz de usuario (UI) y realizan otras operaciones sofisticadas.
Seguridad, el entorno del runtime .NET est diseado para ser un entorno seguro.
El runtime .NET es un entorno administrado o controlado, lo cual significa que el
runtime administra la memoria por el programador a travs del recolector de basura.
El runtime .NET es un entorno verificado, en tiempo de ejecucin el entorno
verifica que la ejecucin del cdigo sea de tipo segura (type-safe).
El sistema de seguridad interactua con el verificador para asegurar que el cdigo
realice slo lo que tiene permitido hacer, esto es posible especificando un
requerimiento de seguridad para una pieza de cdigo especfica.
Soporte de herramientas potentes, Microsoft suministra cuatro lenguajes .NET:
VB, VC++, C# y JScript. La depuracin en gran medida es enriquecida por el
runtime .NET, el modelo de ejecucin comn hace la depuracin de lenguajes
simple y directa.
Distribucin, empaquetado y soporte, El runtime .NET ayuda simplificando la
distribucin y en algunos casos no existe el paso tradicional de instalacin, porque
los paquetes son distribuidos en un formato genrico, un paquete puede correr en
cualquier entorno que soporte .NET, el entorno separa los componentes de una
aplicacin por lo que una aplicacin slo corre con los componentes que son
enviados.
Ensamblaje
En el runtime .NET el mecanismo de empaquetado es el ensamble (assembly), cuando el
cdigo es compilado por uno de los compiladores .NET, es convertido a una forma
intermedia conocida como IL.
El ensamble contiene todos los IL, metadatos y otros archivos requeridos para que un
paquete se ejecute en un paquete completo.
Cada ensamble contiene un manifiesto que enumera todos los archivos que estn
contenidos en el ensamble, controla que tipos y recursos son expuestos fuera del ensamble
y relaciona las referencias de esos tipos y recursos a los archivos que contienen los tipos y
recursos.
El manifiesto tambin lista otros ensambles que dependen de un ensamble.
Los ensambles se contienen a s mismo, existe suficiente informacin en el ensamble para
ser auto-descrito.
Cuando se define un ensamble, el ensamble puede ser contenido en un solo archivo o puede
ser dividido entre varios archivos. Utilizando varios archivos podra hacer posible un
escenario donde las secciones del ensamble sean descargadas slo como se necesiten.
Interoperabilidad de Lenguaje
Una de las metas del runtime .NET es ser un lenguaje agnstico, permitiendo que el cdigo
sea utilizado y escrito desde cualquier lenguaje, no slo las clases pueden ser escritas en
algn lenguaje .NET como VB.NET y ser invocadas desde otro lenguaje .NET como C#,
una clase que fu escrita en VB.NET puede ser utilizada como una clase base escrita en C#
y esa clase podra ser utilizada desde una clase VC++ o JScript, es decir, no importaria en
que clase sea escrita una clase.
Para hacer lo anterior posible existen algunos obstaculos como las propias caractersticas
del lenguaje, ya que un lenguaje no podra soportar ciertas cosas que otro si las soporte, por
ejemplo la sobrecarga de operadores.
Para que una clase sea utilizada desde un lenguaje .NET, la clase debe adherir la
Especificacin Comn de Lenguaje (Common Language Specification - CLS) la cual
describe que caractersticas pueden ser visibles en la interfaz pblica de la clase, por
ejemplo el CLS prohibe exponer tipos de datos sin signo, porque no todos los lenguajes
pueden utilizarlos.
Atributos
El runtime .NET soporta atributos personalizables, los cuales son en cierto sentido un lugar
para colocar informacin descriptiva en los metadatos junto con un objeto y entonces
recuper despus los datos. Los atributos proveen un mecanismo general para hacer esto y
son utilizados en exceso en todo el tiempo de ejecucin para almacenar informacin que
modifica como el runtime utiliza las clases.
Los atributos son extensibles y permite a los programadores definir atributos y utilizarlos.
Los atributos se especifican encerrandolos entre corchetes:
[Version("14/09/2005", Comentario="1.0.1.0")]
Los atributos son anotaciones que se colocan en elementos de cdigo fuente, como clases,
miembros, parmetros, etc.
Los atributos puede ser utilizados para: cambiar el comportamiento del runtime, proveer
informacin acerca de un objeto, llevar informacin organizacional al diseador.
El atributo informacin es almacenado con los metadatos del elemento y pueden ser
facilmente recuperados en tiempo de ejecucin a travs de un proceso conocido como
reflection.
C# utiliza un Atributo Condicional para controlar cuando las funciones miembro son
invocadas.
Por convencin los atributos se agregan al final del nombre de una clase, con la finalidad de
conocer cuales son clases atributo y cuales son clases normales. Todos los atributos derivan
de System.Attribute.
Procure que el atributo para el elemento sea especfico, utilizando los identificadores
siguientes:
Identificador Descripcin
assembly ensamble
module
mdulo
type clase o estructura
method
mtodo
property porpiedad
event
evento
field campo
param
parmetro
return valor de regreso
Los atributos que son aplicados a ensambles o mdulos deben colocarse despus de
cualquier clusula using y antes de cualquier cdigo.
Biblioteca de Clases de la Plataforma .NET
La Biblioteca de Clases de la Plataforma .NET es una coleccin de tipos reutilizables
integradas en el CLR.
Los tipos de la Plataforma .NET permiten llevar a cabo tareas de programacin comunes
como manipulacin de strings, colecciones de datos, conectividad a bases de datos y acceso
a archivos.
Es posible utilizar la Plataforma .NET para desarrollar los siguientes tipos de aplicaciones y
servicios:
Aplicaciones de consola
Windows Forms
Aplicaciones ASP.NET
Servicios Web XML
Servicios Windows
Requerimientos de Software
Todo lo que se necesita para desarrollar en C# es el Kit de desarrollo (SDK), del cual solo
se utilizar el CLR y el compilador de C#.
Lenguaje Intermedio y Metadatos
Microsoft desarrollo un lenguaje parecido al lenguaje ensamblador llamado Microsoft
Intermediate Language (MSIL).
Para compilar aplicaciones .NET, los compiladores toman el cdigo fuente como entrada y
producen MSIL como salida.
MSIL en s es un lenguaje completo con el cual es posible escribir aplicaciones.
El managed code generado por el compilador C# no es cdigo nativo porque es un cdigo
de Lenguaje Intermedio (IL). Este cdigo IL se convierte en la entrada para la
administracin del proceso de ejecucin del CLR. La ventaja final del cdigo IL es que el
CPU es independiente, lo cual significa que se necesita un compilador en la mquina
destino para cambiar el cdigo IL en el cdigo nativo.
El IL es generado por el compilador, pero no es lo nico que se provee para el runtime, el
compilador tambin genera metadatos acerca del cdigo, los cuales dicen ms al runtime
del cdigo, por ejemplo la definicin de cada tipo. Los metadatos son bibliotecas de tipo,
entrada de datos al registry, etc. Los metadatos son empaquetados directamente con el
cdigo ejecutable y no en localidades separadas.
El IL y los metadatos son colocados en los archivos que extienden el formato PE (Portable
Executable) utilizado para archivos .exe y .dll, cuando se carga el archivo PE el runtime
coloca y extrae los metadatos y el IL de estos.
Cuando se compila una aplicacin C# o cualquier aplicacin escrita en un CLS, la
aplicacin es compilada dentro del MSIL, adems se compila dentro de las instrucciones
nativas de CPU cuando la aplicacin es ejecutada por vez primera por el CLR.
El proceso es el siguiente:
1. Cdigo fuente escrito en C#
2. El cdigo fuente es compilado usando el compilador de C# (csc.exe) dentro de un
EXE.
3. El compilador C# produce como salida el cdigo MSIL y un manifiesto en una parte
de slo lectura del EXE que tiene un encabezado estndar PE (Win32-Portable
Executable).
Cuando el compilador produce o crea la salida tambin importa una funcin llamada
_CorExeMain del runtime .NET.
4. Cuando la aplicacin es ejecutada, el sistema operativo carga el PE como una DLL
dependiente tal como la nica que exporta la funcin _CorExeMain (mscoree.dll)
justo como lo hace con cualquier PE vlido.
5. El sistema operativo carga y entonces salta al punto dentro del PE el cual es puesto
ah por el compilador C#.
El sistema operativo obviamente no puede ejecutar el cdigo MSIL, el punto de
entrada es un pequea parte que salta a la funcin _CorExeMain en mscoree.dll.
6. La funcin _CorExeMain comienza la ejecucin del cdigo MSIL que fue colocado
en el PE.
7. Dado que el cdigo MSIL no puede ser ejecutado directamente (porque no est un
un formato de mquina ejecutable) el CLR compila el MSIL usando un compilador
just-in-time (JIT o JITter) dentro de instrucciones CPU nativas tal como procesa el
MSIL.
JITers
El managed code generado por C# es el cdigo IL, aunque el cdigo IL es empaquetado en
un formato de archivo PE vlido, no es posible ejecutarlo sin convertirlo a un managed
code nativo.
Cuando un tipo es cargado, el laoder crea y agrega un stub (pieza pequea) a cada mtodo
del tipo, as cuando el mtodo es invocado por vez primera, el stub pasa el control al JIT.
El JIT compila el IL a cdigo nativo y cambia el stub para que apunte al cdigo nativo que
est en cache, as las subsecuentes invocaciones podran ejecutar el cdigo nativo.
El CLR incluye tres diferentes JITers que pueden ser usados para convertir MSIL en cdigo
nativo, dependiendo de las circunstancias:
1. PreJIT (Generacin de cdigo Install-time), opera como un compilador tradicional,
aunque est basado sobre el compilador JIT principal, se ejecuta cuando un
componente NGWS es intalado y compila el cdigo IL a managed code nativo.
La generacin de cdigo en tiempo de instalacin compilar un ensamble completo
dentro de un cdigo binario de CPU-especifico, tal como lo hace el compilador
C++. Un ensamble el cdigo empaquetado que es enviado al compilador. La
compilacin se hace en tiempo de instalacin, cuando el usuario final es menos
probable para notificar que el ensamble esta siendo compilado-JIT.
La ventaja de la generacin de cdigo en tiempo de instalacin, es que permite
compilar el ensamble completo justo una vez antes de ser ejecutado. Al ser
compilado el ensamble entero no hay preocupacin referente al desempeo
intermitente cada vez que un mtodo en el cdigo es ejecutado por primera vez.
Al usar esta utilidad depende del tamao del sistema y del ambiente de distribucin.
2. JIT, compilador por default utilizado por el CLR, es un compilador optimizado, el
cual realiza el anlisis del flujo de datos, administra el cdigo nativo como salida.
El JITter es invocado en tiempo de ejecucin.
3. EconoJIT, realiza una conversin muy veloz del IL a managed code nativo
Tambin es un JITter en tiempo de ejecucin, esta especialmente diseado para
sistemas que tienen recursos limitados como memoria. La principal diferencia con
un JIIter regular es la incorporacin de algunas invocaciones code pitching, que
permiten al EconoJIT descartar el cdigo generado o compilado si el sistema
comienza a ejecutarse fuera de memoria, siendo el beneficio el reclamo de memoria.
La desventaja es que si el cdigo es pitched (lanzado) es invocado otra vez por lo
que debe ser compilado de nuevo.
Es posible determinar que tipo de JIT esta siendo utilizado y cuanta memoria utiliza a
travs de una pequea utilidad llamada JIT Compiler Manager (jitman.exe), que reside en
el directorio bin del directorio de instalacin del NGWS SDK.
Sistema de Tipo Unificado
El runtime de .NET hace ms que dar al desarrollador un simple sistema de tipo unificado
que es usado a travs de todos los lenguajes, tambin deja a los lenguajes escribir
extensiones de sistema tipo, agregando nuevos tipos que parezcan y actuen como tipos de
sistemas built.in.
El Sistema Virtual de Objetos - VOS
Las reglas que se siguen cuando se declaran, utilizan y administran tipos son modeladas en
el Sistema Virtual de Objetos (Virtual Object System - VOS).
El VOS establece una plataforma que permite la integracin de lenguajes y type safety.
La base de la arquitectura del runtime es la plataforma que puede describir en cuatro reas:
1. VOS Type System, provee un sistema de tipos que intenta soportar la
implementacin completa de una rango amplio de lenguajes de programacin.
2. Metadata, describe y hace referencia a los tipos definidos por el VOS.
3. Common Language Specification - CLS, define el subconjunto de tipos del VOS. Si
una biblioteca de clases es soportada por las reglas del CLS, garantiza que la
biblioteca de clases pueda ser utilizada por los dems lenguajes que implementen el
CLS.
4. Virtual Execution System - VES, es responsable de la carga y ejecucin de los
programas que fueron escritos por el CLR.
VOS Type System
El VOS define tipos que describen valores y especifican un contrato en donde todos los
valores de tipo deben soportar. Existen dos entidades: valores y objetos.
Para un valor el tipo describe la representacin de almacenamiento y las operaciones que
puede realizar.
Los objetos son ms poderosos porque el tipo es almacenado explicitamente en su
representacin, cada objeto tiene una identidad que lo distingue de los dems objetos.
Metadata
El compilador CLS toma el cdigo fuente como entrada y produce cdigo MSIL para el
runtime para compilar a travs de los JITters y ejecutar. Adems se mapea el cdigo fuente
a secuencias de instrucciones MSIL, el compilador CLS tiene otra tarea importante:
envolver metadatos dentro del EXE resultante.
Los Metadatos son datos que describen datos.
Los metadatos son la coleccin de elementos programticos que constituyen el EXE, como
los tipos declarados y los mtodos implementados.
Estos metadatos son similares a los tipos de bibliotecas generadas con componentes COM
(Component Object Model).
La razn para usar metadatos es simple ya que permiten al runtime .NET conocer en tiempo
de ejecucin que tipos podran ser almacenados y que mtodos podran ser invocados. Esto
permite al runtime configurar apropiadamente el ambiente para mayor eficiencia al ejecutar
la aplicacin. El significado por el cual estos metadatos son consultados es llamado
reflection.
Los metadatos por cada objeto .NET registran toda la informacin que es requerida para
usar el objeto, con esta informacin el runtime .NET es capaz de resolver como crear
objetos, invocar funciones miembro o acceder a los datos de un objeto y el compilador
puede utilizar la informacin para encontrar que objetos estn disponibles y como es
utilizado un objeto. La informacin incluye lo siguiente:
El nombre del objeto
Los nombres de todos los campos del objeto y sus tipos
Los nombres de todas las funciones miembro, incluyendo tipos parmetro y
nombres
Los metadatos tambin permiten a otras herramientas acceder a la informacin detallada
acerca del cdigo
Existe un proceso llamado reflection donde el cdigo en tiempo de ejecucin puede
consultar los metadatos para encontrar que objetos estn disponibles y que funciones y
campos estn presentes en la clase. La reflection est disponible para usuarios finales para
determinar como son los objetos, bsqueda de atributos o ejecutar mtodos en los que los
nombres no son conocidos hasta el tiempo de ejecucin.
Los metadatos son utilizados para varias tareas:
Para representar la informacin que el CLR utiliza para localizar y cargar clases.
Para sacar las instancias de las clases en memoria.
Para resolver la invocacin de mtodos.
Para traducir IL a cdigo nativo.
Para forzar la seguridad.
El encargado de generar los metadatos es el compilador C#, al pasar el cdigo a IL,
emitiendo la informacin binaria de los metadatos en un archivo PE.
La principal ventaja de la combinacin de los metadatos con el cdigo ejecutable es que la
informacin acerca de los tipos es persistente.
Una herramienta que toma ventaja de reflection es el ILDASM (Microsoft .NET
Framework IL Disassembler), el cual analiza la aplicacin de metadatos fuente y entonces
presenta informacin acerca de la aplicacin en la jerarqua del rbol.
Seguridad
La faceta ms importante de cualquier ambiente de desarrollo de aplicaciones distribuidas
es como manejar la seguridad.
La seguridad comienza tan pronto como una clase es caragada por el CLR porque la clase
loader es parte del esquema de seguridad .NET, la seguridad relacionada a factores tales
como reglas de accesibilidad y requerimientos de consistencia son verificados.
Deployment
La llave para el Deployment de aplicaciones .NET es el concepto de (ensambles). Los
assemblies son paquetes simples de comportamiento semanticamente relacionados que son
construidos como un archivo individual o entidades de archivos mltiples.
La especificacin de como deploy una aplicacin podra variar ya que se puede tratar de un
desarrollo web o aplicacin tradicional de escritorio.
El runtime .NET mantiene el rastreo delos archivos y de las versiones de los archivos
asociados con una aplicacin. Cualquier aplicacin que es instalada es automticamente
asociada con los archivos que son parte de ese ensamble.
Si una aplicacin de instalacin intenta sobre escribir un archivo necesario para otra
aplicacin, el runtime .NET es lo bastante inteligente para permitir que la aplicacin de
instalacin, instale los archivos necesarios pero el CLR no elimina las versiones previas de
el archivo porque todava son requeridas por la primer aplicacin.
Interoperabilidad con cdigo no administrado
El cdigo no administrado no tiene las ventajas que tiene el cdigo administrado, como
recoleccin de basura, sistema de tipo unificado y metadatos.
Cdigo administrado invocando funciones DLL no administradas, cuando la
aplicacin necesita una interfaz para una DLL en C y la empresa que escribe la DLL
no adopta .NET ser necesario invocar esa DLL desde una aplicacin .NET.
Cdigo administrado usando componentes COM, es posible lograr esto creando
un wrapper .NET para el componente COM, as que el cliente administrado trabaja
con clases .NET
Cdigo no administrado usando servicios .NET, cuando se desea acceder a .NET
desde cdigo no administrado.
Common Language Specification - CLS
Es un conjunto de reglas que un lenguaje debe adherir para crear aplicaciones .NET que se
ejecutan en el CLR.
Un concepto importante relacionado a la CLR es el cdigo administrado, el cdigo
administrado es justo el cdigo que esta ejecutandose bajo el auspicio de la CLR y por
consiguiente comienza a ser controlado por el CLR.
El CLS define un subconjunto de tipos del VOS, si una biblioteca de clases sigue las reglas
del CLS esta garantizando ser utilizada por clientes de otro lenguaje de programacin que
tambin se adhieren a la CLS.
El CLS se refiere a la interoperabilidad entre lenguajes, por lo que es necesario seguir los
tipos y caractersticas del CLS, para ello es necesario conocer los tipos primitivos, arreglos,
tipos, miembros tipo, mtodos, campos, propiedades, enumeraciones, excepciones,
interfaces, eventos, atributos personalizables, delegados, identificadores, etc. que la propia
especicicacin define.
Virtual Execution System - VES
El Sistema Virtual de Ejecucin implementa la VOS y se crea implementando un motor de
ejecucin (Execution Engine EE). Los componentes de la VES son:
Lenguaje Intermedio (Intermediate Language - IL), diseado para ser facilmente
traducido a una amplia gama de lenguajes, por lo que el compilador C# es capaz de
generar el lenguaje intermedio.
Carga del Cdigo Administrado (Loading Managed Code), resuelve nombres,
obtiene clases de la memoria, crea stubs que son necesarios para la compilacin JIT.
La class loader forza la seguridad.
Conversin de IL a Cdigo Nativo via JIT, el cdigo del lenguaje intermedio no
esta diseado como un interprete tradicional bytecode o rbol de cdigo, la
conversin del lenguaje intermedio es realmente una compilacin.
Carga de Metadatos, se encarga de checar la seguridad de tipos y la integridad de
los mtodos.
Recolector de Basura y Manejo de Excepciones (Garbage Collection), el codigo
administrado premite rastrear el apilado en el runtime, para que el runtime entienda
el apilado individual de frames un cdigo administrado tiene que ser proporcionado
por el JITer o por el compilador.
Servicios de debugging, estos servicios dependeran de la informacin producida
por el compilador del lenguaje fuente y se emiten dos mapas, un mapa del lenguaje
fuente de la construccin de direcciones en el flujo de instrucciones y un mapa de
las direcciones de las localidades en el apilado de frames.
Administracin de Hilos, el VES proprorciona este servicio al cdigo
administrado.
Tipos de Datos
C# soporta el conjunto de tipos de datos usual, para cada tipo de dato que C# soporta, existe
una correspondencia tipo de lenguaje comn en tiempo de ejecucin .NET subyacente.
Todos los tipos runtime pueden encontrarse en el namespace System del lenguaje comn en
tiempo de ejecucin .NET.
Tipo Bytes Tipo runtime Descripcin
byte 1 Byte Unsigned byte
sbyte 1 SByte Signed byte
short 2 Int16 Signed short
ushort 2 UInt16 Unsigned short
int 4 Int32 Signed integer
uint 4 UInt32 Unsigned int
long 8 Int64 Signed big integer
ulong 8 UInt64 Unsigned big integer
float 4 Single Floating point number
double 8 double Double-precision floating point number
decimal 8 Decimal Fixed-precision number
string String Unicode string
char Char Unicode character
bool Boolean Boolean value
Los tipos de datos son separados en value types y reference types. Los value types son
asignados en estructuras de pilas o en lnea. Los reference types son asignados al
aglomerado.
Las referencias y tipos de valores son derivados de la ltima clase base objet, de esta
manera en caso de que un tipo de valor necesite actuar como un object una envoltura hace
que el tipo de valor parezca una referencia asignandolo al aglomerado, y los tipos de
valores son copiados a estos. La envoltura es marcada por lo que el sistema conoce que
contiene por ejemplo int, a este proceso se le conoce como boxing y el proceso de reversa
se le conoce como unboxing
La palabra reservada class es empleada para declarar un tipo referencia (heap allocated), y
la palabra reservada struct es empleada para declarar un tipo valor, una estructura es
utilizada para objetos ligeros que necesitan actuar como tipos built-in, las clases son
utilizadas en cualquier otro caso.
Por ejemplo un tipo int es un valor tipo y un tipo string es un tipo referencias, esto
trabajaria as:
int i = 2005;
string s = "Septiembre";
i 2005


s o-----

------------
>
Septiembre

Constantes y Campos Solo Lectura
En C# los valores pueden ser definidos como constantes y para que un valor sea constante
su valor debe ser algo que pueda ser escrito como una constante.
public const string sDominio = "informatique.com.mx";
La restriccin de tipos constantes es que son conocibles en tiempo de compilacin, en vez
de ello es posible utilizar el modificador readonly el cual est diseado para aquellas
situaciones en donde las constantes tienen restriccin.
Aplicando el modificador readonly un valor puede ser establecido en el constructor o en
una inicializacin pero no puede ser modificado despus.
Ejemplo Hello World!
El cdigo C# puede ser escrito en cualquier editor, tambin puede escribirse con Visual
Studio 7.
El cdigo C# debe almacenarse en un archivo con extensin .cs
Para compilar el cdigo C# es necesario tener instalado la Plataforma .NET que incluye el
compilador C#, puede buscar el ejecutable en la ruta:
C:WINDOWSMicrosoft.NETFrameworkv1.1.4322csc.exe
Asegurese de tener esta ruta en el path para poder ejecutar el compilador desde cualquier
ubicacin.
Para compilar su archivo .cs es necesario abrir la consola (DOS) y escribir el comando cs
seguido del nombre de su archivo por ejemplo:
cd helloworld.cs
La salida exitosa de la compilacin podra ser as:

Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights
reserved.

Si existe algn error el compilador lo notificar. El archivo es compilado y ligado a
helloworld.exe, (el archivo .exe generado tendr el nombre del archivo fuente) para
ejecutar el programa slo es necesario escribir el nombre del archivo ejecutable.
Algo interesante es que es posible especificar el nombre del archivo ejecutable a travs de
un switch:
csc /out:nuevoNombre.exe nombreArchivoFuente.cs

El siguiente es el ejemplo tpico de los lenguajes de programacin:
class HelloWorld{
public static void Main(){
System.Console.WriteLine("Hello World");
}
}
El mtodo Main debe estar contenido en la clase y escrito con la primer letra en mayscula.
El tipo de este mtodo puede ser void o int. Tambin este mtodo puede especificar
argumentos:
public static void Main(string[] args)
System es el mbito del namespace en el cual el objeto Console est contenido.
Es posible importar el namespace en las aplicaciones indicandolo al inicio del cdigo con la
palabra reservada using que es una directiva para el namespace System. Existen ms
namespaces en la Plataforma .NET
using System;
Ejemplo Args
Examinemos el siguiente ejemplo, el cual recibe los argumentos con los que el componente
fue invocado:
Ejemplo de Args con for:

using System;
class Args{
public static void Main(string[] args){
Console.WriteLine("Argumentos : {0}",
args.Length);
for(int itera = 0; itera < args.Length; itera++)
Console.WriteLine("Argumento {0} : {1}",
itera, args[itera]);
}
}
Ejemplo de Args con foreach:
using System;
class App{
public static void Main(string[] args){
foreach(string input in args){
Console.WriteLine(input);
}
}
}
using System;, define el namespace System, el cual contiene entre otras la clase
Console la cual es utilizada para comunicarse con la lnea de comandos.
using permite al usuario omitir el namespace al utilizar el tipo al que es
referenciado en este caso System, por lo que en vez de escribir:
System.Console.WriteLine();
Solamente se escribe:
Console.WriteLine();
using no puede ser utilizado con un nombre de clase por lo que no es permitido
escribir using System.Console
class Args, Al no existir las funciones globales en C#, se declara una clase
llamada Args.
public static void Main(string[] args), La clase Args contiene una funcin
o mtodo Main(), el cual sirve como punto de partida de la ejecucin del
componente, este mtodo puede o no ser declarado con argumentos, en este caso es
fundamental declarlos porque deseamos precisamente leer y escribir estos
argumentos proporcionados al invocar el componente.
Al ser un mtodo de arranque debe ser declarado con el modificador static porque
no est asociado con una instancia de un objeto.
El mtodo indica que recibe un arreglo de tipo string llamado args
Console.WriteLine("Argumentos : {0}", args.Length);, invoca el mtodo
WriteLine de la clase Console para escribir en la lnea de comando lo que se
indica entre los parntesis.
La primer parte de lo que se encierra entre parntesis es un string donde es
necesario destacar que{0}, es una notacin que indica entre llaves un ndice que
hace referencia a una variable asociada a este, en este caso asociada con
args.Length
args.Length, Length es un mtodo de la clase args el cual obtiene el nmero de
elementos que contiene este arreglo.
El ciclo for comienza una iteracin desde 0 hasta el nmero de elementos que
contiene el arreglo args.Length, por cada elemento contenido en el arreglo escribe
en la lnea de comandos lo que se indica en ("Argumento {0} : {1}", itera,
args[itera]) que como mencionamos anteriormente {0} hace referencia al orden
en que las variables sern escritas, en este caso corresponde al iterador y {1}
corresponde a args[itera], lo cual indica obtener el elemento en cuestin del
arreglo args.
Para compilar el componente utilice csc Args.cs
Para ejecutar el componente sin parmetros escriba en la lnea de comando: csc
Args
Salida : Argumentos : 0
Para ejecutar el componente con parmetros escriba en la lnea de comando:
csc Args p1 p2 p3 p4 p5 p6 ... pn
Por ejemplo: args http : www . informatique . com . mx
Salida :
Argumentos : 8
Argumento 0 : http
Argumento 1 : :
Argumento 2 : www
Argumento 3 : .
Argumento 4 : informatique
Argumento 5 : .
Argumento 6 : com
Argumento 7 : .
Argumento 8 : mx

Ejemplo Input/Output
Es posible leer datos de la consola utilizando el mtodo ReadLine y es posible mostrarlos
utilizando el mtodo Write o WriteLine del objeto Console:
using System;
class inOut{
public static void Main(){
Console.Write("Fecha de Nacimiento: ");
String strFecNac = Console.ReadLine();
Console.WriteLine("FecNac = " + strFecNac);
}
}

Note que importar la directiva System hace posible omitir escribir el namespace, de esta
forma slo es necesario escribir el nombre del objeto seguido del nombre del mtodo.
Ejemplo String Format
Es posible dar formato a la salida de datos a un tipo string, utilizando la sintaxis {nmero}
donde nmero es reemplazado por la variable correspondiente:
using System;
class strFormat{
public static void Main(){

Console.Write("Nombre: ");
String strNombre = Console.ReadLine();

Console.Write("Edad: ");
String strEdad = Console.ReadLine();

Console.Write("Telfono: ");
String strTel = Console.ReadLine();

Console.Write("Direccin: ");
String strDir = Console.ReadLine();

Console.WriteLine("Datos: {0} {1} {2} {3}",
strNombre
, intEdad, strTel, strDir);
}
}
Funcin Main
Es posible incluir una funcin esttica en la clase para poder probarla, en C# esta funcin
esttica puede ser escrita como Main() e indica el inicio de la ejecucin de un programa:

using System;
class App{
public static void Main(){
Console.WriteLine("Hello world!");
}
}
El ejemplo anterior define a la funcin Main como void lo cual indica que no regresa un
valor, pero es posible indicar que si regrese un valor escribiendo el tipo de la funcin como
int por ejemplo, que indica que regresa un valor de tipo entero:
using System;
class App{
public static int Main(){
Console.WriteLine("Hello world!");
return(1);
}
}

Tambin es posible que la funcin Main reciba parmetros de la lnea de comandos, para
ello es necesario especificar un arreglo de strings como parmetro:
using System;
class App{
public static void Main(string[] args){
foreach(string input in args){
Console.WriteLine(input);
}
}
}
Mltiples Funciones Main
Es posible que existan en una aplicacin varias clases que contengan la funcin Main() y
por ello al compilar se indicar un error.
Para evitar el error o indicar que funcin Main() de que clase deseamos que se ejecute, es
necesario utilizar el siguiente switch al compilar:
/main:nombreClase
Por ejemplo
using System;
class ClaseA{
public static void Main(){
Console.WriteLine("Main de la clase A");
}
}
class ClaseB{
public static void Main(){
Console.WriteLine("Main de la clase B");
}
}
class ClaseC{
public static void Main(){
Console.WriteLine("Main de la clase C");
}
}
Al compilar utilice : csc multiplesmain.cs /main:ClaseB
Salida: Main de la clase B
Preprocesamiento
Lo ms importante en este punto es que en C# no existe el preprocesador, el motivo por el
cual no existe es para simplificar la estructura de compilacin adems de que no hay
necesidad de escribir un archivo de encabezados por separado y mantener en sincronia la
implementacin, cuando los archivos fuente C# son compilados el orden de la compilacin
de archivos individuales no es importante y es equivalente a un archivo de gran tamao.
Un identificador es el nombre que es usado para algn elemento de un programa como una
variable o funcin y deben tener una letra o guin bajo como primer caracter.
C# soporta las siguientes directivas de preprocesamiento:
Tamao Valor
#define
Define un identificador, los identificadores tambin pueden ser
definidos via la lnea de comando
#undef Elimina la definicin de un identificador
#if
El cdigo de la seccin es compilado si la expresin es
verdadera
#elif
Constructor Else-if, si la directiva anterior no se cumplio y si la
expresin es verdadera el cdigo de la seccin es compilado
#else
Si la directiva anterior no se cumplio el cdigo de la seccin es
compilado
#endif Marca el final de la seccin
Los identificadores deben preceder a cualquier cdigo real.
Es posible utilizar los siguientes operadores en expresiones preprocesador:
!
==
!=
&&
||
Es posible utilizar parntesis para agrupar expresiones.
Comentarios
Es posible comentar el cdigo, para ello existen dos modalidades:
1. //, que se utiliza para comentar una lnea, es decir, todo lo que sigue a // es
ignorado.
2. /* */, que se utiliza para comentar segmentos de cdigo.
Value Types
Una variable contiene un valor de cierto tipo, C# forza a inicializar las variables antes de
utilizarlas en una operacin.
Cuando se asigna un valor a un value type el valor actual es copiado a diferencia de los
reference types lo que se copia es la referencia actual no el valor.
C# agrupa los value types en:
1. Tipos Simples
2. Tipos Estructura
3. Tipos Enumeracin
Tipos Simples
Los Tipos Simples de C# comparten caractersticas como las de alias con los tipos de
sistema de .NET, expresiones constantes consisten de Tipos Simples evaluados solamente
en tiempo de compilacin no en tiempo de ejecucin y los Tipos Simples pueden ser
inicializados con literales.
Los Tipos Simples de C# se agrupan en:
Integral
Representa valores enteros y existen nueve tipos integral en C#:
Tipo Tamao Valor
sbyte
Entero con
signo
8 bit -128 a 127
byte
Entero sin
signo
8 bit 0 a 255
short
Entero con
signo
16 bit -32,768 a 32,767
ushort
Entero sin
signo
16 bit 0 a 65,535
int
Entero con
signo
32 bit -2,147,483,648 a 2,147,483,647
uint
Entero sin
signo
32 bit 0 a 4,294,967,295
long
Entero con
signo
64 bit
-9,223,372,036,854,775,808 a -
9,223,372,036,854,775,807
ulong
Entero sin
signo
64 bit 0 a 18,446,744,073,709,551,615

Bool
Representa valores booleanos verdadero y falso, por lo que es posible asignar a una
variable un valor booleano o el resultado de una expresin:
bool bContinuar = (a > b);
En C# el valor verdadero no es posible representarlo con algn valor diferente de
cero, no hay una conversin entre el tipo integral a bool que force esta conversin.
Char
Representa un caracter Unicode de 16 bit de tamao, por ejemplo:
char cSexo = 'M';
Tambin es posible asignar un valor hexadecimal utilizando la secuencia de escape
x o un valor Unicode con la secuencia de escape u:
char cHexadecimal = 'x0068';
char cUnicode = 'u0068';

No existen conversiones implicitas de char a otro tipo de datos disponible, esto
significa por ejemplo que tratar de convertir una variable char a un tipo de dato
integral no es posible en C#, por lo que se tendr que hacer un cast explicito:
char cCaracter = (char)65;
int nNumero = (int)'A';

Floating Point
Representan dos tipos de datos, flotantes (float) y dobles (double):
Tipo Valor
float 1.5x10
-45
a 3.4x10
38
con una precisin de 7 dgitos
double 5.0x10
-324
a 1.7x10
308
con una precisin de 15-16 dgitos
Al realizar operaciones con Floating Point pueden producirse los siguientes valores:
o Cero positivo y negativo
o Infinito positivo y negativo
o NaN, Not-a-Number
Nota: Si una expresin un valor es de tipo Floating Point todos los otros valores
son convertidos a tipos Floating Point antes de realizar el clculo.
Decimal
Representa un tipo de alta precisin de 128 bit el cual es posible utilizarlo para
calculos financieros y monetarios. Los valores posibles comprenden los rangos
1.0x10
-28
a 7.9x10
28
con una precisin de 28 a 29 dgitos.
No hay conversiones implicitas entre decimales y dobles, se podra generar un
overflow o perder precisin, por lo que es necesario una conversin explcita con un
cast.
Cuando se define una variable y se le asigna un valor se utiliza el sufijo m para
denotar que es un valor decimal:
decimal decDecimal = 1.0m
Si se omite la letra m la variable podra ser tratada como double por el compilador
antes de ser asignado.
Tipos Estructura
Un tipo struct puede declarar constructores, constantes, campos, mtodos, propiedades,
ndices, operadores y tipos anidados. Las estructuras actuan de manera similar a una clase y
con mayores restricciones, por ejemplo no pueden heredar de cualquier otro tipo, ni
tampoco otra clase puede heredar de una estructura.
Las estructuras deberan ser utilizadas slo para tipos que son realmente una pieza de datos.
La diferencia entre struct y class en C# es que struct es un value type y class es una
reference type.
La principal idea de utilizar struct es para crear objetos ligeros como Point, FileInfo,
etc., de esta manera se conserva memoria porque no hay referencias adicionales que son
creadas como se necesiten por objetos clase.
using System;
struct IP{
public byte b1,b2,b3,b4;
}
class ip{
public static void Main(){
IP miIP;
miIP.b1 = 192;
miIP.b2 = 168;
miIP.b3 = 1;
miIP.b4 = 101;
Console.Write("{0}.{1}.", miIP.b1,miIP.b2);
Console.Write("{0}.{1}", miIP.b3,miIP.b4);
}
}
Tipos Enumeracin
Es posible establecer un conjunto de constantes relacionadas, por default los elementos de
una enumeracin son de tipo int donde el primer elemento tiene el valor 0 y cada elemento
subsecuente se incrementa en 1. Es posible establecer el valor del primer elemento
simplemente asignando a este el valor deseado, as como es posible especificar el tipo de
dato de los valores contenidos especificandolo despus del nombre de la enumeracin
aunque estn restringidos a los tipos: long, int, short y byte.
Sintaxis:
enum NombreEnumeraciones{
constante1,
constante2,
constante3,
.
.
constanteN
}
Ejemplo:

using System;
public class Enumeracion {
enum enumDias {Sabado, Domingo, Lunes, Martes, Mircoles,
Jueves, Viernes };
enum enumMeses
{Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto,Septiembre,_
Octubre,Noviembre,Diciembre};
enum enumFecha {Dia = 21, Mes = 9, Ao = 1971};

public static void Main() {
Type eDias = typeof(enumDias);
Type eMeses = typeof(enumMeses);
Type eFecha = typeof(enumMeses);

Console.WriteLine("Los das de la semana, y su valor
correspondiente en la enumeracin es:");

foreach ( string s in Enum.GetNames(eDias) )
Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( eDias,
Enum.Parse(eDias, s), "d"));

Console.WriteLine();
Console.WriteLine("Los meses del ao, y su valor correspondiente
en la enumeracin es:");

foreach ( string s in Enum.GetNames(eMeses) )
Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(eMeses,
Enum.Parse(eMeses, s), "d"));
}
}
Tipos Base
Los Tipos Base para las enumeraciones se especifican listando el tipo base despus del
nombre de la enumeracin:
enum eDias : int{
Lunes,
Martes,
Mircoles,
Jueves,
Viernes
};
Los tipos base vlidos para las enumeraciones son: byte, sbyte, short, ushort, int,
uint, long y ulong.
Si el tipo base no es especificado, el tipo base por default es int.
Tipos Referencia
Es contraste a value types los reference types no almacenan el dato actual que representan,
porque almacenan una referencia al dato actual.
Los reference types que C# utiliza son:
Tipo Objeto
Tipo Clase
Interfaces
Delegados
Tipo string
Arreglos
Tipo Objeto
El Tipo Objeto es la Clase Base de todos los tipos, al ser la clase base de todos los tipos es
posible asignarle valores de cualquier tipo.
El Tipo Objeto es utilizado cuando el value type esta boxed, es decir, que est disponible
como un objeto.
Tipo Clase
El Tipo Clase contiene datos miembro, funciones miembro y tipos anidados. Los datos
miembro son constantes, campos y eventos. Las funciones miembro incluyen mtodos,
propiedades, ndices, operadores, constructores y destructores.
Interfaces
Una interface declara un tipo referencia que tiene slo miembros abstractos. Slo existe la
firma pero no tiene implementado todo el cdigo, por lo que no es posible instanciar una
interface, slo un objeto que deriva de la interface. Para crear una interface se emplea la
palabra reservada interface:
using System;
interface Iuno{
void AccionUno();
}

class Implementa : Iuno{
public void AccionUno(){
Console.WriteLine("Accin uno...");
}
}

class App{
public static void Main(){
Implementa I = new Implementa();
I.AccionUno();
}
}
Es posible definir mtodos, propiedades e ndices en una interface, cuando se define una
Clase es posible derivar de mltiples interfaces, mientras que al definir una interface slo es
posible derivar de slo una clase.
Las interfaces estn estrechamente relacionadas a clases abstractas, se parecen a una clase
abstracta que tiene todos sus miembros abstractos.
Cuando un objeto implementa una interface, una referencia a la interface puede ser
obtenida por un cast de la interface.
Una clase puede implementar ms de una interface.
class NombreClase : InterfaceA, InterfaceB{}
Existe una tcnica llamada Implementacin de la Interface Explcita y se utiliza para
resolver colisiones con nombres de mtodos iguales entre interfaces:
using System;
interface Iuno{
void AccionUno();
}
interface Idos{
void AccionUno();
}

class Implementa : Iuno, Idos{
void Iuno.AccionUno(){
Console.WriteLine("Colisin resuelta con el nombre
del mtodo Iuno");
}
void Idos.AccionUno(){
Console.WriteLine("Colisin resuelta con el nombre
del mtodo Idos");
}
}

class App{
public static void Main(){
Implementa I = new Implementa();
Iuno uno = (Iuno) I;
uno.AccionUno();
Idos dos = (Idos) I;
dos.AccionUno();
}
}
Es posible ocultar al usuario de la clase la implementacin de una interfaz, as como
tambin es posible crear interfaces basadas de otras interfaces.
Delegados
Los delegados son similares a las interfaces, especifican un contratado entre un caller y un
implementer (implementador).
Un delegado especifica la forma de una funcin en vez de especificar toda una interface.
Las interfaces se crean en tiempo de compilacin y los delegados son creados en tiempo de
ejecucin.
Un delegado encapsula un mtodo con cierta firma, bsicamente un delegado es un type-
safe y secure version. Un delegado es una implementacin de function pointers orientada a
objetos y son utilizados en muchas situaciones donde un componente necesita volver a
invocar el componente que lo esta usando.
Es posible encapsular mtodos estticos e instancias en una instancia delegado.
El principal uso de los delegados es con los eventos no con las clases.
La especificacin del delegado determina la forma de la funcin y crea una instancia del
delegado, se usa la funcin que coincide con la forma.
Los delegados al ser de naturaleza dinmica se utilizan cuando el usuario desea cambiar el
comportamiento, por ejemplo si deseamos que una clase Ordenamiento soporte diferentes
mtodos de ordenacin, la ordenacin podra ser controlada en base a un delegado que
defina la funcin de comparacin.
Nota los delegados siempre son creados an si no son usados, pero los delegados podran
ser creados al vuelo si se reemplazan las funciones estticas por propiedades, entonces
unicamente se crea el delegado solo si se utiliza la propiedad.
Tipo string
El Tipo string se utiliza para manipular datos string. La clase string deriva directamente
de object y no es posible derivarla.
Todos los strings en C# son instancias del tipo System.String en el CLR.
string es un alias para la clase predefinida System.String y su uso es muy sencillo:
string sWebSite = "http://www.informatique.com.mx";
Para acceder a un caracter, simplemente acceda a su ndice:
sWebSite[11];
Es posible hacer un barrido de los caracteres que componen el string utilizando la
propiedad Length que poseen los arreglos y porque es posible acceder a estos tratando al
string como un arreglo:
using System;
class App{
public static void Main(){
string sWebSite = "http://www.informatique.com.mx";
Console.WriteLine("sWebSite contiene : " + sWebSite.Length
+ " caracteres");
for(int iElemento = 0; iElemento < sWebSite.Length;
iElemento++){
Console.WriteLine("Elemento " + iElemento + " : "
+ sWebSite[iElemento]);
}
}
}
Es posible concatenar strings utilizando el operador +.
Si requiere comparar strings por igualdad utilice el operador de comparacin ==
Aunque string es un reference type la comparacin se realiza comparando los valores no
las referencias.
La clase String es un ejemplo de tipo inmutable, es decir, que los caracteres contenidos en
el string no puede ser modificados por los usuarios del string, todas las operaciones que son
realizadas por la clase String regresan una versin modificada del string en vez de
modificar la instancia en la cual se invoco el mtodo.
La clase String soporta los sisguientes mtodos de comparacin y bsqueda:
Mtodo Descripcin
Compare()
Compara dos strings.
CompareOrdinal()
Compara dos regiones de strings utilizando una comparacin
ordinal
CompareTo()
Compara la instancia actual con otra instancia.
EndsWith()
Determina cuando un substring existe al final de un string
StartsWith()
Determina cuando un substring existe al principio de un string.
IndexOf()
Regresa la posicin de la primer ocurrencia de un substring
LastIndexOf()
Regresa la posicin de la ltima ocurrencia de un substring
Concat()
Concatena dos o ms strings u objetos, si se pasan objetos la
funcin ToString es invocada
CopyTo()
Copia un nmero especfico de caracteres de una ubicacin del
string dentro del arreglo
Insert()
Regresa un nuevo string con un substring insertado en la
ubicacin especfica
Join()
Une un arreglo de strings junto con un separador entre cada
elemento del arreglo
PadLeft()
Alinea a la izquierda un string
PadRight() Alinea a la derecha un string
Remove()
Elimina caracteres de un string
Replace()
Reemplaza todas las instancias de un caracter con caracteres
diferentes
Split()
Crea un arreglo de strings dividiendo un string en cualquier
ocurrencia de uno o ms caracteres
Substring()
Extrae un substring de un string
ToLower() regresa una versin de un string en minsculas
ToUpper()
regresa una versin de un string en maysculas
Trim() Elimina espacios en blanco de un string
TrimEnd()
Elimina un string de caracteres al final de un string
TrimStart() Elimina un string de caracteres al inicio de un string
object.ToString(), convierte un objeto a una representacin string. String.Format()
puede ser utilizada para crear un string basado en los valores de otro string.
La clase StringBuilder soporta las siguientes propiedades y mtodos:
Propiedad Descripcin
Capacity
Recupera o establece el nmero de caracteres que StringBuilder
puede contener
[]
ndice StringBuilder utilizado para obtener o establecer un
caracter en la posicin especfica
Length Recupera o establece la longitud
MaxCapacity
Recupera la capacidad mxima del StringBuilder

Mtodo Descripcin
Append()
Agrega la representacin string de un objeto
AppendFormat()
Agrega la representacin string de un objeto, utilizando un
formato especfico para el objeto
EnsureCapacity()
Asegura que StringBuilder tiene suficiente espacio para un
nmero de caracteres especfico
Insert()
Inserta la representacin string de un objeto especfico en una
posicin especfica
Remove()
Elimina los caracteres especficos
Replace()
Reemplaza todas las instancias de un caractes con un nuevo
caracter
Arreglos
Un arreglo contiene variables a las cuales se accede a travs de ndices, todas las variables
contenidas en el arreglo son referidos como elementos los cuales deben ser del mismo tipo,
por lo que el tipo del arreglo.
Los arreglos en C# son referencias a objetos. Un arreglo value type no contiene instancias
boxed.
El valor inicial de un arreglo es null, un arreglo de objetos es creado utilizando new.
Cuando un arreglo es creado inicialmente contiene los valores por default para los tipos que
este contendr.
Sintaxis:
tipo[] identificador;
Note que para definir un arreglo se utilizan los corchetes [] despus del tipo del arreglo.
Ejemplo:
string[] aPersonas;
Es posible inicializar un arreglo al momento de crearlo:
string[] asPersonas = new string[] {"Tim Berners-Lee","Brendan
Eich","Dennis Ritchie","James Gosling"};
Durante la inicializacin es posible omitir new tipo[x] y el compilador podra determinar
el tamao de almacenamiento para el arreglo del nmero de items en la lista de
inicializacin:
string[] asPersonas = {"Tim Berners-Lee","Brendan Eich","Dennis
Ritchie","James Gosling"};
Cada elemento de un arreglo de ints es un int con el valor 0:
int[] aiNumeros = new int[5];
Cada elemento de un arreglo de strings es un string con el valor null:
string[] asNombres = new string[5];
La dimensin del arreglo puede ser simple o multidimensional, donde cada dimensin
comienza con el ndice 0, si requiere hacer un barrido de todos los elementos del arreglo,
comience a partir del ndice 0 hasta la longitud del arreglo menos uno
(nombreArreglo.Length - 1 o nIndice < nombreArreglo.Length);
using System;
class Arreglo{
static public void Main(){
string[] aNombres = {"Hugo","Paco","Luis"};
Console.WriteLine(aNombres[0]);
Console.WriteLine(aNombres[1]);
Console.WriteLine(aNombres[2]);
}
}
Otra alternativa al ejemplo anterior es:
int[] aiNumeros = new int[3];
aiNumeros[0] = 4;
aiNumeros[1] = 33;
aiNumeros[2] = 43;
Al declarar el arreglo especifique solamente el nmero de elementos que este contendr.
utilice la palabre reservada new seguido del tipo y entre corchetes el nmero de elementos
que contendr.
Es posible ordernar y buscar los elementos de un arreglo gracias a que los arreglos en C#
estn basados en el tipo System.Array del runtime NET. El mtodo Sort() podra ordenar
los elementos de un arreglo, los mtodos IndexOf() y LastIndexOf() y BinarySearch
podran buscar elementos en un arreglo. El mtodo Reverse podra invertir el orden de los
elementos de un arreglo.
Arreglos Multidimensionales
Los Arreglos Multidimensionales son aquellos que tienen ms de una dimensin.
Sintaxis:
tipo[,] identificador;
Ejemplo:
string[,] asBidimensional = new string[2, 4];
Para definir un arreglo multidimensional, simplemente defina arreglos como elementos del
arreglo:
string[,] asMulti = {{"a","1"},{"b","2"},{"c","3"}};
Ejemplo:
using System;
class App{
public static void Main(){

string[] asPersonas = {"Tim Berners-Lee", "Brendan Eich", "Dennis
M. Ritchie", "James Gosling"};
Console.WriteLine("Longitud del arreglo asPersonas : " +
asPersonas.Length);

int[] aiNumeros = new int[3] {1, 2, 3};
Console.WriteLine("Longitud del arreglo aiNumeros : " +
aiNumeros.Length);

//Define 4 arreglos de 2 dimensiones
int iRenglon = 4;
int iColumna = 2;
string[,] asBidimensional = new string[iRenglon, iColumna];
// 4 renglones * 2 columnas = 8 Elementos

asBidimensional[0,0] = "00";
asBidimensional[0,1] = "01";

asBidimensional[1,0] = "10";
asBidimensional[1,1] = "11";

asBidimensional[2,0] = "20";
asBidimensional[2,1] = "21";

asBidimensional[3,0] = "30";
asBidimensional[3,1] = "31";

Console.WriteLine("Longitud del arreglo asBidimensional : " +
asBidimensional.Length);

int[,] aiBidimensional = { {11,22}, {33,44}, {55,66}, {77,88} };

for(int i = 0; i < iRenglon; i++){
for(int j = 0; j < iColumna; j++){
Console.WriteLine("Dimensin " + i + " elemento " + j + "
: " + aiBidimensional[i,j]);
}
}
Console.WriteLine("Longitud del arreglo aiBidimensional : " +
aiBidimensional.Length);
}
}

Arreglo de Arreglos
Un Arreglo de Arreglos es tambin conocido como jagged array porque no tiene que ser
rgido.
Por ejemplo:
int[][] aiIDs = new int[3][];
Este ejemplo define un arreglo de arreglo de tipo int donde su dimensin es 3 elementos,
donde estos elementos son arreglos.
Arreglos de Objetos
Un arreglo de objetos es creado utilizando new.
Es posible declarar y manipular arreglos de objetos de la siguiente manera:
using System;
public class Persona{
//Propiedades
public string sNombre;
public int iEdad;
//Constructor
public Persona(string sNombre, int iEdad){
this.sNombre = sNombre;
this.iEdad = iEdad;
}
//Mtodos
public string Tipo(){
return "Persona";
}
}
//Herencia Simple
public class Empleado : Persona{
public Empleado(string sNombre, int iEdad):base(sNombre,
iEdad){}
public new string Tipo(){
return "Empleado";
}
}

class App{
//Aplicacin
public static void Main(){
Persona Mexicano = new Persona("Gerado ngeles Nava", 33);
Console.WriteLine("Mexicano.sNombre : " +
Mexicano.sNombre);
Console.WriteLine("Mexicano.iEdad : " + Mexicano.iEdad);
Console.WriteLine("Mexicano.Tipo : " + Mexicano.Tipo());

Console.WriteLine("--- Arreglo de Objetos ---");

Empleado[] aProgramadores = new Empleado[2];
aProgramadores[0] = new Empleado("Bill Gates", 50);
aProgramadores[1] = new Empleado("Eric S. Raymond", 60);
for(int i = 0; i < aProgramadores.Length; i++){
Console.WriteLine("aProgramadores["+i+"].sNombre : " +
aProgramadores[i].sNombre);
Console.WriteLine("aProgramadores[" + i + "].iEdad : "
+ aProgramadores[i].iEdad);
Console.WriteLine("aProgramadores[" + i + "].Tipo : " +
aProgramadores[i].Tipo());
}
}
}
Conversin de Arreglos
Una conversin implcita es posible si los arreglos tienen el mismo nmero de dimensiones,
si los elementos de un arreglo tienen una conversin de referencia implcita para los tipos
de elementos del otro arreglo y ambos arreglos son tipos referencia.
Una conversin explcita tiene los mismos requerimientos de una conversin implcita
excepto que los elementos de un arreglo deben ser convertibles explcitamente a los tipos
de elementos del otro arreglo.
Clase Array
La clase Array provee entre otras, funciones de bsqueda y ordenamiento.
En el siguiente ejemplo se muestra como es ordenado un arreglo de strings:
using System;
class App{
public static void Main(){
string[] aLenguajes = {"Java", "Pascal", "ActionScript",
"PHP", "C#", "SQL",
"JavaScript", "C", "Java", "Prolog", "Visual Basic",
"C++"};
Array.Sort(aLenguajes);
for(int elemento = 0; elemento < aLenguajes.Length;
elemento++)
Console.WriteLine("Elemento [" + elemento + "] = "
+ aLenguajes[elemento]);
}
}
Salida:
Elemento [0] = ActionScript
Elemento [1] = C
Elemento [2] = C#
Elemento [3] = C++
Elemento [4] = Java
Elemento [5] = Java
Elemento [6] = JavaScript
Elemento [7] = Pascal
Elemento [8] = PHP
Elemento [9] = Prolog
Elemento [10] = SQL
Elemento [11] = Visual Basic
La funcin Sort(), tambin se puede utilizar con nmeros:
using System;
class App{
public static void Main(){
double[] aNumeros = {8.7, 6.9, -6.5, 4.2, -102.09, 1.9,
0.01, -0.002, 99.87};
Array.Sort(aNumeros);
for(int elemento = 0; elemento < aNumeros.Length;
elemento++)
Console.WriteLine("Elemento [" + elemento + "] = "
+ aNumeros[elemento]);
}
}
Salida:
Elemento [0] = -102.09
Elemento [1] = -6.5
Elemento [2] = -0.002
Elemento [3] = 0.01
Elemento [4] = 1.9
Elemento [5] = 4.2
Elemento [6] = 6.9
Elemento [7] = 8.7
Elemento [8] = 99.87
Interface IComparable
La funcin sort no trabaja con clases o estructuras porque no conoce su orden, pero si
desea ordenarlas utilice la interface IComparable, por ejemplo una ordenacin utilizando
una propiedad numrica:
using System;

public class Lenguaje : IComparable{
string nombre;
int id;
public Lenguaje(string nombre, int id){
this.nombre = nombre;
this.id = id;
}
int IComparable.CompareTo(object o){
Lenguaje lenguajeB = (Lenguaje)o;
if(this.id > lenguajeB.id){return 1;}
if(this.id < lenguajeB.id){
return -1;
}else{
return 0;
}
}
public override string ToString(){
return nombre + " " + id;
}
}

class App{
public static void Main(){
Lenguaje[] aLenguaje = new Lenguaje[5];
aLenguaje[0] = new Lenguaje("C",3);
aLenguaje[1] = new Lenguaje("ActionScript",5);
aLenguaje[2] = new Lenguaje("JavaScript",2);
aLenguaje[3] = new Lenguaje("Java",8);
aLenguaje[4] = new Lenguaje("PHP",1);
Array.Sort(aLenguaje);
foreach(Lenguaje len in aLenguaje)
Console.WriteLine(len);
}
}
Salida:
PHP 1
JavaScript 2
C 3
ActionScript 5
Java 8

Interface IComparer
Es posible definir mltiples tipos de ordenamientos gracias a que el diseo del Framework
provee esta capacidad.
Cada clase slo puede implementar una interface a la vez, por lo que solamente se podra
permitir un tipo de ordenamiento, entonces se requiere una clase separada para cada tipo de
ordenamiento que implementen IComparer y podra tambin implementar la funcin
Comapare():
using System;
using System.Collections;
public class Lenguaje : IComparable{
string nombre;
int id;
public Lenguaje(string nombre, int id){
this.nombre = nombre;
this.id = id;
}
int IComparable.CompareTo(object o){
Lenguaje lenguajeB = (Lenguaje)o;
if(this.id > lenguajeB.id){return 1;}
if(this.id < lenguajeB.id){
return -1;
}else{
return 0;
}
}
public override string ToString(){
return nombre + " " + id;
}
public class OrdenaNombres : IComparer{
public int Compare(object oA, object oB){
Lenguaje lenA = (Lenguaje)oA;
Lenguaje lenB = (Lenguaje)oB;
return
String.Compare(lenA.nombre,lenB.nombre);
}
}
}

class App{
public static void Main(){
Lenguaje[] aLenguaje = new Lenguaje[5];
aLenguaje[0] = new Lenguaje("C",3);
aLenguaje[1] = new Lenguaje("ActionScript",5);
aLenguaje[2] = new Lenguaje("JavaScript",2);
aLenguaje[3] = new Lenguaje("Java",8);
aLenguaje[4] = new Lenguaje("PHP",1);

ArrayList aList = new ArrayList();
aList.Add(aLenguaje[0]);
aList.Add(aLenguaje[1]);
aList.Add(aLenguaje[2]);
aList.Add(aLenguaje[3]);
aList.Add(aLenguaje[4]);
aList.Sort((IComparer) new
Lenguaje.OrdenaNombres());
foreach(Lenguaje len in aList)
Console.WriteLine(len);
}
}
Salida:
ActionScript 5
C 3
Java 8
JavaScript 2
PHP 1
IComparer Como Propiedad
En el ejemplo anterior el usuario tiene que crear una instancia del ordenamiento deseado y
hacer un cast de IComparer, pero es posible simplificar esto utilizando una propiedad
esttica y hacerlo por el usuario:
using System;
using System.Collections;
public class Lenguaje : IComparable{
string nombre;
int id;
public Lenguaje(string nombre, int id){
this.nombre = nombre;
this.id = id;
}
int IComparable.CompareTo(object o){
Lenguaje lenguajeB = (Lenguaje)o;
if(this.id > lenguajeB.id){return 1;}
if(this.id < lenguajeB.id){
return -1;
}else{
return 0;
}
}
public override string ToString(){
return nombre + " " + id;
}
public static IComparer Ordena{
get{
return (IComparer) new OrdenaNombres();
}
}
public class OrdenaNombres : IComparer{
public int Compare(object oA, object oB){
Lenguaje lenA = (Lenguaje)oA;
Lenguaje lenB = (Lenguaje)oB;
return
String.Compare(lenA.nombre,lenB.nombre);
}
}
}

class App{
public static void Main(){
Lenguaje[] aLenguaje = new Lenguaje[5];
aLenguaje[0] = new Lenguaje("C",3);
aLenguaje[1] = new Lenguaje("ActionScript",5);
aLenguaje[2] = new Lenguaje("JavaScript",2);
aLenguaje[3] = new Lenguaje("Java",8);
aLenguaje[4] = new Lenguaje("PHP",1);

Array.Sort(aLenguaje, Lenguaje.Ordena);

foreach(Lenguaje len in aLenguaje)
Console.WriteLine(len);
}
}
Salida:

ActionScript 5
C 3
Java 8
JavaScript 2
PHP 1
Expresiones Regulares
Las Expresiones Regulares proveen un mtodo muy poderoso para hacer funciones de
busquedas y reemplazamiento.
Operador as
El Operador as checa el tipo del operador izquierdo y si puede ser convertido
explicitamente a el operador derecho, se obtiene como resultado el objeto convertido a el
operador derecho, si no puede ser convertido la operacin falla y regresa null. Este
operador slo puede se utilizado con clases.
Secuencias de Escape
Secuencia de Escape Descripcin
' Comilla simple
" Comilla doble
\ Diagonal invertida

Nulo
a Alert
b Retroceso
f Form Feed
n Nueva lnea
r Retorno de carro
t Tabulador
v Tabulador vertical
Boxing
Boxing es un mecanismo que crea una liga entre los tipos de valores y las tipos de
referencia permitiendo a un tipo de valor ser convertido a un tipo objeto y viceversa.
using System;
class App{
public static void Main(){
int iEdad = 33;
object oNumero = iEdad; //Box
int iNumero = (int)oNumero; //Unbox
//cast necesario porque oNumero podra contener
cualquier tipo de objeto
}
}
Nota, durante la conversin unboxing el tipo debe coincidir exactamente, un valor de tipo
boxed no puede ser unboxed (convertido) a un tipo compatible. Si requiere obtener otro tipo
de valor diferente al que contiene el boxed, en ese caso primero obtenga el valor correcto y
despus realice un cast al tipo que requiera: (valorRequerido)
valorRequerido vr = (valorRequerido)(valorBoxed)objeto;
Otra forma de definir el concepto boxing es que este mecanismo permite que los value
types parezcan o tengan la apariencia de reference types.
Conversiones Boxing
Boxing un valor se refiere a la conversin implcita de cualquier tipo de valor al tipo objeto.
Cuando un tipo de valor es boxed se asigna espacio a una instancia de objeto y el valor del
value type es copiado al nuevo objeto.
Observe las siguientes lneas:
int iNumero = 2012;
object oNumero = iNumero; //invocacin implicita a
una operacin boxing

Al asignar el valor de la variable entera nNumero a una variable objeto se realiza
internamente una operacin boxing, donde el valor de la variable nNumero es copiado al
objeto oNumero, entonces las variables entera y objeto existen en la pila pero los valores de
los objetos residen en el rea o espacio asignado, lo que implica que los valores son
independientes y no hay una liga entre ellos:
using System;
class Box{
public static void Main(){
int iNumero = 2012;
object oNumero = iNumero; //invocacin implicita a
una operacin boxing

oNumero = 2005;
Console.WriteLine(iNumero);
Console.WriteLine(oNumero);
}
}
Al ejecutar el cdigo notar que el valor de oNumero es 2005 y el valor de iNumero no
cambio permanece en 2012.
Conversiones Unboxing
Al contrario que Boxing, Unboxing es un mecanismo de una operacin explcita, por lo que
es necesario indicar al compilador que tipo de valor deseamos extraer de un objeto, al
realizar la operacin Unboxing C# checa que el value type que se requiere este almacenado
en la instancia del objeto, si la verificacin es exitosa el valor es Unboxing.
Suponga que tiene una variable de tipo int y asigna el valor de esta variable int a un
objeto, despus declara una variable de tipo double y aplica un cast (double) al objeto
para asignar su valor a la variable double, el objeto contiene slo un valor int y no puede
ser asignado a la variable double porque el CLR dispara una excepcin
(System.InvalidCastException):
int iNumero = 2012;
object oNumero = iNumero; //invocacin implicita a una
operacin boxing
double dNumero = (double)oNumero; //invocacion explcita
(cast)
//CLR dispara la excepcin System.InvalidCastException
Constructores y Destructores
Antes de acceder a los mtodos o propiedades de una clase, primero se ejecuta el
constructor de la clase el cual contiene cdigo de inicializacin, si no se escribe un
constructor para la clase el compilador provee automticamente un constructor default.
En el runtime .NET el programador no puede controlar la destruccin de objetos.
Un constructor puede invocar un constructor del tipo base utilizando la sintaxis base.
Los constructores son invocados invocados automaticamente slo cuando una instancia de
un objeto es creada con new.
class NombreClase{
public NombreClase() : base(){} //Constructor que provee
el compilador
}
Las caractersticas de un constructor son:
Siempre tiene el mismo nombre que la clase.
No tiene declarado un tipo de regreso.
Por lo general tienen el modificador pblico.
Son utilizados para inicializar varibles.
Si la clase slo contiene miembros estticos, es posible crear un constructor
private, lo cual significa que no podr ser accesible fuera de la calse o que slo se
puede acceder desde la clase.
No puede ser invocado desde la definicin de la clase.
Un objeto no puede ser instanciado desde la definicin de la clase.
Al codificar no se est limitado a los parmetros del constructor, es posible enviar
argumentos iniciales para inicializar ciertos miembros.
using System;

class Vehiculo{
//Propiedades:
private int iRueda;
private int iPuerta;
private int iVentana;
private int iHelice;
private int iMotor;
private int iAsiento;
private string sTipo;//Aereo, anfibio, terrestre, espacial

//Constructor:
public Vehiculo(int Rueda, int Puerta, int Ventana, int
Helice, _
int Motor, int Asiento, string Tipo){
iRueda = Rueda;
iPuerta = Puerta;
iVentana = Ventana;
iHelice = Helice;
iMotor = Motor;
iAsiento = Asiento;
sTipo = Tipo;
}

//Lectura/escritura de propiedades:
public int Ruedas{
get{return iRueda;}
set{iRueda = value;}
}

public int Puertas{
get{return iPuerta;}
set{iPuerta = value;}
}

public int Ventanas{
get{return iVentana;}
set{iVentana = value;}
}

public int Helices{
get{return iHelice;}
set{iHelice = value;}
}

public int Motores{
get{return iMotor;}
set{iMotor = value;}
}

public int Asientos{
get{return iAsiento;}
set{iAsiento = value;}
}

public string Tipo{
get{return sTipo;}
set{sTipo = value;}
}

}

//Aplicacin:
class AplicConstructor{
public static void Main(){
Vehiculo MiAvion = new
Vehiculo(2,1,100,0,3,200,"Aereo");
Console.WriteLine("Ruedas : " + MiAvion.Ruedas);
Console.WriteLine("Puertas : " +
MiAvion.Puertas);
Console.WriteLine("Ventanas : " +
MiAvion.Ventanas);
Console.WriteLine("Helices : " +
MiAvion.Helices);
Console.WriteLine("Motores : " +
MiAvion.Motores);
Console.WriteLine("Asientos : " +
MiAvion.Asientos);
Console.WriteLine("Tipo : " + MiAvion.Tipo);
}
}
En un sentido estricto en C# no se tienen destructores, pero el termino destructor se refiere
a la liberacin de recursos.
Es posible escribir un mtodo que libere recursos despus de ser utilizados, pero porque
escribir un mtodo para liberar recursos si existe un destructor:
public ~NombreClase(){
//liberar recursos
}
La razn por la cual se debera escribir un mtodo adicional es por el recolector de basura,
el cual no es invocado inmediatamente despus que las variables quedan fuera de mbito,
slo se invoca el recolector de basura en ciertos intervalos o condiciones de memoria.
Lo que podra suceder es que los recursos se agoten antes de ser utilizados, entonces es
buena idea proveer un mtodo explcito Release, el cual tambin puede ser invocado por el
destructor:
public void Release(){
//Liberar recursos
}
public ~NombreClase(){
Release();
}
La invocacin del mtodo Release en el destructor no es obligatoria, la coleccin garbage
de cualquier forma realiza la liberacin de cualquier objeto, pero es una buena prctica no
olvidar liberar los recursos.
Constructor Esttico
Un Constructor Esttico podra ser invocado antes de ser creada la primer instancia de un
objeto, y es til para configurar el trabajo que necesita hacerse una vez.
En el runtime .NET el usuario no tiene control sobre cuando el constructor esttico es
invocado, ya que el runtime slo garantiza que algo es invocado despus del inicio del
programa y antes de ser creada la primer instancia de un objeto, lo que significa que no
puede ser determinada la instancia que es creada en el constructor esttico.
Para declarar un constructor esttico se utiliza el modificador static:
class NombreClase{
static NombreClase(){
.
.
}
}

Mtodos
La mayor parte de la funcionalidad es implementada en los mtodos, los mtodos son parte
del Tipo (class), pero los mtodos no son parte de la instancia (object).
Parmetros
De algn modo se deben pasar valores a un mtodo y tambin se debe regresar el resultado
de un mtodo, los valores son manipulados en:
Valores en Parmetros in
Se utilizan valores en parmetros para pasar una variable por valor a un mtodo, la variable
del mtodo es inicializada con una copia del valor del caller (quien realiz la invocacin).
using System;
public class Fecha{
public string Mayor(int iDiaA,int iMesA,int iAoA,int
iDiaB,int iMesB,int iAoB){
int iA = (iDiaA * 10000) + (iMesA + 100) +
(iAoA);
int iB = (iDiaB * 10000) + (iMesB + 100) +
(iAoB);
Console.WriteLine(iA + " > " + iB); //Test Line
(Delete)
if(iA > iB){
return iDiaA + "/" + iMesA + "/" + iAoA;
}else{
return iDiaB + "/" + iMesB + "/" + iAoB;
}
}
public string Menor(int iDiaA,int iMesA,int iAoA,int
iDiaB,int iMesB,int iAoB){
int iA = (iDiaA * 10000) + (iMesA + 100) +
(iAoA);
int iB = (iDiaB * 10000) + (iMesB + 100) +
(iAoB);
Console.WriteLine(iA + " < " + iB); //Test Line
(Delete)
if(iA < iB){
return iDiaA + "/" + iMesA + "/" + iAoA;
}else{
return iDiaB + "/" + iMesB + "/" + iAoB;
}
}
}

class AplicFecha{
public static void Main(){
Fecha MiFecha = new Fecha();
Console.WriteLine("La fecha mayor es : " +
MiFecha.Mayor(21,9,1971, 21,10,2000));
Console.WriteLine("La fecha menor es : " +
MiFecha.Menor(21,9,1971, 21,10,2000));

Console.WriteLine("La fecha mayor es : " +
MiFecha.Mayor(21,10,2000, 21,9,1971));
Console.WriteLine("La fecha menor es : " +
MiFecha.Menor(21,10,2000, 21,9,1971));

Console.WriteLine("La fecha mayor es : " +
MiFecha.Mayor(21,10,2000, 21,9,2005));
Console.WriteLine("La fecha menor es : " +
MiFecha.Menor(21,10,2000, 21,9,2005));
}
}

Al pasar un valor y no una referencia a la variable, es posible utilizar expresiones
constantes, el resultado de los mtodos Mayor y Menor es pasado a el caller como un
valor de regreso y es manipulado sin ser almacenarlo en una variable intermedia.
Si no hay modificadores los parmetros son siempre pasados por valor.
Valores en Parmetros ref
Es posible pasar un valor como parmetro a un mtodo, modificar el valor y regresarlo
como resultado del mtodo, para ello se utiliza el modificador ref seguido del tipo y del
nombre del parmetro.
Al contrario de los valores en parmetros no se pasa una copia del valor, sino la referencia
del valor y por ello al modificar el valor se hace la modificacin directa, tambin es
necesario inicializar el valor que se pasa como paramtro por medio de una variable
intermedia y no directamente a travs de una expresin constante:

using System;

public class Param{
public void ParametroRef(ref int RefParametro){//No
regresa un valor explcito
RefParametro *= RefParametro; //Se modifica el
valor directamente
//No se regresa un valor, porque se modifico de
manera directa
}
}

class Parametros{
public static void Main(){
Param MiParam = new Param();

int iValorRef = 5; //Se requiere inicializar el valor
MiParam.ParametroRef(ref iValorRef);//Se invoca el mtodo
pasando la referencia del valor
Console.WriteLine("ref : " + iValorRef);
}
}
Good Practice, se recomienda tener dos variables, una en el parmetro y otra en el
parmetro ref.
Recuerde, el compilador de C# no permite utilizar variables que no han sido inicializadas,
por lo que antes de utilizar o establecer los valores de una variable debe ser inicializada,
para ello existen dos formas de hacerlo:
1. Inicializar la variable al declararla.
2.
3. using System;
4.
5. class MiClase{
6. private int MiPropiedad;
7. public void AsignarValor(ref int MiRefParam){
8. this.MiPropiedad = MiRefParam;
9. }
10. public static void Main(){
11. MiClase MiObjeto = new MiClase();
12. int MiEdad = 33;//Se inicializa la variable al
declararla
13. MiObjeto.AsignarValor(ref MiEdad);
14. Console.WriteLine("MiEdad : " + MiEdad);
15. Console.WriteLine("MiObjeto.MiPropiedad : " +
MiObjeto.MiPropiedad);
16. }
17. }

18. Por ejemplo cambiar la definicin de la funcin y utilizar un parmetro out
en vez de un parmetro ref.
19. using System;
20.
21. class MiClase{
22. private int MiPropiedad;
23. public void AsignarValor(out int MiOutParam){//Se cambia
la definicin de la funcin
24. MiOutParam = 33;
25. this.MiPropiedad = MiOutParam;
26. }
27. public static void Main(){
28. MiClase MiObjeto = new MiClase();
29. int MiEdad;//No se inicializa la variable
30. MiObjeto.AsignarValor(out MiEdad);
31. Console.WriteLine("MiEdad : " + MiEdad);
32. Console.WriteLine("MiObjeto.MiPropiedad : " +
MiObjeto.MiPropiedad);
33. }
34. }

Los parmetros out son exactamente como los parmetros ref excepto que una variable sin
inicializar puede ser pasada como parmetro y el caller define un parmetro out en vez de
ref.
Valores en Parmetros out
Un parmetro out puede ser utilizado slo para contener el resultado de un mtodo, es
necesario especificar el modificador out para indicar el tipo de parmetro, a diferencia de
los parmetros ref el caller no necesita inicializar la variable antes de invocar el mtodo:
using System;

public class Param{
public void ParametroOut(out int OutParametro){
OutParametro = 4 * 4;
//No se gregresa un valor, porque es regresado en
el parmetro out
}
}

class Parametros{
public static void Main(){
Param MiParam = new Param();
int iValorOut; //No se requiere inicilizar el valor
MiParam.ParametroOut(out iValorOut); //Se invoca el mtodo
con un parmetro out
Console.WriteLine("out : " + iValorOut);//Resultado de la
invocacin del mtodo
}
}
Ejemplo de Parmetros In, Ref y Out
using System;

public class Param{
public int ParametroIn(int InParametro){
return InParametro * InParametro;
}

public void ParametroRef(ref int RefParametro){//No
regresa un valor explcito
RefParametro *= RefParametro; //Se modifica el
valor directamente
//No se regresa un valor, porque se modifico de
manera directa
}

public void ParametroOut(out int OutParametro){
OutParametro = 4 * 4;
//No se gregresa un valor, porque es regresado en
el parmetro out
}
}

class Parametros{
public static void Main(){
Param MiParam = new Param();

Console.WriteLine(" in : " + MiParam.ParametroIn(3));

int iValorRef = 5; //Se requiere inicializar el valor
MiParam.ParametroRef(ref iValorRef);//Se invoca el mtodo
pasando la referencia del valor
Console.WriteLine("ref : " + iValorRef);

int iValorOut; //No se requiere inicilizar el valor
MiParam.ParametroOut(out iValorOut); //Se invoca el mtodo
con un parmetro out

Console.WriteLine("out : " + iValorOut);//Resultado de la
invocacin del mtodo
}
}
Redefinicin de Mtodos (Overriding)
Uno de los principios bsicos de la programacin orientada a objetos es el polimorfismo, el
cual hace posible que una clase derivada pueda redefinir (override) mtodos de la clase
base. Para indicar que se puede redefinir el mtodo se emplea la palabra reservada
virtual:
virtual void NombreMetodo_PuedeSerRedefinido
Despus, al derivar de la clase base se agrega la palabra reservada override en el nuevo
mtodo:
override void NombreMetodo_PuedeSerRedefinido()
No es posible cambiar la accesibilidad de un mtodo que es redefinido, es decir, no es
posible cambiar los modificadores que definen al mtodo.
Cuando se invoca un mtodo virtual se est derivando el mtodo de clase que es
invocado y no el mtodo de la clase base:
((ClaseBase)InstanciaClaseDerivada).NombreMetodo_PuedeSerRedefinido();
Para indicar que una clase deriva de otra se utiliza el operador : el cual denota esta accin:
class ClaseDerivada : ClaseBase{}
El siguiente ejemplo muestra como se redefine un mtodo:
using System;
class ClaseBase{
public virtual int Calculo(int iA, int iB){
return iA + iB;
}
}

class ClaseDerivada : ClaseBase{//Se deriva de la clase base
public override int Calculo(int iA, int iB){//Se especifica que
el mtodo ser redefinido
return iA - iB;//Se redefine la funcionalidad del mtodo
}
}

class RedefinirMetodos{
public static void Main(){
ClaseBase ClsBase = new ClaseBase();
Console.WriteLine("Clase base : " +
ClsBase.Calculo(5,3));
//Se crea una instancia de la clase derivada:
ClaseDerivada ClsDer = new ClaseDerivada();
//Se invoca el mtodo redefinido en la clase
derivada:
Console.WriteLine("Clase derivada : " +
ClsDer.Calculo(5,3));
}
}
Ocultamiento de Mtodos (Hiding)
Es posible ocultar mtodos de la clase base, esto se logra haciendo uso de una caracterstica
especial de la redefinicin de mtodos llamada ocultamiento de mtodos y al derivar de la
clase base:
using System;

class ClaseBase{
//Sin cdigo
}

class ClaseDerivada : ClaseBase{//Clase derivada de la clase base
public void MetodoOculto(){//Mtodo Oculto
Console.WriteLine("Hiding Methods");
}
}

class Hiding{
public static void Main(){
ClaseDerivada MiClaseDerivada = new
ClaseDerivada();
MiClaseDerivada.MetodoOculto();
}
}
El cdigo anterior demuestra que es posible derivar una clase que implementa un mtodo
que la clase base no contiene.
Por otro lado si la clase base contiene el mtodo y se trata de derivar una clase que trata de
implemetar un mtodo que si contiene la clase, se produce un error:
using System;

class ClaseBase{
public void MetodoOculto(){
Console.WriteLine("Hiding Methods");
}
}

class ClaseDerivada : ClaseBase{//Clase derivada de la clase base
public void MetodoOculto(){//Se implementa un mtodo que
si existe
Console.WriteLine("Hiding Methods");
}
}

class Hiding{
public static void Main(){
ClaseDerivada MiClaseDerivada = new
ClaseDerivada();
MiClaseDerivada.MetodoOculto();
}
}
El compilador indicar un mensaje similar al siguiente:
Hiding.cs(10,14): warning CS0108: The keyword new is required on
'ClaseDerivada.MetodoOculto()'
because it hides inherited member
'ClaseBase.MetodoOculto()'
Hiding.cs(4,14): (Location of symbol related to previous warning)
El error principal es que no se hace uso del modificador new, ya que si es posible ocultar un
mtodo contenido en la clase base:
using System;

class ClaseBase{
public void MetodoOculto(){//Mtodo Oculto
Console.WriteLine("Hiding Methods");
}
}

class ClaseDerivada : ClaseBase{//Clase derivada de la clase base
new public void MetodoOculto(){//Mtodo Oculto
Console.WriteLine("Hiding Methods using new");
}
}

class HidingClassMet{
public static void Main(){
ClaseDerivada MiClaseDerivada = new
ClaseDerivada();
MiClaseDerivada.MetodoOculto();
}
}
Al hacer uso del modificador new, se le indica al compilador que se est redefiniendo el
mtodo de la clase base y que debera ocultar este mtodo.
Se puede asegurar de invocar el mtodo que redefine la clase derivada utilizando la
siguiente sintaxis:
((ClaseBase)MiClaseDerivada).MetodoOculto();
Propiedades
Las propiedades son convenientes para separar la interfaz de un objeto de su
implementacin, en vez de permitir a un usuario acceder directamente a un campo o
arreglo, una propiedad permite especificar a un conjunto de sentencias realizar el acceso
mientras se permita utilizar el campo o arreglo.
class NombreClase{

int iNombrePropiedad; //declaracin de la propiedad

//Especificacin del acceso a la propiedad
public int NombrePropiedad{
get{return iNombrePropiedad;}
set{iNombrePropiedad = value;}
}
}
Ejemplo:

using System;
class Propiedades{

private int iEdad;
public int Edad{
get{return iEdad;}
set{iEdad = value;}
}

private string sNombre;
public string Nombre{
get{return sNombre;}
set{sNombre = value;}
}

private bool bMexicano;
public bool Mexicano{
get{return bMexicano;}
set{bMexicano = value;}
}

public static void Main(){
Propiedades Ciudadano = new Propiedades();

Ciudadano.Edad = 33;
Console.WriteLine("Edad Ciudadano : " +
Ciudadano.Edad);

Ciudadano.Nombre = "Gerardo ngeles Nava";
Console.WriteLine("Nombre Ciudadano : " +
Ciudadano.Nombre);

Ciudadano.Mexicano = true;
Console.WriteLine("Mexicano Ciudadano : " +
Ciudadano.Mexicano);
}
}
Existen dos maneras de exponer el nombre de los atributos:
1. Campos (fields)
2. Propiedades (properties)
Los atributos son implementados como variables miembro con acceso pblico via
accessors (get o set).
Los accessors (get o set) especifican las sentencias que son ejecutadas cuando se requiere
leer o escribir el valor de una propiedad.
Los accessors para la lectura del valor de una propiedad son marcados con la palabra
reservada get y los accessors para modificar el valor de una propiedad son marcados con la
palabra reservada set.
El siguiente ejemplo muestra como se implentan los accessors para las propiedades:
using System;

class Persona{
private int iSueldo;
public int Sueldo{
get{return iSueldo;}
set{iSueldo = value;}
}
}

class AplicPersona{
public static void Main(){
Persona Empleado = new Persona();
Empleado.Sueldo = 33;
Console.WriteLine("Edad : " + Empleado.Sueldo);
}
}
Note, que se utiliza el parmetro value, ya que el valor actual es almacenado en este que es
accesible dentro de la clase.
Si en vez de utilizar propiedades desea utilizar campos deber dejar fuera los accessors y
redefinir la variable como:
public int Sueldo;
Accessors
Es posible ocultar los detalles de la estructura de almacenamiento de la clase reordenando
los accessors, en este caso el accessors set es pasado en el nuevo valor para la propiedad
en el parmetro value.
Las operaciones que pueden realizarse con los atributos son:
Implementar get y set, es posible tener acceso al valor de la propiedad para leerlo
y escribirlo.
get only, slo es posible leer el valor de la propiedad.
set only, slo es posible establecer el valor de la propiedad.
Propiedades Estticas
Propiedades estticas no pueden ser declaradas con los modificadores virtual, abstract
u override.
Las propiedades estticas pueden ser inicializadas hasta que sea necesario hacerlo, el valor
puede ser fabricado cuando se necesite sin almacenarlo.
using System;

class Persona{
int iPiernas;
int iBrazos;
int iOjos;
public Persona(int piernas, int brazos, int ojos){
this.iPiernas = piernas;
this.iBrazos = brazos;
this.iOjos = ojos;
}
public static Persona Piernas{
get{
return(new Persona(2,0,0));
}
}
public static Persona Brazos{
get{
return(new Persona(0,4,0));
}
}
public static Persona Ojos{
get{
return(new Persona(0,0,8));
}
}
}

class App{
public static void Main(){
Persona ET = Persona.Piernas;
Console.WriteLine(ET);
}
}
ndices
Es posible incluir una forma de acceso indexado a la clase tal como si la clase se tratar de
un arreglo, para ello se utiliza la caracterstica de C# indexer, sintaxis:
atributos modificadores declarador{instrucciones}
Los ndices o indexers regresan o establecen un string en un ndice dado, los indexers no
tienen atributos por lo que utilizan el modificador public.
La parte del declarador consiste del tipo string y la palabra reservada this para denotar el
indexer de la clase:
public string this[int iIndex]{
get{intrucciones}
set{intrucciones}
}
Las reglas de implementacin para get y set son las mismas reglas de las propiedades, la
nica diferencia es que la lista de parmetros se define libremente entre los corchetes,
tambin existen restricciones como que es necesario especificar al menos un parmetro y
los modificadores ref y out no estn permitidos.
Ejemplo:
using System;
using System.Net;//Directiva namespace para la clase DNS

class ResolverDNS{
IPAddress[] aIPs;
public void Resolver(string strHost){
IPHostEntry IPHE = Dns.GetHostByName(strHost);
aIPs = IPHE.AddressList;
}
public IPAddress this[int iIndex]{
get{return aIPs[iIndex];}
}
public int Contador{
get{return aIPs.Length;}
}
}

class AplicResolverDNS{
public static void Main(){
ResolverDNS MiDNS = new ResolverDNS();
MiDNS.Resolver("www.informatique.com.mx");

int iContador = MiDNS.Contador;
Console.WriteLine("Se encontro {0} para el host ",
iContador);
for(int i = 0; i < iContador; i++){
Console.WriteLine(MiDNS[i]);
}
}
}
Si el namespace para la clase DNS no est contenida en la biblioteca central, al compilar
incluya la referencia a la biblioteca que la contiene:
csc /r:System.Net.dll /out:resolver.exe AplicResolverDNS.cs
Los ndices pueden tener ms que un parmetro para simular un arreglo virtual
multidimensional.
Eventos
Una clase puede usar un evento para notificar a otra clase o clases que algo ocurrio, los
eventos usan el idioma "publish-subscribe", ya que una clase publica el evento que puede
lanzar y las clases que estn interesadas en un evento especfico pueden subscribir al
evento.
La rutina o tarea que un evento podra invocar es definida por un delegado.
Para tratar de manera fcil con eventos, la convencin de diseo para eventos es emplear
dos parmetros, donde el primer parmetro es el objeto que lanza el evento y el segundo
parmetro es un objeto que contiene la informacin acerca del evento el cual siempre deriva
de la clase EventArgs.
Los eventos pueden ser declarados como campos o propiedades de clase, ambos accesos
comparten la comodidad de tipo que el evento debe tener delegate.
Cada evento puede ser utilizado por cero o ms clientes y un cliente puede utilizar un
evento en cualquier momento.
Los delegados pueden ser implementados como mtodos o instancias estticas.
Modificadores
Los modificadores pueden clasificarse en:
Modificadores de Clase
Modificadores Miembro
Modificadores de Acceso
Modificadores de Clase
Existen dos tipos de modificadores de clase:
1. abstract
o Una clase abstracta no puede ser inicializada
o Slo clases derivadas que no son abstractas pueden ser inicializadas
o Las clases derivadas deben implementar todos los miembros abstractos de la
clase base abstracta
o No puede aplicarse un modificador sealed a una clase abstracta
2. sealed
o Clases sealed no pueden ser heredadas
o Utilice este modificador para prevenir herencia accidental
Ejemplo:
using System;

abstract class ClaseAbstracta{
abstract public void MiMetodo();
}

sealed class ClaseDerivada:ClaseAbstracta{
public override void MiMetodo(){
Console.WriteLine("Clase sealed");
}
}

public class ModificadorClase{
public static void Main(){
ClaseDerivada CD = new ClaseDerivada();
CD.MiMetodo();
}
}
Modificadores Miembro
Algunos modificadores miembro son:
abstract
o Indica que un mtodo o accessor no contiene una implementacin, que son
implicitamente virtual.
o La clase que recibe la herencia debe proveer la palabra reservada override.
const
o Este modificador aplica a campos y variables locales
o La expresin constante es evaluada en tiempo de compilacin, por lo tanto
no puede contener referencias de la clase.
event
o Define un campo o propiedad como tipo event
o Utilizado para ligar al cdigo cliente a eventos de la clase
extern
o Indica al compilador que el mtodo es implemetado externamente
override
o Utilizado para modificar un mtodo o accessor que es definido virtual en
cualquiera de las clases base
o La firma de redefinicin y mtodo base debe ser el mismo
readonly
o Un campo declarado con el modificador readonly puede ser cambiado slo
en su declaracin o en el constructor de la clase contenedora
static
o Miembros que son declarados static pertenecen a la clase y no a una
instancia de la clase
o Pueden utilizarse modificadores static con campos, mtodos, propiedades,
operadores y constructores.
virtual
o Indican que un mtodo o accessor pueden ser redefinidos por las clases que
reciben la herencia.
Modificadores de Acceso
Los modificadores de acceso definen el nivel de acceso que cierto cdigo tiene en los
miembros de la clase como mtodos y propiedades. Es necesario aplicar el modificador de
acceso deseado a cada miembro, de otra forma el tipo de acceso por default es implcito.
Los modificadores de acceso son:
public, el miembro es accesible desde cualquier parte, este modificador de acceso
es el menos restrictivo.
protected, el miembro es accesible en la clase y todas las clases derivadas. No es
permitido el acceso desde fuera.
El acceso protected permite a otras clases depender de la implementacin interna
de la clase y por lo tanto deberan ser otorgados slo cuando sea necesario.
private, slo el cdigo dentro de la misma clase puede acceder este miembro. Las
clases derivadas no pueden acceder al cdigo.
internal, este tipo de acceso es otorgado a todo el cdigo que es parte del mismo
componente (aplicacin o biblioteca) .NET, es visto como pblico a nivel del
componente .NET y privado fuera de este. Este modificador permite que un
miembro sea accesible desde las clases en el mismo ensamblaje, pero no desde las
clases fuera de este.
El modificador internal protected provee mayor flexibilidad en como una clase
es definida y se utiliza para indicar que un miembro pueder ser accedido desde una
clase internal o protected, en otras palabras internal protected permite
acceso internal o protected.
Sentencias de Control
Las Sentencias de Control se emplean para controlar la ejecucin y flujo del cdigo, las
cuales se dividen en:
1. Sentencias de Seleccin
2. Sentencias de Iteracin
Sentencias de Seleccin
Las Sentencias de seleccin son aquellas que se utilizan para realizar operaciones basadas
en el valor de una expresin.
Las Sentencias de seleccin son aquellas que se utilizan para escribir diferentes flujos de
accin en base a una condicin dada, existen dos tipos de sentencias de seleccin:
1. Sentencia if
2. Sentencia switch
Sentencia if
Al escribir uno o varios flujos de accin el cdigo contenido en estos se ejecutar siempre y
cuando la evaluacin de la expresin en la sentencia if se evalue como verdadera (tenga
cuidado en C# if(0){} o if(1){} no es vlido).
if(expresin-booleana){la expresin se evaluo verdadera}
Es posible indicar cdigo alterno en caso de que la expresin booleana se evalue falsa:
if(expresin-booleana){
la expresin se evaluo verdadera
}else{
la expresin se evaluo falsa

}
Nota C# no puede convertir valores numricos a booleanos, solo puede hacer
comparaciones entre ellos para evaluar el resultado de la expresin el cual es un valor
booleano.
using System;
class SeleccionIf{
public static void Main(){
if(1 == 1){
Console.WriteLine("se evaluo verdadero");
}
/* No es soportado por C#
if(0){
Console.WriteLine("?");
}
*/
}
}
Nota el operador de igualdad en C# es ==, si est habituado a otra forma, sera cosa tiempo
acostumbrarse a escribirlo correctamente, en la siguiente tabla se muestran los operadores
vlidos en C#:
Operador Evalua
== Verdadero, si ambos valores son los mismos
!=
Verdadero, si los valores son diferentes
<, <=, >, >= Verdadero, si el valor cumple con la condicin
Los operadores de la tabla son implementados via la sobrecarga de operadores y la
implementacin es especifica para el tipo de dato, si se comparan dos variables de diferente
tipo se realiza una conversin implcita que debe existir para que el compilador cree el
cdigo necesario automticamente. Recuerde que siempre podr realizar un cast explcito.
Ejemplo
using System;

class Caracteres{
public static void Main(){
string sNombre = "Gerardo Angeles Nava";

char chLetra = sNombre[0];//Extrae el primer
caracter del string

if(Char.IsDigit(chLetra)){
Console.WriteLine(chLetra + " es un
dgito");
}else{
EsMayuscula(chLetra);
EsMinuscula(chLetra);
}

chLetra = sNombre[1];//Extrae el segundo caracter
del string

if(Char.IsDigit(chLetra)){
Console.WriteLine(chLetra + " es un
dgito");
}else{
EsMayuscula(chLetra);
EsMinuscula(chLetra);
}

sNombre = "123";
chLetra = sNombre[2];//Extrae el tercer caracter
del string

if(Char.IsDigit(chLetra)){
Console.WriteLine(chLetra + " es un
dgito");
}else{
EsMayuscula(chLetra);
EsMinuscula(chLetra);
}
}
public static void EsMayuscula(char chCaracter){
if(chCaracter >= 'A' && chCaracter <= 'Z'){
Console.WriteLine(chCaracter + "
mayscula");
}
}
public static void EsMinuscula(char chCaracter){
if(chCaracter >= 'a' && chCaracter <= 'z'){
Console.WriteLine(chCaracter + "
minscula");
}
}
}
En el ejemplo anterior se muestra la aplicacin de la sentencia de seleccin if y el uso del
mtodo IsDigit de la clase Char, tambin se muestra como determinar si un caracter
correponde a las letras maysculas o minsculas.
Good Practice: nunca asigne valores a variables dentro de una condicin que utiliza
operadores lgicos (&&,||,!), porque puede que nunca se le asigne el valor correspondiente
a la variable en caso de que una expresin anterior se evalue verdadera:
if(a == b || (c == (iValor = d))){}
En el ejemplo anterior, si la expresin a == b se evalua verdadera entonces la variable
iValor nunca contendr el valor d.
Sentencia switch
La sentencia de seleccin switch tiene una expresin de control y los flujos de cdigo
alternos son ejecutados dependiendo del valor constante asociado con esta expresin.
switch(expresion-de-control){
case expresion-contante:
sentencias;
break;
case expresion-contante:
goto case 2;
case expresion-contante:
goto default;
default:
sentencias;
}
Los tipos de datos permitidos para la expresin de control son sbyte, byte, short, ushort,
uint, long, ulong, char, string o un tipo enumeracin (enumeration).
Cmo funciona la sentencia de seleccin switch?
Se evalua la expresin de control
Si la expresin constante en las etiquetas case coincide con el valor evaluado en la
expresin de control, entonces las sentencias contenidas para ese caso son
ejecutadas
Si la expresin constante en las etiquetas case no coincide con el valor evaluado en
la expresin de control, entonces el cdigo contenido en el caso por default es
ejecutado
Si la expresin constante en las etiquetas case no coincide con el valor evaluado en
la expresin de control y no existe un caso por default, entonces el control es
transferido al final del bloque switch
Ejemplo:
using System;

class SentenciaSwitch{
public static void Main(){
for(int i = 0; i <= 12; i++){
Mes(i);
}
}
public static void Mes(int iMes){
switch(iMes){
case 1:
Console.WriteLine("Enero");
break;
case 2:
Console.WriteLine("Febrero");
break;
case 3:
Console.WriteLine("Marzo");
break;
case 4:
Console.WriteLine("Abril");
break;
case 5:
Console.WriteLine("Mayo");
break;
case 6:
Console.WriteLine("Junio");
break;
case 7:
Console.WriteLine("Julio");
break;
case 8:
Console.WriteLine("Agosto");
break;
case 9:
Console.WriteLine("Septiembre");
break;
case 10:
Console.WriteLine("Octubre");
break;
case 11:
Console.WriteLine("Noviembre");
break;
case 12:
Console.WriteLine("Diciembre");
break;
default:
Console.WriteLine("Mes no vlido");
break;
}
}
}
Es posible utilizar sentencias goto dentro del switch de la siguiente manera:
goto case expresion-contante
goto default
Ejemplo:
using System;

class SentenciaSwitch{
public static void Main(){
int iOpcion = 4;
Opcion(iOpcion);
iOpcion = 2;
Opcion(iOpcion);
iOpcion = 8;
Opcion(iOpcion);
iOpcion = 10;
Opcion(iOpcion);
}
public static void Opcion(int iValor){
switch(iValor){
case 2:
goto case 6;
case 4:
Console.WriteLine(" cuatro");
break;
case 6:
Console.WriteLine(" seis");
break;
case 8:
goto default;
case 10:
Console.WriteLine(" diez");
break;
default:
Console.WriteLine(" por defecto");
break;
}
}
}
Sentencias de Iteracin (repeticin)
Las Sentencias de Iteracin (tambin conocidas como looping statements) son aquellas
que nos permiten ejecutar un bloque de cdigo repetidamente mientras una condicon
especfica sea verdadera:
for
foreach
while
do
Sentencia for
La Sentencia for se utiliza cuando se conoce previamente cuantas veces ha de repetirse un
bloque de cdigo. Este bloque se repetira mientras la condicin evalue una expresin
booleana verdadera, no ser posible evaluar otro tipo de expresin.
Sintaxis:
for(inicializador; condicin; iterador)
Los componentes de la sentencia for: inicializador, condicin, iterador, no son
obligatorios.
Es posible salir de un ciclo for a travs de las instrucciones:
1. break
2. goto
Ejemplo:
using System;

class Factorial{
public static void Main(string[] aArgs){
if(aArgs.Length == 0){
Console.WriteLine("Debe proporcionar un argumento,
Ejemplo: Factorial 5");
return;
}

long lFactorial = 1;
long lCalcular = Int64.Parse(aArgs[0]);

long lAux = 1;
for(lAux = 1; lAux <= lCalcular; lAux++){
lFactorial *= lAux;
//Test Line Console.WriteLine("{0}! * {1}", lAux,
lFactorial);
}
Console.WriteLine("{0}! es {1}", lCalcular, lFactorial);
}
}
Sentencia foreach
La Sentencia foreach es un comando para enumerar los elementos de una coleccin.
foreach(Tipo indentificador in expresin){}
La variable de iteracin es declarada por el Tipo, indentificador y expresin
correspondiente a la coleccin.
La variable de iteracin representa el elemento de la coleccin para cada iteracin.
El siguiente ejemplo muestra el uso de for:
using System;
class App{
public static void Main(string[] aArgs){
for(int i = 0; i < aArgs.Length; i++){
Console.WriteLine("Elemento " + i + " = " +
aArgs[i]);
}
}
}
El ejemplo anterior implementado con foreach:
using System;
class App{
public static void Main(string[] aArgs){
foreach(String s in aArgs){
Console.WriteLine(s);
}
}
}
No es posible asignar un nuevo valor a la variable de iteracin. No se puede pasar la
variable de iteracin como un parmetro ref o out.
Para que una clase soporte la sentencia foreach, la clase debe soportar un mtodo con la
firma GetEnumerator() y la estructura, clase o interface que regresa debe tener un mtodo
pblico MoveNext y una propiedad pblica Current.
En el siguiente ejemplo el mtodo GetEnvironmentVariables() regresa una interfaz de
tipo IDictionary. Es posible acceder a las colecciones Keys y Values de la interfaz
IDictionary:
using System;
using System.Collections;

class SentenciaForEach{
public static void Main(){
IDictionary VarsAmb =
Environment.GetEnvironmentVariables();
Console.WriteLine("Existen {0} variables de ambiente
declaradas", VarsAmb.Keys.Count);
foreach(String strIterador in VarsAmb.Keys){
Console.WriteLine("{0} = {1}", strIterador,
VarsAmb[strIterador].ToString());
}
}
}
Nota, es necesario tener una precaucin extra al decidir el tipo de variable de iteracin,
porque un tipo equivocado no puede ser detectado por el compilador, pero si detectado en
tiempo de ejecucin y causar una excepcin.
Sentencia while
La Sentencia while se utiliza cuando no se conoce previamente cuantas veces ha de
repetirse un bloque de cdigo, por lo que puede ejecutarse 0 o ms veces. Este bloque se
repetira mientras la condicin evalue una expresin booleana verdadera, no ser posible
evaluar otro tipo de expresin.
while(condicional){}
Ejemplo:
using System;
using System.IO;

class SentenciaWhile{
public static void Main(){
if(!File.Exists("test.html")){
Console.WriteLine("El archivo test.html no
existe");
return;
}
StreamReader SR = File.OpenText("test.html");
String strLinea = null;
while(null != (strLinea = SR.ReadLine())){
Console.WriteLine(strLinea);
}
SR.Close();
}
}
Es posible utilizar la sentencia break para salir del ciclo o continue para saltar una
iteracin.
Sentencia do
La diferencia entre la sentencia while y do es que do se evalua despus de su primer
iteracin, por lo que al menos siempre se ejecuta una vez:

do{
sentencias;
}while(condicin);
Es posible salir de un ciclo do a travs de la sentencia break y es posible saltar una
iteracin utilizando la sentencia continue
El siguiente ejemplo le la entrada de la consola toma el primer caracter leido, lo convierte
en un Tipo double y suma su valor mientras la entrada sea 's' o hasta que la entrada sea 'n'.
using System;

class Consola{
public static void Main(){
Consola LeerDatos = new Consola();
LeerDatos.Run();
}
public void Run(){
char chContinuar = 's';
string strDatos;
double dSuma = 0;
do{
Console.Write("Proporcione un nmero: ");
strDatos = Console.ReadLine();
dSuma += Double.Parse(strDatos);

Console.Write("Continuar s/n?");
strDatos = Console.ReadLine();
chContinuar = strDatos[0];
if(chContinuar == 'n') break;
}while(chContinuar == 's');
Console.WriteLine("La suma de los nmeros es: " +
dSuma);
}
}
Sentencias de Salto
Las Sentencias de Salto como break, continue, goto y return sirven para ir de una
sentencia a otra
break
La Sentencia break es utilizada para salir de la iteracin en curso o sentencia switch y
continuar con la ejecucin despus de esa sentencia.
continue
La Sentencia continue salta todas las sentencias siguientes en la iteracin en curso y
entonces continua la ejecucin en la sentencia de iteracin (siguiente iteracin).
goto
La Sentencia goto puede ser utilizada para saltar directamente a una etiqueta. Una
sentencia goto no puede ser utilizada para saltar adentro de un bloque de sentencias. Su uso
podra ser empleado en sentencias switch o para transferir el control fuera de un loop
anidado.
Nota, como buena prctica no se recomienda el uso de goto.
return
La Sentencia return regresa a la funcin invocadora y opcionalmente retorna un valor.
Asignacin Definitiva
Las reglas de Asignacin definitiva previenen la observacin del valor de una variable no
asignada, ya que C# no permite utilizar variables que no han sido inicializadas, as como
tambin no pueden realizarse operaciones con variables de clase que no han sido
inicializadas.
Puede accederse al elemento de un arreglo an si no ha sido inicializado, ya que el
compilador no puede rastrear la asignacin definitiva en todas las situcaciones.
Precedencia de Operadores
Cuando una expresin contiene mltiples operadores, la precedencia de operadores controla
el orden en el cual los elementos de la expresin son evaluados.
Categora Operador
Primary
(x), x.y, f(x), a[x], x++, x--, new, typeof, sizeof,
checked, unchecked
Unary
+, -, !, ~, ++x, --x, (T)x
Multiplicative *, /, %
Additive
+, -
Shift <<, >>
Relational
<, >, <=, >=, is
Equality ==, !=
Logical AND
&
Logical XOR ^
Logical OR
|
Conditional
AND
&&
Conditional OR
||
Conditional ?:
Assignment
=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
typeof
El operador typeof regresa el tipo del objeto, el cual es una instancia de la clase
System.Type
Una instancia ya existente puede obtener el tipo de objeto con el mtodo de la instancia
GetType().
is
El operador is es utilizado para determinar cuando una referencia a un objeto puede ser
converitda a un tipo especfico o interface.
El operador as es muy similar al operador is, pero en vez de determinar cuando un objeto
es un tipo especfico o interface, as tambin realiza la conversin explicita a ese tipo o
interface y si no lo puede convertir el operador regresa null.
Utilizar as es ms eficiente que utilizar is, porque as slo necesita checar el tipo del objeto
una vez e is checa el tipo cuando el operador es utilizado y lo checa otra vez cuando la
conversin se realiza.
Utilizando is
if(UnObjeto is UnTipo){
UnTipo ut = (UnTipo) UnObjeto;
}
Utilizando as
UnTipo ut = UnObjeto as UnTipo;
if(ut != null){
sentencias;
}

Conversiones
En C# las conversiones se dividen en conversiones explcitas y conversiones implcitas que
son aquellas que podran siempre ocurrir:
//conversiones implcitas
sbyte a = 55;
short b = a;
int c = b;
long d = c;

//conversiones explcitas
c = (int) d;
b = (short) c;
a = (sbyte) b;
A continuacin se presenta la jerarqua de conversin en C##
Manejo de Excepciones
Las excepciones son el mtodo fundamental de manejo de condiciones de error.
Ejemplo:

using System;
class DivisionCero{
public static void Main(){
int iA = 33;
int iB = 0;
try{
//Sentencia que puede lanzar una excepcin
Console.WriteLine("{0}/{1} = {2}", iA ,iB, iA/iB);
}catch(Exception e){
//Manejo de la excepcin
Console.WriteLine("La operacin {0}/{1} genero la
excepcion : {2}", iA, iB, e);
}
Console.WriteLine("Continua la ejecucin del cdigo...");
}
}
El ejemplo encierra el bloque de cdigo que podra lanzar una excepcin con try. En caso
de generarse una excepcin el runtime .NET detiene la ejecucin del cdigo y busca el
bloque try en el cual la excepcin tuvo lugar, entonces busca si este bloque tiene
relacionado un bloque catch, puede ser que encuentre ms de un bloque catch relacionado
al bloque try que genero la excepcin, por lo que se determina que bloque catch es el que
mejor y ejecuta el cdigo que contiene.
El compilador de C# puede manejar silenciosamente situaciones que podran producir un
error sin notificarnos explicitamente de ello, por ejemplo una situacin como un overflow
que es cuando el clculo de una operacin excede el rango vlido de resultados posibles
para el tipo de dato.
El caso del cdigo para calcular un factorial, el compilador no prodruce una advertencia,
pero si trata de obtener el factorial de 2000 dara por resultado 0, el compilador actuo en
modo silencioso porque por default el compilador tiene deshabilitada la opcin de chequeo
de overflow.
Es posible cambiar el comportamiento de chequeo de overflow utilizando un switch al
compilar.
Jerarqua de Excepciones
Todas las excepciones derivan de la clase Exception, la cual es parte del lenguaje comn
en tiempo de ejecucin (CLR), donde la propiedad catch determina por coincidencia el
tipo de excepcin a el nombre de la excepcin generada. Un bloque catch con una
coincidencia especifica hacen ms general la excepcin:
using System;
class ExceptionDivision0{
public static void Main(){
int iA = 33;
int iB = 0;
try{
Console.WriteLine("{0}/{1} = {2}", iA ,iB,
iA/iB);
}catch(DivideByZeroException){
Console.WriteLine("Se genero la excepcion :
DivideByZeroException");
}
Console.WriteLine("Continua la ejecucin del
cdigo...");
}
}
En este ejemplo el bloque catch que atrapa la excepcin DivideByZeroException es una
coincidencia ms especfica, por lo que es la nica que ser ejecutada, pero si adems de
escribir el catch para DivideByZeroException escribe el catch para Exception, el
compilador le notificara que existe una excepcin que atrapa todas las excepciones y esto es
porque Exception ocupa la cima de la jerarqua de todas las excepciones.
Trabajar con Excepciones
Existen tres formas bsicas de trabajar con excepciones:
Caller Beware
La primer forma es no atrapar la excepcin, lo cual provocar dejar al objeto en un estado
incorrecto, y causar daos cuando el caller trate de utilizarla de nuevo.
Caller Confuse
La segunda forma es atrapar la excepcin y tratar de hacer acciones que dejen la operacin
como estaba hasta antes de generarse la excepcin y entonces relanzar la excepcin, esto
usualmente es lo menos que se esperaria del manejo de excepciones ya que un objeto
debera siempre mantener un estado vlido despus de generarse una excepcin.
Se llama Caller Confuse, porque despus de generase una excepcin, el caller con
frecuencia tiene poca informacin respecto al entendimiento de los detalles de la excepcin
o como podra ser solucionada.
Caller Inform
Las tercer forma Caller Inform agrega informacin que es devuelta al usuario, la excepcin
atrapada es envuelta en una excepcin que tiene informacin adicional:
using System;
class ExcDivZeroInf{
public static void Main(){
int iA = 33;
int iB = 0;
try{
Console.WriteLine("{0}/{1} = {2}", iA ,iB,
iA/iB);
}catch(DivideByZeroException e){
Console.WriteLine("Se genero la excepcion :
DivideByZeroException");
throw(new
DivideByZeroException("Informacin adicional...", e));
}
Console.WriteLine("Continua la ejecucin del
cdigo...");
}
}
Chequeo de Overflow
Si requerimos controlar el chequeo de overflow para la aplicacin completa, el compilador
de C# debe establecerse como checked. Por default el compilador tiene deshabilitada la
opcin de chequeo.
Para indicar explicitamente que el compilador cheque el overflow escriba:
csc Factorial.cs /checked+
Una vez que se compilo de con la opcin de chequeo de overflow habilitado, al intentar
obtener el factorial de 2000 de presenta la ventana Just-In-Time-debbuging
notificandonos que ocurrio una excepcin en Factorial.exe:
System.OverflowException
Este tipo de situaciones es posible atraparlas y manejarlas a travs de las excepciones que
se producen.
Chequeo programtico de Overflow
Existe otra opcin si es que no deseamos activar el Chequeo de Overflow para la aplicacin
completa y habilitar slamente partes especificas de cdigo, para ello se utiliza la sentencia
checked:
using System;

class FactorialChecked{
public static void Main(string[] aArgs){
if(aArgs.Length == 0){
Console.WriteLine("Debe proporcionar un argumento,
Ejemplo: Factorial 5");
return;
}

long lFactorial = 1;
long lCalcular = Int64.Parse(aArgs[0]);

long lAux = 1;
for(lAux = 1; lAux <= lCalcular; lAux++){
checked{lFactorial *= lAux;} //Habilitar chequeo
de overflow
//Test Line Console.WriteLine("{0}! * {1}", lAux,
lFactorial);
}
Console.WriteLine("{0}! es {1}", lCalcular, lFactorial);
}
}
Tambin es posible hacer el caso contrario, es decir, indicar que no se realice el chequeo de
overflow para partes especificas de cdigo, para ello se utiliza la sentencia:
unchecked{sentencias;}
Sentencias para el Manejo de Excepciones
Es posible atrapar, manejar y limpiar las excepciones que se producen utilizando las
sentencias siguientes:
try - catch
try - finally
try - catch - finally
try - catch
Para evitar que se muestre el mensaje que indica que una excepcin ocurrio, es necesario
atrapar la excepcin y lo mejor de todo es que continue la ejecucin del programa, para
ello se utiliza try y catch.
try contiene el cdigo que quiz pueda lanzar una excepcin y catch maneja la excepcin
si esta ocurre:
try{
//sentencias que pueden lanzar una excepcin
}catch(nombreExcepcin){
//manejo de la excepcin
}
El siguiente ejemplo maneja la excepcin FileNotFoundException que se produce cuando
se intenta manipular un archivo que no existe, si esto ocurre se presenta un mensaje que
muestra el nombre del archivo que se intento manipular y no se encontro a travs de una
propiedad pblica de la excepcin llamada FileName.
using System;
using System.IO;

class SentenciaWhile{
public static void Main(){
try{
StreamReader SR =
File.OpenText("test.html");
String strLinea = null;
while(null != (strLinea = SR.ReadLine())){
Console.WriteLine(strLinea);
}
SR.Close();
}catch(FileNotFoundException e){//En caso de que
el archivo no exista
Console.WriteLine("No se encontro el
archivo : " + e.FileName);
return;
}
}
}
try - finally
Es posible limpiar el manejo de errores utilizando try y el constructor finally, sin
eliminar el mensaje de error, pero el cdigo contenido en el bloque finally es ejecutado
an despus de ocurrir una excepcin.
El siguiente cdigo maneja una variable booleana que indica si se produjo un error,
simplemente poniendola dentro del bloque try, si el cdigo contenido fu ejecutado la
variable booleana es false lo cual indica que no ocurrieron excepciones, si el bloque no se
ejecuto la variable booleana mantiene su valor inicial lo cual significa que si ocurrieron
excepciones y entonces se ejecuta el bloque Finally el cual evalua el valor de la variable
booleana y presenta la indicacin correspondiente.
using System;
using System.IO;

class SentenciaTryFinally{
public static void Main(){
bool bExcepcion = true;
try{
StreamReader SR =
File.OpenText("test.html");
String strLinea = null;
while(null != (strLinea = SR.ReadLine())){
Console.WriteLine(strLinea);
}
SR.Close();
bExcepcion = false;
}
finally{
if(bExcepcion){
Console.WriteLine(">>> No se
encontro el archivo");
}else{
Console.WriteLine(">>> No
ocurrieron excepciones");
}
}
}
}
Note que en caso de no existir el archivo se produce una excepcin y se presenta el mensaje
que indica que ha ocurrido una excepcin pero tambin fu ejecutado el bloque finally, el
cdigo que contiene el bloque finally siempre es ejecutado ocurra o no una excepcin.
Puede emplear la sentencia finally para reestablecer los valores previos a la generacin
de la excepcin.
try - catch - finally
Combinar try para controlar el cdigo que puede lanzar excepciones, atrapar la excepcin
con catch y llevar acabo instrucciones necesarias con finally hacen una mejor solucin
cuando ocurren las excepciones.
Es posible utilizar una sentencia catch por cualquier excepcin que pudiera ocurrir, es
decir, tener ms de un bloque catch, pero es necesario conocer la jerarqua de las
excepciones porque puede ocurrir que un bloque previo catch sea ms general y contenga
todas las excepciones lo cual produciria un error.
using System;
using System.IO;

class SentenciaTryCatchFinally{
public static void Main(){
bool bExcepcion = true;
bool bModificacion = false;
try{
bModificacion = true;
StreamReader SR = File.OpenText("test.htmlX");
String strLinea = null;
while(null != (strLinea = SR.ReadLine())){
Console.WriteLine(strLinea);
}
SR.Close();
bExcepcion = false;
}catch(FileNotFoundException e){//En caso de que el
archivo no exista
Console.WriteLine("No se encontro el archivo : " +
e.FileName);
return;
}
finally{
if(bExcepcion){
bModificacion = false;//Valor antes de
generarse la excepcin
if(!bModificacion){
Console.WriteLine("Entro en modo
modificacin, _
pero las modificaciones no se
realizaron");
}
Console.WriteLine("Causa : No se encontro
el archivo");
}else{
Console.WriteLine("No ocurrieron
excepciones");
}
}
}
}
Lanzamiento de Excepciones
Para atrapar una excepcin con la sentencia catch primero debe generarse la excepcin,
pero es posible que a travs de codigo se lanze o invoque una excepcin:
throw new NombreExcepcion(excepcion);
El poder lanzar o invocar una excepcin es util cuando no se ha contemplado cierto
escenario o para nuevos escenarios, al crear una clase podrian crearse tambin excepciones
propias de esta clase.
A continuacin se presenta una tabla que contiene las excepciones estndar que provee el
runtime:
Tipo Descripcin
Exception
Clase base para todas los objetos exception
SystemException
Clase base para todos los errores generados en
tiempo de ejecucin
IndexOutRangeException
Lanzada en tiempo de ejecucin cuando el
ndice de un arreglo est fuera de rango
NullreferenceException
Disparada en tiempo de ejecucin cuando un
objeto null es referenciado
InvalidOperationException
Lanzada por ciertos mtodos cuando invocan a
mtodos que son invlidos para el estado de los
objetos actuales
ArgumentException
Clase base de todos los argumentos de las
excepciones
ArgumentNullException
Lanzada por un mtodo, en caso de que un
argumento sea null cuando no sea permitido
ArgumentOutOfRangeException
Lanzada por un mtodo cuando un argumento
no est en el rango permitido
InteropException
Clase base para excepciones que son originadas
u ocurren en ambientes fuera del CLR
ComException Excepcin que contiene informacin
HRESULT COM
SEHException
Excepcin que encapsula informacin del
manejo de excepciones destructurada Win32
Relanzamiento de Excepciones
El siguiente cdigo muestra como es posible atrapar una excepcin, manejarla y se volverla
a invocar:
using System;

class FactorialCheckedReThrow{
public static void Main(string[] aArgs){
if(aArgs.Length == 0){
Console.WriteLine("Debe proporcionar un argumento,
Ejemplo: Factorial 5");
return;
}

long lFactorial = 1;
long lCalcular = Int64.Parse(aArgs[0]);

long lAux = 1;

try{
checked{ //Habilitar chequeo de overflow
for(lAux = 1; lAux <= lCalcular; lAux++){
lFactorial *= lAux;
//Test Line Console.WriteLine("{0}! * {1}",
lAux, lFactorial);
}
}
}catch(OverflowException){
Console.WriteLine("El factorial {0}! causo una excepcin",
lCalcular);
throw;
}
Console.WriteLine("{0}! es {1}", lCalcular, lFactorial);
}
}

Creacin de Clases Exception
Es recomendable utilizar las clases predefinidas para excepciones, para ciertos escenarios
es posible crear clases de excepciones apropiadas, por ejemplo cuando creamos una clase,
tambin podemos crear excepciones para esta clase, esto es conveniente cuando se utiliza la
clase y manejar posibles escenarios de error con las clases de excepciones creadas.
using System;

public class MiExcepcion:Exception{
public MiExcepcion(string str):base(str){}
}

public class AplicMisExcepciones{
public static void Probar(){
throw new MiExcepcion("ocurrio un error");
}
public static void Main(){
try{
AplicMisExcepciones.Probar();
}catch(Exception e){
Console.WriteLine(e);
}
}
}
Se deben tomar ciertas consideraciones al crear excepciones:
Al lanzar una excepcin se debe proporcionar un texto significativo
Lanzar excepciones solo cuando se presente una condicin realmente excepcional
Lanzar un ArgumentException si el mtodo o propiedad envio mal los parmetros
Lanzar un InvalidOperationException cuando la operacin invocada no es
apropiada para el estado actual de los objetos
Lanzar la excepcin ms apropiada
Usar excepciones encadenadas
No utilizar excepciones para errores esperados o normales
No usar excepciones para control o flujo normal
No lanzar NullReferenceException o IndexOutOfRangeException en mtodos
Componentes
As como es posible escribir clases y hacer uso de estas en un mismo archivo, tambin es
posible escribir en un archivo (ejecutable) unicamente la clase lo cual es conocido como
componente y en otro archivo (tambin ejecutable) el uso de la clase lo cual es conocido
como cliente.
Creacin de Componentes
Para crear un componente unicamente es necesario escribir la Clase con todos sus
miembros (Constructores, Propiedades, Mtodos), almacenarla en un archivo y compilar el
componente.
using System;

public class ClsPersona{
private int iSueldo;
public int Sueldo{
get{return iSueldo;}
set{iSueldo = value;}
}

public string sNombre;
public void AsignarNombre(string sValor){
sNombre = sValor;
}
public string ObtenerNombre(){
return sNombre;
}
}
Compilacin de Componentes
Al compilar un componente se crea una biblioteca y no se crea una aplicacin, como es el
caso cuando se trabaja en un slo archivo la clase y la aplicacin que hace uso de la clase:
csc /t:library /out:ClsPersona.dll ClsPersona.cs
Si utiliza nombres de espacio:
csc /r:System.nombreBiblioteca.dll /t:library /out:NombreComponente.dll
NombreComponente.cs
Donde el switch /t:library indica al compilador de C# crear una biblioteca y no buscar el
mtodo esttico Main.
Si su clase requirio de nombres de espacio (namespace) es necesario hacer referencia a
estas bibliotecas mediante el switch /r:NombreBiblioteca.dll
Recuerde que el switch /out no es obligatorio ya que se utiliza para especificar un nombre
distinto al nombre del archivo fuente, aunque es buena prctica especificarlo ya que algunas
aplicaciones no slo tienen un archivo fuente, entonces el compilador podra llamar a la
biblioteca con el primer nombre de archivo fuente en la lista.
Una vez que ha compilado su componente puede escribir una Aplicacin Cliente.
Creacin de una Aplicacin Cliente
Para hacer uso de los componentes creados es posible crear aplicaciones cliente donde se
creen instancias de las clases creadas:
using System;

class AplicClsPersona{
public static void Main(){
ClsPersona Empleado = new ClsPersona();
Empleado.Sueldo = 33;
Console.WriteLine("Edad : " + Empleado.Sueldo);

Empleado.AsignarNombre("Gerardo ngeles Nava");
Console.WriteLine("Nombre : " +
Empleado.ObtenerNombre());
}
}
Compilacin de Clientes
Es necesario indicarle al compilador una referencia a la nueva biblioteca de componentes
DLL:
csc /r:NombreComponente.dll NombreCliente.cs
Nota para hacer uso de una clase es necesario que tenga el modificador de acceso public.
Namespaces
Los nombres de espacio namespace en el runtime .NET son utilizados para organizar las
clases y otros tipos en una estructura jerarquica. El propsito del uso de namespace hacen
las clases fciles de usar y prevenir colisiones con las clases escritas por otros
programadores.
Los namespace en C# se utilizan para organizar programas y la jerarqua natural de la
organizacin facilita presentar los elementos de un programa a otros programas. Los
namespace son utiles para la organizacin interna de aplicaciones.
Un namespace contiene tipos que pueden ser utilizados en la construccin de programas:
clases, estructuras, enumeraciones, delegados e interfaces, por ejemplo para poder escribir a
la consola se utiliza el namespace System.
No es obligatorio jerarquizar los namespace pero es una buena prctica organizar los
namespace creados de manera jerarquica para dar claridad a la aplicacin.
Los nombres de espacio son definidos utilizando la sentencia:
namespace
Para mltiples niveles de organizacin los namespaces pueden ser anidados:
namespace NombreNamespaceA{
namespace NombreNamespaceB{
class NombreClase{
public static void Function(){}
}
}
}
El cdigo anterior puede ser simplificado de la siguiente manera:
namespace NombreNamespaceA.NombreNamespaceB{
class NombreClase{
public static void Function(){}
}
}
Las colisiones entre tipos o nombres de espacio que tienen el mismo nombre se pueden
resolver utilizando una variante de la clusula using que permite definir un alias para la
clase:
using Alias = System.Console;
class NombreClase{
public static void Main(){
Alias.WriteLine("Alias de una clase");
}
}
Envolver Clases en Namespace
Es posible envolver (wrapping) las clases en un namespace, para ello slo es necesario
utilizar la palabra reservada namespace seguida de un nombre que lo identifique y encerrar
entre llaves el cdigo que deseamos pertenezca a este.
using NombreOtrosEspacios;
namespace NombreEspacio{
public class NombreClase{
//propiedades
//mtodos
}
}
Ejemplo:

using System;

namespace informatique.com.mx{
public class iPersona{
private int iSueldo;
public int Sueldo{
get{return iSueldo;}
set{iSueldo = value;}
}

public string sNombre;
public void AsignarNombre(string sValor){
sNombre = sValor;
}
public string ObtenerNombre(){
return sNombre;
}
}
}
Compilar:
csc /t:library /out:iPersona.dll iPersona.cs
Utilizar Namespace en Aplicaciones Cliente
Al desarrollar componentes utilizando namespace la aplicacin cliente debe importarlo:
using NombreEspacio;
Otra posibilidad es hacer una referencia absoluta a los elementos del namespace, aunque
para evitar conflictos es preferible utilizar la directiva:
Ejemplo:
using System;
using informatique.com.mx;

class iAplicClsPersona{
public static void Main(){
iPersona Empleado = new iPersona();
Empleado.Sueldo = 33;
Console.WriteLine("Edad : " + Empleado.Sueldo);

Empleado.AsignarNombre("Gerardo ngeles Nava");
Console.WriteLine("Nombre : " +
Empleado.ObtenerNombre());
}
}
Compilar:
csc /r:iPersona.dll iAplicPersona.cs
Especificar de manera absoluta el namespace:
using System;

class iAplicClsPersonaAbs{
public static void Main(){
informatique.com.mx.iPersona Empleado = new
informatique.com.mx.iPersona();
Empleado.Sueldo = 33;
Console.WriteLine("Edad : " + Empleado.Sueldo);

Empleado.AsignarNombre("Gerardo ngeles Nava");
Console.WriteLine("Nombre : " +
Empleado.ObtenerNombre());
}
}
Compilar:
csc /r:iPersonaAbs.dll iAplicPersonaAbs.cs
Agregar Mltiples Clases a Un Namespace
En el punto anterior envolvimos una clase a un namespace, pero es posible agregar y
envolver ms clases o componentes al mismo namespace, sin importar que esten
contenidos en diferentes archivos, despus de la compilacin son parte del mismo
namespace:
csc /t:library /out:NombreComponente.dll archivoFuente1.cs
archivoFuente2.cs
Agregando otra clase al namespace informatique.com.mx:
using System;

namespace informatique.com.mx{
class iVehiculo{
private int iRueda;
private int iPuerta;
private int iVentana;
private int iHelice;
private int iMotor;
private int iAsiento;
private string sTipo;//Aereo, anfibio, terrestre,
espacial
//Constructor
public iVehiculo(int Rueda, int Puerta, int
Ventana, _
int Helice, int Motor, int Asiento, string Tipo){
iRueda = Rueda;
iPuerta = Puerta;
iVentana = Ventana;
iHelice = Helice;
iMotor = Motor;
iAsiento = Asiento;
sTipo = Tipo;
}

public int Ruedas{
get{return iRueda;}
set{iRueda = value;}
}

public int Puertas{
get{return iPuerta;}
set{iPuerta = value;}
}

public int Ventanas{
get{return iVentana;}
set{iVentana = value;}
}

public int Helices{
get{return iHelice;}
set{iHelice = value;}
}

public int Motores{
get{return iMotor;}
set{iMotor = value;}
}

public int Asientos{
get{return iAsiento;}
set{iAsiento = value;}
}

public string Tipo{
get{return sTipo;}
set{sTipo = value;}
}
}
}
Compilar:
csc /t:library /out:informatique.com.mx.dll iPersona.cs iVehiculo.cs
Aplicacin Cliente:
using System;
using informatique.com.mx;
class iAplic{
public static void Main(){
iPersona Empleado = new iPersona();
Empleado.Sueldo = 33;
Console.WriteLine("Edad : " + Empleado.Sueldo);

Empleado.AsignarNombre("Gerardo ngeles Nava");
Console.WriteLine("Nombre : " +
Empleado.ObtenerNombre());

//Clase que est contenida en otro archivo
iVehiculo MiAvion = new
iVehiculo(2,1,100,0,3,200,"Aereo");
Console.WriteLine("Ruedas : " + MiAvion.Ruedas);
Console.WriteLine("Puertas : " +
MiAvion.Puertas);
Console.WriteLine("Ventanas : " +
MiAvion.Ventanas);
Console.WriteLine("Helices : " +
MiAvion.Helices);
Console.WriteLine("Motores : " +
MiAvion.Motores);
Console.WriteLine("Asientos : " +
MiAvion.Asientos);
Console.WriteLine("Tipo : " + MiAvion.Tipo);
}
}
Compilar:
csc /r:informatique.com.mx.dll iAplic.cs
Recuerde que sus clases deben tener el modificador de acceso public, de lo contrario el
compilador notificara un error (error CS0122: is inaccessible due to its protection level),
por lo que tendr que agregar el modificador de acceso y volver a compilar.
Namespace y Ensambles
Un objeto puede ser utilizado desde un archivo fuente C# slo si ese objeto puede ser
localizado por el compilador C#, por default el compilador slo abre el ensamble conocido
como mscorlib.dll, el cual contiene las funciones principales para el CLR.
Para referenciar objetos localizados en otros ensambles, el nombre del archivo de ensamble
debe ser pasado al compilador, esto es posible utilizando un switch al compilar:
/r:nombreEnsamble
Es as como se crea un correlacin entre el namespace de un objeto y el nombre del
ensamble en el cual reside, por ejemplo los tipos de namespace en el System.Net residen
en el ensamble System.Net.dll
Compilacin Condicional
La Compilacin Condicional permite excluir o incluir cdigo, en C# existen dos formas
de hacer esto:
1. Uso del Preprocesador
2. Atributo conditional
Uso del Preprocesador
C# el compilador emula el preprocesador, ya que no hay un preprocesador por separado.
El compilador de C# no soporta macros, en cambio soporta las siguientes directivas:
Definicin de smbolos
Exclusin de cdigo basado en smbolos
Lanzamiento de errores y advertencias
Definicin de smbolos
La Definicin de smbolos es utilizada para excluir o incluir cdigo dependiendo si son o
no son definidos ciertos smbolos.
Una forma para definir un smbolo es utilizando la directiva #define en un archivo fuente
C#, est definicin deber realizarse antes de cualquier otra sentencia:
#define DEBUG
#define RELEASE
En este caso #define DEBUG, define un smbolo DEBUG y su mbito es el archivo donde
es definido, al igual que el smbolo RELEASE.
Otra forma utilizada para definir smbolos es usar el compilador y es de mbito global para
todos los archivos:
csc /define:DEBUG nombreArchivo.cs
Si se requiere definir mltiples smbolos utilizando el compilador, es necesario separar cada
smbolo con una coma (,)
csc /define:DEBUG,RELEASE,DEMOVERSION nombreArchivo.cs
Si el cdigo fuente incluye directivas de definicin de smbolos, es posible deshabilitarlas
utilizando la directiva #undef cuyo mbito tambin corresponde al archivo donde es
definida:
#undef DEBUG
Exclusin de cdigo basado en smbolos
El principal propsito de los smbolos es la inclusin o exclusin condicional del cdigo,
basado sobre si son o no son definidos los smbolos.
El siguiente cdigo no define smbolos en el archivo fuente:
.
sentencia;
.
#if NOMBRE_SIMBOLO
sentencia;
#else
sentencia;
#endif
.
Pero es posible definir o no los smbolos al compilar la aplicacin:
csc /define:NOMBRE_SIMBOLO NombreAplicacion.cs
Las directivas del preprocesador emulado utilizadas para evaluar el smbolo son: #if,
#else y #endif las cuales actuan como su contraparte, la sentencia condicional if C#, es
posible utilizar &&, || y !:
//#define SIMBOLO_A
#define SIMBOLO_B
#define SIMBOLO_C

#if SIMBOLO_A
#undef SIMBOLO_C
#endif

using System;

class NombreClase{
public static void Main(){
#if SIMBOLO_A
.
#elif SIMBOLO_B && SIMBOLO_C
.
#else
.
#endif
}
}
Lanzamiento de errores y advertencias
Existe otro uso de las directivas del preprocesador para lanzar errores del compilador o
advertencias dependiendo de ciertos smbolos, para ello se utilizan las directivas:
#warning
#error
Por ejemplo
#if SIMBOLO_ERROR
#error Presentar el mensaje de error correspondiente
#endif
.
#if SIMBOLO_WARNING
#error Presentar el mensaje de advertencia correspondiente
#endif
Atributo conditional
Un atributo conditional evalua la invocacin de una funcin cuando sierto smbolo es
definido y evalua a nada cuando una versin liberada es construida.
Un atributo conditional debe tener un tipo void de regreso, cualquier otro tipo de regreso
no es permitido.
.
[conditional("NOMBRE_SIMBOLO")]
mtodo A
[conditional("NOMBRE_SIMBOLO")]
mtodo B
.
Comentarios de Documentacin en XML
Es posible construir automticamente la Documentacin utilizando comentarios en el
cdigo.
La salida que es generada por el compilador es XML puro y puede ser utilizada como
entrada para la documentacin de un componente.
La documentacin es una parte extremadamente importante del software y en especial de
los componentes por ser utilizados por otros desarrolladores.
Elementos XML
Nota: todo comentario de documentacin son tags XML (eXtensible Markup Language).
Para describir un elemento se utiliza el tag <summary></summary>, el cual se escribe en el
cdigo fuente anteponiendo tres diagonales que son indicativo de un comentario de
documentacin:
///<summary>Descripcin...</summary>
En caso de requerir ms una lnea para el comentario de documentacin utilice el tag:
///<para>
///.
///.
///</para>
En caso de requerir una referencia a otros elementos utilice el tag:
///<see cref="NombreElemento"/>
En caso de requerir una referencia a un tpico de interes utilice:
///<seealso cref="System.Net"/>
Un tag contrario a summary, para un volumen mayor de documentacin es:
///<remarks>
Es posible incluir listas utilizando los tags :
///<list type="bullet">
/// <item>Constructor
/// <see cref="Constructor()"/>

/// <see cref="Constructor(string)"/>
/// </item>
///</list>
Para describir parmetros se utiliza el tag:
///<paramref name="nombreParametro"/>
Es posible encerrar en un tag un ejemplo completo e incluir la descripcin y cdigo:
///<example>
/// .
/// <code>

/// .
/// </code>
/// .
///</example>
Para describir los parmetros de regreso utilice:
///<returns>

/// <para>true: valor obtenido</para>
/// <para>false: valor no obtenido</para>
///</returns>
Para describir propiedades de clase se utiliza un tag especial:
///<value>Propiedad...</value>
Una vez que el proceso de documentacin para un componente es terminado, es posible
crear un archivo XML basado en la documentacin descrita en el cdigo fuente y hacerla
disponible a quienes utilicen el componente, para ello simplemente se utiliza al compilar el
switch /doc: seguido del documento XML.
csc /doc:Persona.xml AplicPersona.cc
Ejemplo:
using System;
///
/// Clase Persona
/// Autor : Gerardo ngeles Nava
/// Fecha : 10/09/2005

/// Descripcin : Clase que define lo que es y puede hacer una
persona
///
///
class Persona{
///La propiedad iSueldo se emplea para obtener y asignar el valor
del sueldo de una persona
private int iSueldo;
public int Sueldo{
get{return iSueldo;}
set{iSueldo = value;}
}

public string sNombre;
///Utilizado para asignar el valor de la propiedad sNombre

public void AsignarNombre(string sValor){
sNombre = sValor;
}
public string ObtenerNombre(){
return sNombre;
}
}

class AplicPersona{
public static void Main(){
Persona Empleado = new Persona();
Empleado.Sueldo = 33;
Console.WriteLine("Edad : " + Empleado.Sueldo);

Empleado.AsignarNombre("Gerardo ngeles Nava");
Console.WriteLine("Nombre : " +Empleado.ObtenerNombre());
}
}
Salida: para ver el documento XML generado de clic aqu. El compilador realizar
validacin sobre los tags XML en el archivo fuente, en caso de existir errores el compilador
lo notificar y an as el documento XML es generado pero tendr un mensaje de error.
El documento XML tendr algunos identificadores seguidos de dos puntos (:) y la ruta del
namespace, los cuales por ejemplo tienen los siguiente significados.
N, denota un namespace
T, identifica un tipo, el cual puede ser una clase, interface, estructura, enumeracin o
delegado
F, describe un campo o clase
P, se refiere a una propiedad la cual tambin puede ser un indce o propiedad ndice.
M, identifica un mtodo, incluyendo constructores y operadores.
E, denota eventos
!, denota un error el cual provee informacin acerca de una liga que el compilador
C# no pudo resolver.
Si un elemento tiene perodos en su nombre, estos son reemplazados por el smbolo #. Los
parmetros para mtodos son encerrados entre parntesis y separados por comas (,).
Componentes .NET
El compilador de C# por default siempre crea componentes .NET para los ejecutables.
Un Componente .NET es la unidad fundamental reusable y compartida en el CLR, un
componente .NET tambin es limitante para asegurar la seguridad, permite la distribucin
de clases y resolucin de tipos. Una aplicacin puede contener mltiples componentes
.NET
Un componente .NET contiene cuatro partes referentes al nmero de versin llamado
versin compatible:
major version.minor version.build number.revision
La versin compatible es utilizada por el class loader para decidir cual es la versin del
componente .NET que cargar, en caso de existir diferentes versiones.
Se considera una versin incompatible cuando major version.minor version es
diferente de la versin solicitada.
Se podra considerar una versin compatible cuando el build number es diferente a la
versin solicitada.
Se considera una QFE (Quick Fix Engineering) compatible cuando revision es diferente.
Adems del nmero de versin (versin compatible) se almacena otro nmero en el
componente llamado informational version, el cual es considerado slo para propsitos de
documentacin y su contenido podra ser SuperControl Build 1880, el contenido
representa algo humano y no para la mquina.
Para indicar al compilador que agregue un version information al componente se utiliza el
switch:
csc /a.version:1.0.1.0 /t:library /out:nombreArchivoFuente.dll
nombreArchivoFuente.cs
El switch /a.version crea una biblioteca con el version information 1.0.1.0, esto puede
comprobarse en las propiedades del archivo.dll.
Componentes .NET Privados
Al ligar una aplicacin a un componente .NET utilizando el switch
/reference:nombreBiblioteca la informacin de dependencia registra las herramientas
de desarrollo, incluyendo la versin de las bibliotecas ligadas, este registro se hace en un
manifiesto y el CLR los nmeros de versin contenidos para cargar la versin apropiada de
un componente .NET dependiente en tiempo de ejecucin.
Cualquier componente .NET que reside en el directorio de la aplicacin es considerado
privado y no es version-checked
Componentes .NET Compartidos
Si se requiere construir software que se comparta con otras aplicaciones, el componente
.NET deber ser instalado como compartido.
Interoperabilidad COM
COM es una tcnica de interoperabilidad, por lo que los clientes .NET debern ser capaces
de invocar componentes COM y componentes COM debern hacer uso de los nuevos
componentes .NET, esta es una caracterstica de iteroperabilidad proporcionada por la
plataforma .NET para todos los lenguajes de programacin que emiten cdigo
administrado.
Uso de Componentes .NET en Componentes COM
La interoperabilidad permite a clientes COM utilizar componentes .NET, para hacer esto
posible en COM primero es necesario registrar un objeto antes de poder ser utilizado, para
registrar un objeto COM se utiliza la aplicacin regsvr32 y para registrar un componente
.NET se utiliza regasm.exe, esta herramienta permite registrar un componente .NET en el
Registry y tambin crear un archivo Registry.
Si requiere examinar las entradas agregadas al Registry escriba en la lnea de comandos:
regasm nombreComponente.dll /regfile:nombreArchivoComponente.reg
Ahora puede examinar el archivo generado nombreArchivoComponente.reg.
Nota asegurese de que el directorio en el que se encuentra exista el archivo .dll o escriba
la ruta completa de su ubicacin.
Ejemplo:
REGEDIT4

[HKEY_CLASSES_ROOTinformatique.com.mx.iPersona]
@="informatique.com.mx.iPersona"

[HKEY_CLASSES_ROOTinformatique.com.mx.iPersonaCLSID]
@="{37504224-213A-3943-845A-E572758E4174}"

[HKEY_CLASSES_ROOTCLSID{37504224-213A-3943-845A-E572758E4174}]
@="informatique.com.mx.iPersona"

[HKEY_CLASSES_ROOTCLSID{37504224-213A-3943-845A-
E572758E4174}InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="informatique.com.mx.iPersona"
"Assembly"="iPersona, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null"
"RuntimeVersion"="v1.1.4322"

[HKEY_CLASSES_ROOTCLSID{37504224-213A-3943-845A-
E572758E4174}InprocServer32.0.0.0]
"Class"="informatique.com.mx.iPersona"
"Assembly"="iPersona, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null"
"RuntimeVersion"="v1.1.4322"

[HKEY_CLASSES_ROOTCLSID{37504224-213A-3943-845A-
E572758E4174}ProgId]
@="informatique.com.mx.iPersona"

[HKEY_CLASSES_ROOTCLSID{37504224-213A-3943-845A-
E572758E4174}Implemented Categories_
{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
El motor de ejecucin mscoree.dll es invocado cuando una instancia del objeto
(componente registrado) es requerida, ms no la biblioteca por si sla.
El motor de ejecucin es responsable de proveer la CCW (COM Callable Wrapper) al
objeto.
Una vez registrado el componente puede ser utilizado por lenguajes de programacin que
soporten esta vinculacin, tambin es posible emplear la utileria tlbexp la cual permite
generar una biblioteca tipo para el componente .NET
tlbexp nombreComponente.dll /out:nombreBiblioteca.tlb
Esta biblioteca tipo puede ser utilizada en lenguajes de programacin que soporten esta
vinculacin.
El Componente .NET y todas las clases ya estn registradas y se tiene una biblioteca tipo
para ambientes
Uso de Componentes COM en Componentes .NET
Los Clientes .NET pueden interoperar con objetos clsicos COM, para que un componente
utilise COM debe tener una biblioteca tipo para el CLR esto se traduce a los metadatos que
son almacenados con los tipos.
Para que sea posible invocar un componente COM desde un objeto .NET, es necesario
envolver el cdigo unsafe, cuando la envoltura o wrapper es invocada, un RCW (Runtime
Callable Wrapper) es construido desde la informacin de la biblioteca tipo. Una
herramienta genera el cdigo wrapper basado en la informacin obtenida de la biblioteca
tipo.
La herramienta a utilizar es tlimp (type library import):
tlbimp nombreComponente.dll /out:nombreBiblioteca.dll
Esta herramienta importa el tipo de biblioteca COM, crea y almacena un RCW que puede
ser utilizado en el CLR en el archivo nombreBiblioteca.dll.
Para ver los metadatos para el RCW utilice ildasm.exe, as podr distinguir el nombre de
la clase que fu generada para el objeto COM original, esta informacin es una ayuda para
poder escribir el objeto .NET que utiliza el componente COM.
Invocacin de Servicios
Se se requiere invocar una funcin provista por el WIN32 o alguna DLL unmanaged, se
utilizan los Servicios de invocacin de plataforma (PInvoke).
PInvoke se encarga de ejecutar la funcin correcta y tambin de la colocacin de los
argumentos para y desde sus contrapartes unmanaged.
Simplemente utilice el atributo sysimport al definir un mtodo externo:
[sysimport(
dll = nombreDLL,
name = puntoEntrada,
cgarset = conjuntoCaracteres
]
Unicamente el argumento dll es obligatorio y los dems opcionales, aunque si se omite el
atributo name, el nombre de la funcin de implementacin externa debe coincidir con el
nombre del mtodo esttico interno.
Cdigo No Seguro
Si requiere de escribir cdigo no seguro, deber utilizar dos palabras reservadas:
unsafe, denota un contexto no seguro, cuando requiera realizar acciones no seguras
se debe envolver el cdigo correspondiente con este modificador, el cual puede ser
aplicado a constructores, mtodos y propiedades.
fixed, al declarar una variable con este modificador previene al recolector de
basura de reacomodarlo.
Debugging
El SDK .NET incorpora dos herramientas de depuracin de errores:
1. CORDBG, depurador de lnea de comando
2. SDK, depurador UI
o El depurador SDK no soporta la depuracin de cdigo nativo, slo es
posible depurar cdigo administrado.
o No es posible la depuracin de una mquina remota
o Window register y disassembly aunque se implementan no son funcionales
Antes de depurar el cdigo de una aplicacin es necesario crear una versin depurada, la
cual contiene informacin de depuracin no optimizada y un archivo adicional PDB
(program database) para depuracin y un estado de informacin del proyecto es creado.
Para crear una versin depurada son necesarios dos switches al compilar:
csc /optimize- /debug+ nombreArchivoFuente.cs
Estos comandos utilizados al compilar crea dos archivos:
nombreArchivoFuente.exe y
nombreArchivoFuente.pdb
Para configurar la sesin de depuracin es necesario seleccionar la aplicacin que se desea
depurar y comenzar el depurador SDK ejecutando dbgurt.exe, el cual esta almacenado en
el directorio ProgramFilesNGWSSDKGuiDebug
Una vez que la aplicacin depuradora comienza se selecciona el programa que se desea
depurar en donde ser tambin posible especificar argumentos en la lnea de comandos,
mismos que son pasados a la aplicacin cuando la sesin de depuracin inicia.
Es posible establecer diferentes tipos de breakpoint:
File, interrumpe la ejecucin cuando una ubicacin especfica en el archivo fuente
se alcanza
Data, interrumpe la ejecucin cuando una variable cambia a un valor especifico
Function, interrumpe la ejecucin en una ubicacin especfica dentro de una
funcin especfica
Address, interrumpe la ejecucin cuando una direccin de memoria especfica se
alcanza
Una vez que se interrumpe la ejecucin, es posible continuarla utilizando los comandos:
Step Over
Step Into
Step Out
Run to Cursor
Es posible modificar valores de variables simplemente dando doble clic en la columna
valor de aquella variable que se desea modificar, as como tambin es posible observar las
variables, para ello es necesario dar clic en la columna nombre y escribir el nombre de las
variables que se desean observar.
Las excepciones son un punto excelente de comienzo para una sesin de depuracin,
cuando una excepcin no es controlada apropiadamente por el cdigo se muestra la ventana
de depuracin llamada JIT just in time.
Seguridad
Hoy en da el cdigo viene de distintas fuentes, no solo el que es instalado via un setup por
el servidor, tambin puede ser instalado via una pgina web o correo electrnico.
.NET plantea dos posibles soluciones para la seguridad:
1. Seguridad de acceso al cdigo
2. Seguridad basada en roles
Seguridad de acceso al cdigo
La Seguridad de acceso al cdigo controla el acceso protegiendo los recursos y
operaciones. El cdigo es confiable en distintos grados, dependiendo su identidad y de
donde viene.
Funciones de la seguridad de acceso al cdigo:
El administrador puede definir las polticas de seguridad asignando ciertos permisos
para definir grupos de cdigo.
El cdigo puede requerir que quien invoca (caller) debe tener permisos especificos
La ejecucin de cdigo est restringido en tiempo de ejecucin, realizando chequeos
para verificar que los permisos otorgados a quien invoca (caller) coincidan con el
permiso requerido para la operacin.
El cdigo puede requerir los permisos necesarios de ejecucin y los permisos que
podran ser utilizados, es decir, verificar los permisos indispensables.
Los permisos son definidos para representar ciertos derechos para acceder a
distintos recursos del sistema.
La seguridad de acceso al cdigo otorga permisos cuando un componente es
cargado, este otorgamiento esta basado en el requerimiento del cdigo, definiendo
operaciones permitidas por las polticas de seguridad.
Existen dos puntos importantes de la seguridad de acceso al cdigo, donde el requerimiento
mnimo para beneficiarse de la seguridad de acceso al cdigo es para generar un cdigo de
tipo seguro.
1. Verificar el tipo de seguridad del cdigo administrado, el runtime forza la
restriccin de seguridad del cdigo administrado, para determinar cuando el cdigo
es seguro. Es importante que el runtime sea capaz de checar los permisos de quien
invoca de manera confiable, evadiendo hoyos de seguridad que son creados cuando
cdigo menos confiable invoca cdigo altamente confiable, para ello el cdigo
administrado debe ser verificado como tipo seguro. Cada acceso a tipos se realiza
slo en un sentido permitido.
El cdigo C# es de tipo no seguro, pero el IL y los metadatos son inspeccionados
antes de dar el visto bueno del tipo de seguridad del cdigo.
2. Permisos que son requeridos por el cdigo, el beneficio de activar el
requerimiento de permisos es conocer cuando se tiene el permiso apropiado para
realizar acciones y cuando no. Es posible prevenir al cdigo de el otorgamiento de
permisos adicionales que no son necesarios. Los permisos mnimos garantizan que
el cdigo se ejecute con los recursos justos cuando el cdigo requiere de muchos
permisos sin que falle.
La categoria de los permisos es:
Required, permiso que el cdigo necesita para ejecutarse correctamente.
Optional, permisos que no son obligatorios para la ejecucin correcta del cdigo,
pero que podra ser bueno tenerlos.
Refused, permiso que se necesita para que el cdigo nunca se otorgue, aunque la
poltica de seguridad lo permita, se utiliza para restringir vulnerabilidades
potenciales.
Permisos Estndar
Los Permisos Estndar son:
EnvironmentPermission, clase que define permisos de acceso a variables de
ambiente, donde son posibles dos tipos de acceso, de slo lectura y escritura al
valor de una variable de ambiente. El tipo de acceso escritura incluye permisos para
crear y eliminar variables de ambiente.
FileDialogPermission, controla el acceso a archivos basado en el sistema de
archivos de dilogo. El usuario debe autorizar el acceso al archivo via el cuadro de
dilogo.
FileIOPermission, es posible especificar tres tipos de acceso a archivos de entrada
y salida: lectura, escritura y adicin, el acceso lectura incluye acceder a la
informacin del archivo, el tipo escritura incluye eliminar y sobreescribir, el acceso
adicin no permite leer otros bits.
IsolatedStoragePermission, controla el acceso a almacenamientos aislados, este
acceso permite utilizacin, tamao de almacenamiento, tiempo de expiracin y
almacenamiento de datos.
ReflectionPermission, controla la capacidad de leer el tipo de informacin de
tipos miembro no pblicos y controla el uso de Reflection.Emit
RegistryPermission, Control de lectura, creacin y escritura en el registry
SecurityPermission, coleccin de permisos simples que son utilizados por el
sistema de seguridad, es posible controlar la ejecucin de cdigo, sobreescritura de
chequeos de seguridad, invocacin de cdigo no administrado, serializacin, etc.
UIPermission, define el acceso a varios aspectos de la interfaz de usuario,
incluyendo el uso de windows, acceso a eventos y uso del portapapeles.
Permisos Identidad
Los Permisos Identidad son:
PubilsherIdentityPermission, la firma de componentes .NET provee resistencia
de software publisher
StrongNameIdentityPermission, define el nombre del componente
criptograficamente, ya que el nombre compromete la identidad.
ZoneIdentityPermission, define la zona de donde el cdigo tiene origen, un URL
puede pertenecer a slo una zona
SiteIdentityPermission, permisos derivados basados en el sitio web de donde el
cdigo tiene origen
URLIdentityPermission, permisos derivados basados en URL de donde el cdigo
tiene origen
Seguridad basada en roles
La Seguridad basada en roles representa a un usuario o agente que actua en
representacin de un usuario dado. Las aplicaciones .NET hacen decisiones basadas en la
identidad principal o su role como miembro.
Un role es un nombre para un conjunto de usuarios quienes comparten los mismos
privilegios.
Un principal puede ser un miembro de mltiples roles y de esta manera se puede utilizar un
role para determinar si ciertas acciones requeridas quiz sean realizadas por un principal.
Un principal no necesariamente es un usuario, tambin puede ser un agente.
Existen tres tipos de principal:
1. Generic principals, representa usuarios no autentificados.
2. Windows principals, relacin de usuarios windows y sus roles, el acceso a recursos
de otro usuario es permitido.
3. Custom principals, definido por una aplicacin. Pueden extender la nocin bsica
de la identidad y los roles del principal. La restriccin es que la aplicacin debe
proveer un mdulo de autentificacin de los tipos que el principal puede
implementar.
La clase Principalpermission provee consistencia con la seguridad de acceso,
permitiendo al runtime realizar la autorizacin en un sentido similar al chequeo de la
seguridad de acceso al cdigo, pero es posible acceder directamente a la informacin de
identidad principal y realizar chequeos de role e identidad en el cdigo cuando sea
necesario.
Funcin ToString()
Analice el siguiente ejemplo:
using System;
class Empleado{
string usr;
string pwd;
public Empleado(string login, string pwd){
this.usr = login;
this.pwd = pwd;
}
}
class App{
public static void Main(){
Empleado empleado = new
Empleado("gangeles","123");
Console.WriteLine("Empleado : " + empleado);
}
}
Salida: Empleado : Empleado
La salida fue el nombre de la clase Empleado ya que es la representacin ms cercana que
encontro.
Es posible especificar algo con mayor sentido para ello se necesita redefinir la funcin
ToString():
using System;
class Empleado{
string usr;
string pwd;
public Empleado(string login, string pwd){
this.usr = login;
this.pwd = pwd;
}
public override string ToString(){
return("Usuario : " + usr + ", Password : " +
pwd);
}
}
class App{
public static void Main(){
Empleado empleado = new
Empleado("gangeles","123");
Console.WriteLine(empleado);
}
}
Salida: Usuario : gangeles, Password : 123
Funcin Equals()
La funcin Equals() es utilizada para determinar cuando dos objetos tienen el mismo
contenido.
En el siguiente ejemplo se redefinen las funciones operator==() y operator!=(), para
permitir la sintaxis del operador, estos operadores deben ser redefinidos en pares, no
pueden ser redefinidos separadamente.
Ejemplo:
using System;
class Empleado{
string usr;
string pwd;
public Empleado(string login, string pwd){
this.usr = login;
this.pwd = pwd;
}
public override string ToString(){
return("Usuario : " + usr + ", Password : " +
pwd);
}
public override bool Equals(object o){
Empleado empB = (Empleado)o;
if(usr != empB.usr){return false;}
if(pwd != empB.pwd){return false;}
return true;
}
public static bool operator==(Empleado empA, Empleado
empB){
return empA.Equals(empB);
}
public static bool operator!=(Empleado empA, Empleado
empB){
return !empA.Equals(empB);
}
}
class App{
public static void Main(){
Empleado empleado1 = new Empleado("gangeles","123");
Empleado empleado2 = new Empleado("gangeles","123");
Console.WriteLine("El empleado1 es igual al empleado2:
"+empleado1.Equals(empleado2));
Console.Write("empleado1 == empleado2 : ");
Console.Write(empleado1 == empleado2);
}
}
Salida:
El empleado1 es igual al empleado2 : True
empleado1 == empleado2 : True
Al compilar el ejemplo anterior se presentara un warning indicando que no fue redefinada
la funcin GetHashCode() ya que los valores que regresa son requeridos para ser
relacionados al valor de regreso de Equals(). Cuando se invoca la funcin Equals() y dos
objetos son iguales siempre se debe regresar el mismo cdigo hash.
Si no es redefinido el cdigo hash podra ser slo identico para la misma instancia de un
objeto y una bsqueda para un objeto que es igual pero no la misma instancia podra fallar.
Es posible utilizar un miembro que es nico para el cdigo hash, pero si no existe un valor
nico el cdigo hash debera ser creado fuera de los valores contenidos en la funcin.
Si la clase no tiene un identificador nico pero tiene tiene otros campos, podras ser
utilizados por la funcin hash:
using System;
class Empleado{
string usr;
string pwd;
public Empleado(string login, string pwd){
this.usr = login;
this.pwd = pwd;
}
public override string ToString(){
return("Usuario : " + usr + ", Password : " +
pwd);
}
public override bool Equals(object o){
Empleado empB = (Empleado)o;
if(usr != empB.usr){return false;}
if(pwd != empB.pwd){return false;}
return true;
}
public static bool operator==(Empleado empA, Empleado
empB){
return empA.Equals(empB);
}
public static bool operator!=(Empleado empA, Empleado
empB){
return !empA.Equals(empB);
}
public override int GetHashCode(){
return usr.GetHashCode() + pwd.GetHashCode();
}
}
class App{
public static void Main(){
Empleado empleado1 = new Empleado("gangeles","123");
Empleado empleado2 = new Empleado("gangeles","123");
Console.WriteLine("El empleado1 es igual al empleado2:
"+empleado1.Equals(empleado2));
Console.Write("empleado1 == empleado2 : ");
Console.Write(empleado1 == empleado2);
}
}
La implementacin del cdigo GetHashCode anterior agrega los elementos y los regresa.
Clase Hashtable
La clase Hashtable es muy utilizada para realizar una bsqueda de objetos por una llave.
Una tabla hash trabaja utilizando una funcin hash, la cual produce un entero llave para
una instancia especfica de una clase, donde esta llave es una versin condensada de la
instancia.
Una tabla hash utiliza esta llave para limitar drasticamente el nmero de objetos que deben
ser buscados para encontrar un objeto especfico en una coleccin de objetos.
Interface IHashCodeProvider
Si requiere definir diferentes cdigos hash para un objeto especfico, podra hacer esto
implementado la Interface IHashCodeProvider para proveer una funcin alterna hash y
adems de que se requiere una coincidencia de la implementacin de IComparer, estas
nuevas implementaciones son pasadas al contructor de la Hashtable:
using System;
using System.Collections;
public class Lenguaje : IComparable{
public string nombre;
int id;
public Lenguaje(string nombre, int id){
this.nombre = nombre;
this.id = id;
}

int IComparable.CompareTo(object o){
Lenguaje lenguajeB = (Lenguaje)o;
if(this.id > lenguajeB.id){return 1;}
if(this.id < lenguajeB.id){
return -1;
}else{
return 0;
}
}

public override string ToString(){
return nombre + " " + id;
}

public override int GetHashCode(){
return id;
}

public static IComparer OrdenaPorNombre{
get{
return (IComparer) new OrdenaNombres();
}
}

public static IHashCodeProvider HashNombre{
get{
return (IHashCodeProvider) new
HashNombreCls();
}
}

public class OrdenaNombres : IComparer{
public int Compare(object oA, object oB){
Lenguaje lenA = (Lenguaje)oA;
Lenguaje lenB = (Lenguaje)oB;
return
String.Compare(lenA.nombre,lenB.nombre);
}
}
}

class HashNombreCls : IHashCodeProvider{
public int GetHashCode(object o){
Lenguaje len = (Lenguaje)o;
return len.nombre.GetHashCode();
}
}

class App{
public static void Main(){
Lenguaje[] aLenguaje = new Lenguaje[5];
aLenguaje[0] = new Lenguaje("C",3);
aLenguaje[1] = new Lenguaje("ActionScript",5);
aLenguaje[2] = new Lenguaje("JavaScript",2);
aLenguaje[3] = new Lenguaje("Java",8);
aLenguaje[4] = new Lenguaje("PHP",1);

Hashtable lenguajes = new Hashtable(Lenguaje.HashNombre,
Lenguaje.OrdenaPorNombre);
lenguajes.Add(aLenguaje[0], "zxc");
lenguajes.Add(aLenguaje[1], "bnm");
lenguajes.Add(aLenguaje[2], "sdf");
lenguajes.Add(aLenguaje[3], "wer");
lenguajes.Add(aLenguaje[4], "tgh");

Lenguaje clone = new Lenguaje("MiLenguaje", 12345);
string s = (string) lenguajes[clone];
Console.WriteLine(clone.ToString(), s);
}
}
Funcin IClonable
La funcin object.MemberWiseClone() puede ser utilizada para crear un clon de un
objeto. La implementacin por default de esta funcin produce una copia de un objeto, los
campos de un objeto son copiados exactamente en lugar de ser duplicados:
using System;

class Saludo{
public string s;
public Saludo(string s){
this.s = s;
}
}

class MiClase{
public Saludo saludo;
public MiClase(string s){this.saludo = new Saludo(s);}
public MiClase Clon(){return (MiClase)MemberwiseClone();}
}

class App{
public static void Main(){
MiClase miClase = new MiClase("Hello World!");
MiClase miClon = miClase.Clon();
Console.WriteLine("miClase : " + miClase.saludo.s);
Console.WriteLine("miClon : " + miClon.saludo.s);
miClon.saludo.s = "Hola Mundo";
Console.WriteLine("miClase : " + miClase.saludo.s);
Console.WriteLine("miClon : " + miClon.saludo.s);
}
}
Salida:
miClase : Hello World!
miClon : Hello World!
miClase : Hola Mundo
miClon : Hola Mundo
El resultado anterior es porque la copia hecha por la funcin MemberWiseClonre() es una
copia, el valor de saludo es el mismo en ambos objetos por lo que se se cambia un valor
dentro del objeto Saludo afecta ambas instancias de MiClase.
Interface ICloneable
Para crear una copia deep, donde una nueva instancia de Saludo es creada para para la
nueva instancia de MiClase, para ello se hace una implementacin de la interface
ICloneable:
using System;

class Saludo{
public string s;
public Saludo(string s){
this.s = s;
}
}

class MiClase : ICloneable{
public Saludo saludo;
public MiClase(string s){this.saludo = new Saludo(s);}
public object Clone(){return (new
MiClase(this.saludo.s));}
}

class App{
public static void Main(){
MiClase miClase = new MiClase("Hello World!");
MiClase miClon = (MiClase) miClase.Clone();
Console.WriteLine("miClase : " +
miClase.saludo.s);
Console.WriteLine("miClon : " + miClon.saludo.s);
miClon.saludo.s = "Hola Mundo!";
Console.WriteLine("miClase : " +
miClase.saludo.s);
Console.WriteLine("miClon : " + miClon.saludo.s);
}
}

Salida:
miClase : Hello World!
miClon : Hello World!
miClase : Hello World!
miClon : Hola Mundo
La invocacin a Memberwiseclone() regresa una nueva instancia de Saludo y su
contenido puede ser modificado sin afectar el contenido de miClase.
Note que en este caso ICloneable requiere implementar la funcin Clone().
Formato Numrico
Los tipos numricos son formateados a travs de la funcin miembro Format() del tipo de
dato, la cual puede ser invocada directamente a travs de String.Format() la cual invoca
a la funcin Format() de cada tipo de dato o Console.WriteLine() la cual invoca a
String.Format().
Existen dos tipos de mtodos para el formateo especfico numrico:
Formato Estndar String
Formato Estndar String, el cual puede ser utilizado para convertir un tipo numrico a
una representacin especfica string.
Este formato consiste del formato especfico del caracter seguido de la secuencia de
precisin especfica de digitos, los formatos soportados son:
Formato Descripcin Ejemplo Salida
C, c Currency
Console.WriteLine("0:C",
123.8977);
$123,345.90
D, d Decimal
Console.WriteLine("0:D7",
0012345
12345);
E, e
Scientific
(exponential)
Console.WriteLine("0:E",
33345.8977);
3.334590E+004
E, f Fixed-point
Console.WriteLine("0:F",
33345.8977);
3.334590E+004
G, g General
Console.WriteLine("0:G",
33345.8977);
33345.8977
N, n Number
Console.WriteLine("0:N",
33345.8977);
33,345.90
X, x Hexadecimal
Console.WriteLine("0:X",
255);
FF
Formato Personalizado String
El Formato Personalizado String, son utilizados para obtener ms control, sobre la
conversacin que est disponible a travs del formato estndar de strings.
Reemplazo de Cero o Digito
Console.WriteLine("{0:000}",12); Salida: 012
Reemplazo de Espacio o Digito
Console.WriteLine("{0:#####}",123); Salida: 123
Punto Decimal
Console.WriteLine("{0:#####.000}",12345.2); Salida: 12345.200
Separador de Grupo
Console.WriteLine("{0:##,###}",1123456789); Salida: 1,123,456,789
Separador de Grupo
Console.WriteLine("{0:000,.##}",12394); Salida: 123.95
Porcentaje
Console.WriteLine("{0:##.000%}",98144); Salida: 98.144%
Notacin Exponencial
Console.WriteLine("{0:###.000E-00}",3.1415533E+04); Salida: 314.155E-02
Separador de Seccin
Console.WriteLine("{0:###.00;0;(###.00)}",-456.55); Salida: 457
Escape y Literales
Console.WriteLine("{0:###\#}",255); Salida: 255#
Parseo Numrico
Los nmeros pueden ser parseados utilizando el mtodo Parse(), esto es posible ya que lo
provee el tipo de dato.
int iValue = Int32.Parse("123");
double dValue = Double.Parse("1.23");

Input/Output
El lenguaje Comn en Tiempo de Ejecucin .NET provee funciones de entrada/salida en el
namespace System.IO.
La lectura y escritura la realiza la clase Stream, la cual describe como los bytes pueden ser
escritos o leidos. Stream es una clase abstracta que en la prctica las clases derivan de
Stream para ser utilizadas.
Clases disponibles:
FileStream, flujo en un archivo de disco
MemoryStream, flujo que es almacenado en memoria
NetworkStream, flujo en una conexin de red
BufferedStream, implementa un buffer en la cima de otro stream.
Lectura y Escritura de Archivos
Existen dos formas de obtener flujos (streams) que conectan a un archivo, uno utilizando la
clase FileStream, la cual provee un control total sobre el acceso de archivos, incluyendo
modo de acceso, compartido y buffering.
A continuacin se muestra un ejemplo donde, cada vez que el programa es ejecutado se
sobreescribe el contenido del archivo en caso de que este exista, si no existe se crea:

using System;
using System.IO;

class App{
public static void Main(){
FileStream f = new FileStream("nuevo.txt",
FileMode.Create);
StreamWriter s = new StreamWriter(f);
for(int iNumberLine = 1; iNumberLine <= 10;
iNumberLine++){
s.WriteLine("Linea " + iNumberLine);
}
s.Close();
f.Close();
}
}
Salida, Archivo Nuevo.txt cuyo contenido es:
Linea 1
Linea 2
Linea 3
Linea 4
Linea 5
Linea 6
Linea 7
Linea 8
Linea 9
Linea 10
Serializacin
La Serializacin es el proceso utilizado por el runtime para objetos persistentes en algn
orden de almacenamiento o para transferirlos de un lugar a otro.
La informacin de los metadatos en un objeto contiene informacin suficiente para que el
runtime serialice los campos, pero es necesario indicar al runtime hacerlo correctamente a
travs de dos atributos [Serializable] el cual es utilizado para marcar un objeto que es
posible serializar y [NonSerialized] que es aplicado para un campo o propiedad para
indicar que no debera ser serializado.
Threading (Hilos)
El namespace System.Threading contiene clases utilizadas para threading y
sincronizacin. El tipo apropiado de sincronizacin y/o exclusin depende del diseo del
programa, pero C# soporta exclusin simple utilizando la sentencia lock.
lock utiliza la clase System.Threading.Monitor y provee funcionalidad similar a la
invocacin de CriticalSection en Win32.
Agradecimientos a Juan Garcia por enviar el tutorial original de informatique.com.mx

You might also like