Está en la página 1de 63

14/2/2015

Manuales.NET:ManualC#

QuesC#?
C#oCSharpesunlenguajedeprogramacinqueestincluidoenlaPlataforma.NETycorreenelLenguajeComnen
TiempodeEjecucin(CLR,CommonLanguageRuntime).ElprimerlenguajeenimportanciaparaelCLResC#,muchode
loquesoportalaPlataforma.NETestescritoenC#.
C#intentaserellenguajebaseparaescribiraplicaciones.NET
C#derivadeCyC++,esmoderno,simpleyenteramenteorientadoaobjetos,simplificaymodernizaaC++enlasreas
declases,namespaces,sobrecargademtodosymanejodeexcepciones.SeeliminolacomplejidaddeC++parahacerlo
msfcildeutilizarymenospropensoaerrores.
AlgunascaractersticasdeC#son:
C#proveeelbeneficiodeunambienteeleganteyunificado.
No soporta herencia mltiple, solamente el runtime .NET permite la herencia mltiple en la forma de
interfaces,lascualesnopuedencontenerimplementacin.
Nomanejaapuntadores,paraemularlafuncindelosapuntadoresseutilizadelegateselcualproveelas
basesparael.NETeventmodel.
Pordefaulttrabajaconcdigoadministrado.
La Plataforma .NET provee un colector de basura que es responsable de administrar la memoria en los
programasC#.
Elmanejodeerroresestbasadoenexcepciones.
Soporta los conceptos como encapsulacin, herencia y polimorfismo de la programacin orientada a
objetos.
ElModelocompletodeclasesestconstruidoenlacimadel.NETVirtualObjectSystem(VOS).Elmodelo
deobjetosespartedelainfraestructurayyanoformapartedellenguajedeprogrmacin.
Noexistenfuncionesglobales,variablesoconstantes.Tododeberserencapsuladodentrodelaclase,como
unmiembrodelainstancia(accesibleviaunainstanciadeclase)ounmiembroesttico(viaeltipo).
Los mtodos que se definen en las clases son por default no virtuales (no pueden ser sobre escritos al
derivarclases)
Soportalosmodificadoresdeaccesoprivate,protected,publicyagregauncuartomodificadorinternal.
Solamentesepermiteunabaseclase,siserequiereherenciamltipleesposibleimplementarintefaces.
Noesposibleutilizarvariablesnoinicializadas.
Noesposiblehacerelcastdeunenteroauntipodereferencia(objeto).
Losparmetrosquesonpasadossontypesafe.
ElsoportedeversionesloproveeelCLR.
Permite acceder a diferentes APIs a travs de .NET Common Language Specification, el cual define el
estdardeinteroperabilidadentrelenguajesqueseadhieranaesteestndar.
LaPlataforma.NETproveeunaccesotransparenteaCOM.
SoportaOLE
PermitelainteroperabilidadconAPIsalestiloCyDLLs,estacaractersticaparaaccederaAPIsnativases
llamadaPlatformInvocationServices(PInvoke)
Pordefaultelcdigoessafemode,peroesposibledeclararclasesoslomtodosunsafe,estadeclaracin
permiteutilizarapuntadores,estructurasyalmacenamientodearreglosestticos.
C#dependedelruntimequeproveelaPlataforma.NET,elruntimeadministralaejecucindecdigo.
LenguajeOrientadoaObjetos
SegnBjarneStroustrupautordellenguajedeprogramacinC++,paraqueunlenguajeseallamadoOrientadoaObjetos
debesoportartresconceptos:objetos,clasesyherencia.
Aunqueloslenguajesorientadosaobjetosseconstruyensobrelosconceptosde:
Encapsulacin
Herencia
Polimorfismo
Objeto
UnObjetoesunainstanciadeuntipodeclase.
La instanciacin es el acto de crear una instancia de un objeto, la instancia es un objeto, la instanciacin usa el
operadornew,despuslainstanciacinesposiblecomunicarnosconelobjetoatravsdesusmiembros.
UnObjetoesunacoleccindeinformacinrelacionadayfuncional.
Unobjetosecomponede:
Datosquedescribenelobjetoy
Operacionesquepuedenserrealizadasporelobjeto
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

1/63

14/2/2015

Manuales.NET:ManualC#

Herencia
La Herencia es la habilidad para heredar datos y funcionalidad de un objeto padre, la herencia es una caracterstica
fundamentaldeunsistemaorientadoaobjetos.
Atravsdelaherenciaesposiblecrearoderivarunanuevaclasebasadaenunaclaseexistente.
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.Lanuevaclasederivadaheredatodoslosmiembrosdelaclasebaseporconsiguientepermitereusareltrabajo
previo.
EnC#sepuedeasumirquelaclasederivadapodraheredartodoslosmiembrosdelaclasebase.
Laherenciaesunejemplodeldiseoorientadoaobjetosconocidocomounarelacin"isa"(esun),porejemplo:
"unempleadoesunapersona".
Al utilizar la herencia la clase base necesita ser diseada teniendo en mente la herencia, si los objetos no tienen la
estructuraapropiadalaherencianopodrafuncionarcorrectamente.
Una clase derivada no debera requerir ms ni prometer menos que su clase base sobre cualquiera de sus interfaces
heredadas.
Unainterfazdeclaseesuncontratoentreestaylosprogramadoresqueusanlaclase.
upcasting,cuandounprogramadortieneunareferenciaalaclasederivada,elprogramadorsiemprepuedetrataraesa
clasecomosifueralaclasebase.
Enellenguajecomnentiempodeejecucin.NETtodoslosobjetosheredandelaltimaclasebasellamadaobject y
existeslounaherenciasimpledeobjetos.
Unobjetopuedederivarslodeunaclasebase.
Clase
UnaClaseesunaplantillaparaunobjeto.
UnaClasedefinelasoperacionesqueunobjetopuederealizarydefineunvalorquemantieneelestadodelobjeto,los
componentesprincipalesdeunaclaseson:mtodos,eventosypropiedades.
Unainstanciadeunaclaseesunobjeto,seaccedealafuncionalidaddeunobjetoinvocandosusmtodosyaccediendoa
suspropiedades,eventosycampos.
Unaclaseutilizamodificadorespara especificar la accesibilidad de la clase y sus componentes, los componentes de una
clasesonllamadosmiembrosporloqueexistendiferentestiposdemiembros.Unareferenciaserefiereaunainstancia,
una instancia es la creacin de un objeto del tipo clase que se est declarando. Una clase utiliza ninguno, uno o
msconstructorespara ayudar a definir la instancia de una clase. Existe una palabra reservada llamadathis que sirve
parahacerreferenciaalaclaseactualenelmbitoenelcualesutilizada.Cuandosehacereferenciaaunavariablede
instanciaquetieneelmismonombredeunparmetrosedebeutilizarthis.name.
Alcrearymanipularobjetosnoesnecesarioadministrarlamemoriaqueestosocupanyaqueexisteunmecanismoque
se encarga de esto llamado garbage collector (recolector de basura), pero es una buena prctica no olvidar liberar los
recursos.
FuncionesMiembro
UnaFuncinMiembropuede ser unconstructor, es decir, una pieza de cdigo que es invocada en una instancia del
objeto.
CamposEstticos
UnMiembroEstticodefininemiembrosdeunobjetoquenosonasociadosconunainstanciadeclaseespecfica.
Un Campo Esttico es el tipo ms simple de un miembro esttico, para declarar un campo esttico se utiliza el
modificadorstatic.
Uncampoestticopuedeaccederseatravsdelnombredelaclase,envezdelainstanciadelaclase(objeto):

usingSystem;

classMiContador{

//CampoEsttico

publicstaticintiContador=0;

publicMiContador(){

iContador++;

classApp{

publicstaticvoidMain(){

MiContadorContadorA=newMiContador();

Console.WriteLine(MiContador.iContador);

MiContadorContadorB=newMiContador();

Console.WriteLine(MiContador.iContador);

}
Elejemplodeterminacuantasinstanciasdelobjetohansidocreadas.
ClaseBase
UnaClasebaseesunobjetopadrededondesebasaunnuevotrabajo.
ClaseDerivada
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

2/63

14/2/2015

Manuales.NET:ManualC#

UnaClasederivadaesunobjetohijo.
ClaseAbstracta
UnaClaseAbstractadefinelasfuncionesqueunaclasederivadadebeimplementar.
UnaClaseAbstractadefine un contrato en donde las clases derivadas deben definir las funciones que la clase padre
marcautilizandolapalabrareservadaabstract,ademsquelaclasepadretambinsedefinecomoabstract.

usingSystem;

abstractpublicclassPersona{//Indicaquelaclaseesabstracta

//Propiedades

publicstringsNombre;

publicintiEdad;

//Constructor

publicPersona(stringsNombre,intiEdad){

this.sNombre=sNombre;

this.iEdad=iEdad;

//Mtodos

abstractpublicstringTipo();//Mtodoquelaclasederivadadebeimplementar

//HerenciaSimple

publicclassEmpleado:Persona{

publicEmpleado(stringsNombre,intiEdad):base(sNombre,iEdad){}

overridepublicstringTipo(){

return"Empleado";

classApp{

//Aplicacin

publicstaticvoidMain(){

Console.WriteLine("ArreglodeObjetos");

Empleado[]aProgramadores=newEmpleado[2];

aProgramadores[0]=newEmpleado("BillGates",50);

aProgramadores[1]=newEmpleado("EricS.Raymond",60);

for(inti=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());

ClaseSealed
Una Clase sealed se utiliza para prevenir que una clase sea utilizada como una clase base, su principal uso es para
prevenirladerivacinnoplaneada.

sealedclassClaseBase{

ClaseBase(){}

classClaseDerivada:ClaseBase{

classSellada{

publicstaticvoidMain(){

ClaseDerivadaCD=newClaseDerivada();

}
Alcompilarelcdigosemuestraelsiguientemensaje:

sealed.cs(4,7):errorCS0509:'ClaseDerivada':cannotinheritfromsealedclass'ClaseBase'

sealed.cs(1,14):(Locationofsymbolrelatedtopreviouserror)
ElerroresporqueClaseDerivadanopuedeutilizarClaseBasecomounaclasebaseporqueClaseBaseessealed,esdecir,
nopermitederivaciones.
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 losconstructorespara definir diferentes maneras de crear una
instancianueva.
Cuando una funcin sobrecargada es invocada el compilador selecciona la funcin apropiada que coincide con los
parmetros.
HerenciaSimple
La Herencia Simple permite derivar una clase en una clase nueva, que contiene la definicin de la clase de la cual
deriva,esdecir,heredatodoslosmiembrosdatosdelaclase,aunquepuedenexistirmiembrosaloscualesnosepueda
teneraccesoporserprivate.
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

3/63

14/2/2015

Manuales.NET:ManualC#

Losconstructoresnopuedenserheredados,porloqueesnecesarioescribirconstructoresysifuncionalmentenoexiste
algunamodificacinseinvocaelconstructordelaclasequeheredautilizandolasintaxisbase.Siseomiteelconstructor
delaclasebaseyesinvocadoelcompiladorpodrainvocarelconstructordelaclasebasesinparmetros.

usingSystem;

publicclassPersona{

//Propiedades

publicstringsNombre;

publicintiEdad;

privatedoubledSueldo;

//Constructor

publicPersona(stringsNombre,intiEdad){

this.sNombre=sNombre;

this.iEdad=iEdad;

//Mtodos

publicstringTipo(){

return"Persona";

publicvoidAsignarSueldo(doubledSueldo){

this.dSueldo=dSueldo;

publicdoubleObtenerSueldo(){

returnthis.dSueldo;

//HerenciaSimple

publicclassEmpleado:Persona{

publicEmpleado(stringsNombre,intiEdad):base(sNombre,iEdad){}

publicnewstringTipo(){

return"Empleado";

doubledSueldo;

publicnewvoidAsignarSueldo(doubledSueldo){

this.dSueldo=dSueldo*dSueldo;

publicnewdoubleObtenerSueldo(){

returnthis.dSueldo;

classApp{

//Aplicacin

publicstaticvoidMain(){

PersonaMexicano=newPersona("GeradongelesNava",33);

Console.WriteLine("Mexicano.sNombre:"+Mexicano.sNombre);

Console.WriteLine("Mexicano.iEdad:"+Mexicano.iEdad);

doubledSueldo=123.456;

Mexicano.AsignarSueldo(dSueldo);

Console.WriteLine("Mexicano.iSueldo:"+Mexicano.ObtenerSueldo());

Console.WriteLine("Mexicano.Tipo:"+Mexicano.Tipo());

Console.WriteLine("HerenciaSimple");

EmpleadoProgramador=newEmpleado("CarlosSalinasG.",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());

}
PolimorfismoyFuncionesVirtuales
El polimorfismo es la funcionalidad que permite a cdigo antiguo invocar cdigo nuevo, tambin permite extender el
sistemasinmodificarelcdigoexistente,estoselograsobreescribiendooredefiniendoelcdigo,paralocualseutilizan
funcionesvirtualesylapalabraclaveoverride.
Lasfuncionesabstractassonautomaticamentefuncionesvirtuales,lascualespermitenalprogramadorusarpolimorfismo
parahacersucdigosimple.
Virtualsignificaquecuandounainvocacinafuncionesmiembro,elcompiladordeberabuscarporeltiporealdelobjeto
ynoporeltipodelareferencia,einvocarenbasealtipolafuncinapropiada.

usingSystem;

publicclassPersona{

//Propiedades

publicstringsNombre;

publicintiEdad;

//Constructor
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

4/63

14/2/2015

Manuales.NET:ManualC#

publicPersona(stringsNombre,intiEdad){

this.sNombre=sNombre;

this.iEdad=iEdad;

//Mtodos

virtualpublicstringTipo(){

return"Persona";

//HerenciaSimple

publicclassEmpleado:Persona{

publicEmpleado(stringsNombre,intiEdad):base(sNombre,iEdad){}

overridepublicstringTipo(){

return"Empleado";

classApp{

//Aplicacin

publicstaticvoidMain(){

PersonaMexicano=newPersona("GeradongelesNava",33);

Console.WriteLine("Mexicano.sNombre:"+Mexicano.sNombre);

Console.WriteLine("Mexicano.iEdad:"+Mexicano.iEdad);

Console.WriteLine("Mexicano.Tipo:"+Mexicano.Tipo());

Console.WriteLine("ArreglodeObjetos");

Empleado[]aProgramadores=newEmpleado[2];

aProgramadores[0]=newEmpleado("BillGates",50);

aProgramadores[1]=newEmpleado("EricS.Raymond",60);

for(inti=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());

}
Cuandounafuncinesdeclaradaconlapalabrareservadaoverridesignificaqueeslamismafuncinquefuedeclarada
enlaclasebase,silapalabrareservadaoverrideseomiteelcompiladorpodraasumirquelafuncinnoestrelacionadaa
lafuncindelaclasebaseynodespachalafuncinvirtual(elcompiladorpodrasugeriromitiroverrideoagregarnew).
Cuando existe una funcin virtual el programador puede pasar una referencia a la clase abstracta aunque la clase
derivadayelcompiladorpodranescribircdigoparainvocarlaversinapropiadadelafuncinentiempodeejecucin.
Porejemplo,elobjetobaseobjecttieneunafuncinvirtualllamadaToString()queconvierteunobjetoastring.Sise
invocalafuncinToString()enunobjetoquequenolatienecomoversinpropia,laversindelafuncinqueesparte
delaclaseobjectpodraserinvocada.
EncapsulacinyVisibilidad
Encapsulacin (tambin llamada information hiding), habilidad de un objeto para ocultar sus datos internos o parte
internadesususuariosyproveeunainterfacequehacelaspartesimportantesdelobjetoaccesibleprogramaticamente.
Laencapsulacinproveeloslmitesentreunainterfazexternaylosdetallesdesuimplementacininterna.
Aldisearobjetoselprogramadordecidequeobjetossonvisiblesalusuarioyqueesprivadodentrodelobjeto,losdetalles
quenosonvisiblesalusuariosonsealadosparaserencapsuladosenlaclase.
Razonesparaencapsularyocultar:
Elusuarionopuedecambiarloqueesprivadoenelobjeto,locualreducelaoportunidaddequeelusuario
cambie o dependa de los detalles en el cdigo, si el usuario hace lode detalles dependientes, los cambios
realizadosenelobjetoquizarruinenelcdigodelusuario.
Los cambios realizados en partes pblicas de un objeto deben permanecer compatibles con la versin
previa.Laspartespblicaspuedensercambiadassinarruinarelcdigodelusuario.
Loscamposprivadospuedensloseraccesadosdesdelaclase,loscampospblicospuedenseraccesados
atravsdecualquierinstanciadelaclase.
Abstraccin
UnaAbstraccinserefiereacomounproblemadadoesrepresentadoenelespaciodeprograma.
Comodesarrolladordeclasesesnecesariopensarenterminosdehacerelmejordiseodeabstraccinparalosclientesde
claseypermitirlesenfocarsealatareaquedebenrealizarynoescudriaroindagarenlosdetallesdecomofuncionala
clase,tambinesnecesariodeterminarcualesdelosmiembrosdelaclasedeberanseraccesiblespublicamente.
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
entenderymantener.
Lainterfazdeclaseeslaimplementacindelaabstraccin.
Plataforma.NET
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

5/63

14/2/2015

Manuales.NET:ManualC#

LasolucinMicrosoft.NETcomprendecuatrocomponentesfundamentales:
Servicios de Bloques de Construccin .NET o acceso programtico para ciertos servicios tales como
almacenamientodearchivos,calendarioypasaporte.NETelcualesunserviciodeverificacindeidentidad.
DispositivosdeSoftware.NETelcualpodracorrersobrenuevosdispositivosInternet.
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
relacionadaapalabrasyfrasesendocumentoscreadosporelusuario.
La Infraestructura .NET la cual comprende la plataforma .NET, Microsoft Studio .NET, los Servidores
Corporativos.NETyMicrosoftWindows.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.NETalgunasvecesllamadalaBibliotecadeClasesBase(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
.NETtienenlabibliotecadeclasesdelaPlataforma.NETasudisposicin.
LabibliotecadeclasesdelaPlataforma.NETincluyensoporteparacualquieradelosarchivosdeentrada/salidaybasede
datosdeentrada/salidaparaXMLySOAP.
La Plataforma .NET es una plataforma nueva que simplifica la aplicacin del desarrollo en ambientes altamente
distribuidosdeInternet.LaPlataforma.NETestdiseadaparacumplirlossiguientesobjetivos:
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
ejecutadoremotamente.
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
cdigocreadoporundesconocidoountercerosemiconfiable.
Proveer un ambiente de ejecucin de cdigo que elimine los problemas de desempeo de ambientes de
scriptsointerpretes.
Hacer que la experiencia del desarrollador sea consistente a travs de una amplia variedad de
aplicaciones,talcomoaplicacionesbasadasenWindowsyaplicacionesbasadasenWeb.
Construir toda la comunicacin sobre estndares industriales para asegurar que el cdigo basado en la
Plataforma.NETpuedaintegrarseconcualquierotrocdigo.
LaPlataforma.NETconsistededoscomponentesprincipales:
ElLenguajeComnenTiempodeEjecucin(CLR)elcualeselfundamentodelaPlataforma.NET
LaBibliotecadeClasesdelaPlataforma.NET,esunacoleccinorientadaaobjetosdetiposreusablesque
pueden utilizarse para desarrollar aplicaciones en el rango de aplicaciones tradicionales desde la lnea de
comandosointerfacesdeusuariogrficas(GUI)hastaaplicacionesbasadasenlasltimasinovacionesque
proveeASP.NETtalescomoWebFormsyservicioswebXML.
Elruntimeesunaagentequeadministraelcdigoentiempodeejecucinalproveerdeservicionesprincipalescomola
administracindememoria,administracindehilos,tambinimplementatiposestrictosdeseguridadyotrasformasde
verificacindecdigoqueasegurenlaseguridadyrobustez.
El concepto de administracin de cdigo es principio fundamental del runtime. El cdigo que manipular el runtime es
conocidocomocdigoadministrado,mientrasqueelcdigoquenosermanipuladoporelruntimeesconocidocomoun
cdigonoadministrado.
La plataforma .NET puede almacenar componentes no administrados que son cargados por el CLR en sus procesos e
inicializadosporlaejecucindecdigoadministradodeestamanerasecreaunambientedesoftwarequepuedeexplotar
tantocaractersitcasdecdigoadministradocomolasdelcdigonoadministrado.
.NETCommonLanguageRuntimeCLR
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(componentcentric).
LoscomponentescreadosenC#sontotalmenteautodescribiblesypuedenserutilizadossinunprocesoderegistro.
C#ayudaenlacreacindecomponentesmedianteelruntimeyframework.NET,loscualesproveenunsistemadetipo
unificadoenelcualtodopuedesertratadocomounobjeto.
CaractersticasdelCLR
ELCLRnoslosoportaelcompiladordeC#,tambineldeVisualBasicyC++,elcdigoquegeneranestoscompiladores
parasersoportadoporCLResllamadomanagedcode.
AlgunosdelosbeneficiosquelasaplicacionesobtienendelCLRson:
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

6/63

14/2/2015

Manuales.NET:ManualC#

IntegracindelenguajesatravsdelCommonLanguageSpecification
Administracinautomaticadememoria,atravsdelrecolectordebasura.
Manejodeexcepcionesdelenguajes.
Seguridadtypesafety.
Soportedeversiones.
ModeloSimplificadoparalainteraccindecomponentes.
El CLR provee los beneficios anteriores, el compilador debe emitir los metadatos en el managed code.
Losmetadatosdescribenlostiposenelcdigoysonempaquetadosenelcdigoejecutable.
ElCLRadministralamemoria,ejecucindehilos,ejecucindecdigo,verificacindecdigoseguro,compilacinyotros
servicios.EstascaractersticassonintrnsecasalaadministracindecdigoquecorresobreelCLR.
Laseguridadyadministracindecomponentesdependedeunnmerodefactoresqueseincluyenensuorigencomo
Internetredcorporativa,computadoralocal,esdecir,quizoquiznoestndisponiblesparadesempearoperacionesde
accesoaarchivos,accesoaregistrosofuncionessensitivas,ansicomienzanautilizarseenelmismaaplicacinactiva.
Elruntimeforzaelaccesoacdigoseguro,noesposibleaccederadatospersonales,sistemadearchivosored.
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
administracindecdigopuedeconsumirotrostiposeinstanciasadministradas,mientrasqueseforzaestrictamentela
fidelidaddetipoyseguridaddetipo.
Laadministracindelambientedelruntimeeliminacuestionesdesoftwarecomunes,liberandoporejemplorecursosque
yanosonutilizados.
Elruntimetambinaceleralaproductividaddeldesarrollador,noimportaellenguajequeunprogramadorutilice,puede
utilizar las ventajas del runtime, biblioteca de clases, y componentes escritos por otros programadores, cualquier
compiladorqueutiliceelruntimepuedehacerlomismo,
La interoperabilidad entre cdigo administrado y no administrado permiten a los desarrolladores continuar utilizando
componentesCOMyDLLs.
El runtime est diseado para incrementar el desempeo, atravs del CLR que provee muchos servicios estndar, el
cdigoadministradonuncaesinterpretado,unacaractersticallamadajustintime(JIT)permitecompilartodoelcdigo
administrado para correr en el lenguaje nativo de la mquina del sistema o de cualquiera que se este ejecutando. El
administradordememoriaeliminalasposibilidadesdefragmentacindememoriaeincrementalareferenciadelocalidad
dememoriaparaimpulsarelincrementodeldesempeo.
ElruntimesoportaaplicacionesdelladodelservidorcomoMicrosoftSQLServereInternetInformationServices(IIS),
estainfraestructurapermiteutilizarcodigoadministradoparaescribirlalgicadelnegocio.
.NETRuntimeEnvironment
El Lenguaje Comn en Tiempo de Ejecucin provee los servicios de ejecucin bsica. Las clases base proveen tipos de
datosbsicos,clasescoleccinyotrasclasesgenerales.LasclasesbasesonclasesparatratardatosyXML.Enlaparte
superiordelaarquitecturalasclasesexponenservicioswebytratramientodelaintefazdeusuario.Unaaplicacinpuede
hacerinvocacionesencualquiernivelyutilizarclasesdesdecualquiernivel.
Organizacin.NETFramework:
ServiciosWeb

InterfazdeUsuario

DatosyXML
ClasesBase

LenguajeComnenTiempodeEjecucin

Ambiente/EntornodeEjecucin
Elambienteoentornoproveeunmodelodeprogramacinsimple,seguro,soportadeherramientaspotentesyayudacon
ladistribucin,empaquetadoysoporte:
ModelodeProgramacinSimple,todoslosserviciossonofrecidosatravsdeunmodelocomnquepuede
seraccedidodesdecualquierlenguaje.NETylosserviciospuedenserescritosencualquierlenguaje.NET,el
entornooambienteengranparteesunlenguajeagnsticopermitiendolaeleccindelenguaje,estohaceel
cdigofcildereusarparaelprogramadorylosproveedoresdebibliotecas.
Enelruntime.NETtodosloserroressonreportadosviaexcepciones.
El entorno contiene las Bibliotecas de Clase Base (Base Class Libraries BCL) las cuales proveen las
funcionestradicionalesfundadasenbibliotecasentiempodeejecucin,lafuncionalidaddelBCLincluye:
Clasescoleccin,talescomoconsultas,arreglos,pilasytablashash.
Clasesdeaccesoabasesdedatos
ClasesIO(inputoutput)
ClasesWinForms,paracrearinterfacesdeusuario
ClasesNetwork
Fueradelaclasebaseentiempodeejecucin,existenmuchosotroscomponentesquecontrolanlainterfazdeusuario
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

7/63

14/2/2015

Manuales.NET:ManualC#

(UI)yrealizanotrasoperacionessofisticadas.
Seguridad,elentornodelruntime.NETestdiseadoparaserunentornoseguro.Elruntime.NET es un
entorno administrado o controlado, lo cual significa que el runtime administra la memoria por el
programadoratravsdelrecolectordebasura.
Elruntime.NETes un entorno verificado, en tiempo de ejecucin el entorno verifica que la ejecucin del
cdigoseadetiposegura(typesafe).
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.
Soportedeherramientaspotentes,Microsoftsuministracuatrolenguajes.NET:VB,VC++,C#yJScript.La
depuracin en gran medida es enriquecida por el runtime .NET, el modelo de ejecucin comn hace la
depuracindelenguajessimpleydirecta.
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
componentesdeunaaplicacinporloqueunaaplicacinslocorreconloscomponentesquesonenviados.
Ensamblaje
Enelruntime.NETelmecanismodeempaquetadoeselensamble(assembly),cuandoelcdigoescompiladoporunode
loscompiladores.NET,esconvertidoaunaformaintermediaconocidacomoIL.
ElensamblecontienetodoslosIL,metadatosyotrosarchivosrequeridosparaqueunpaqueteseejecuteenunpaquete
completo.
Cadaensamblecontieneunmanifiestoqueenumeratodoslosarchivosqueestncontenidosenelensamble,controla
quetiposyrecursossonexpuestosfueradelensambleyrelacionalasreferenciasdeesostiposyrecursosalosarchivos
quecontienenlostiposyrecursos.
Elmanifiestotambinlistaotrosensamblesquedependendeunensamble.
Losensamblessecontienenasmismo,existesuficienteinformacinenelensambleparaserautodescrito.
Cuando se define un ensamble, el ensamble puede ser contenido en un solo archivo o puede ser dividido entre varios
archivos.Utilizandovariosarchivospodrahacerposibleunescenariodondelasseccionesdelensambleseandescargadas
slocomosenecesiten.
InteroperabilidaddeLenguaje
Unadelasmetasdelruntime.NETesserunlenguajeagnstico,permitiendoqueelcdigoseautilizadoyescritodesde
cualquierlenguaje,noslolasclasespuedenserescritasenalgnlenguaje.NETcomoVB.NETyserinvocadasdesdeotro
lenguaje.NETcomoC#,unaclasequefuescritaenVB.NETpuedeserutilizadacomounaclasebaseescritaenC#yesa
clasepodraserutilizadadesdeunaclaseVC++oJScript,esdecir,noimportariaenqueclaseseaescritaunaclase.
Parahacerloanteriorposibleexistenalgunosobstaculoscomolaspropiascaractersticasdellenguaje,yaqueunlenguaje
nopodrasoportarciertascosasqueotrosilassoporte,porejemplolasobrecargadeoperadores.
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
pblicadelaclase,porejemploelCLSprohibeexponertiposdedatossinsigno,porquenotodosloslenguajespueden
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
mecanismogeneralparahacerestoysonutilizadosenexcesoentodoeltiempodeejecucinparaalmacenarinformacin
quemodificacomoelruntimeutilizalasclases.
Losatributossonextensiblesypermitealosprogramadoresdefiniratributosyutilizarlos.
Losatributosseespecificanencerrandolosentrecorchetes:
[Version("14/09/2005",Comentario="1.0.1.0")]
Losatributossonanotacionesquesecolocanenelementosdecdigofuente,comoclases,miembros,parmetros,etc.
Losatributospuedeserutilizadospara:cambiarelcomportamientodelruntime,proveerinformacinacercadeunobjeto,
llevarinformacinorganizacionalaldiseador.
Elatributoinformacinesalmacenadoconlosmetadatosdelelementoypuedenserfacilmenterecuperadosentiempode
ejecucinatravsdeunprocesoconocidocomoreflection.
C#utilizaunAtributoCondicionalparacontrolarcuandolasfuncionesmiembrosoninvocadas.
Por convencin los atributos se agregan al final del nombre de una clase, con la finalidad de conocer cuales son clases
atributoycualessonclasesnormales.TodoslosatributosderivandeSystem.Attribute.
Procurequeelatributoparaelelementoseaespecfico,utilizandolosidentificadoressiguientes:
Identificador

Descripcin

assembly

ensamble

module

mdulo

type

claseoestructura

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

8/63

14/2/2015

Manuales.NET:ManualC#
method

mtodo

property

porpiedad

event

evento

field

campo

param

parmetro

return

valorderegreso

Losatributosquesonaplicadosaensamblesomdulosdebencolocarsedespusdecualquierclusulausingyantesde
cualquiercdigo.
BibliotecadeClasesdelaPlataforma.NET
LaBibliotecadeClasesdelaPlataforma.NETesunacoleccindetiposreutilizablesintegradasenelCLR.
LostiposdelaPlataforma.NETpermitenllevaracabotareasdeprogramacincomunescomomanipulacindestrings,
coleccionesdedatos,conectividadabasesdedatosyaccesoaarchivos.
EsposibleutilizarlaPlataforma.NETparadesarrollarlossiguientestiposdeaplicacionesyservicios:
Aplicacionesdeconsola
WindowsForms
AplicacionesASP.NET
ServiciosWebXML
ServiciosWindows
RequerimientosdeSoftware
TodoloquesenecesitaparadesarrollarenC#eselKitdedesarrollo(SDK),delcualsoloseutilizarelCLRyelcompilador
deC#.
LenguajeIntermedioyMetadatos
MicrosoftdesarrollounlenguajeparecidoallenguajeensambladorllamadoMicrosoftIntermediateLanguage(MSIL).
Paracompilaraplicaciones.NET,loscompiladorestomanelcdigofuentecomoentradayproducenMSILcomosalida.
MSILensesunlenguajecompletoconelcualesposibleescribiraplicaciones.
ElmanagedcodegeneradoporelcompiladorC#noescdigonativoporqueesuncdigodeLenguajeIntermedio(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
cambiarelcdigoILenelcdigonativo.
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
metadatossonbibliotecasdetipo,entradadedatosalregistry,etc.Losmetadatossonempaquetadosdirectamenteconel
cdigoejecutableynoenlocalidadesseparadas.
El IL y los metadatos son colocados en los archivos que extienden el formato PE (Portable Executable) utilizado para
archivos.exey.dll,cuandosecargaelarchivoPEelruntimecolocayextraelosmetadatosyelILdeestos.
CuandosecompilaunaaplicacinC#ocualquieraplicacinescritaenunCLS,laaplicacinescompiladadentrodelMSIL,
adems se compila dentro de las instrucciones nativas de CPU cuando la aplicacin es ejecutada por vez primera por
elCLR.
Elprocesoeselsiguiente:
CdigofuenteescritoenC#
ElcdigofuenteescompiladousandoelcompiladordeC#(csc.exe)dentrodeunEXE.
ElcompiladorC#producecomosalidaelcdigoMSILyunmanifiestoenunapartedeslolecturadelEXE
quetieneunencabezadoestndarPE(Win32PortableExecutable).
Cuandoelcompiladorproduceocrealasalidatambinimportaunafuncinllamada_CorExeMaindelruntime
.NET.
Cuandolaaplicacinesejecutada,elsistemaoperativocargaelPEcomounaDLLdependientetalcomola
nicaqueexportalafuncin_CorExeMain(mscoree.dll)justocomolohaceconcualquierPEvlido.
ElsistemaoperativocargayentoncessaltaalpuntodentrodelPEelcualespuestoahporelcompilador
C#.
ElsistemaoperativoobviamentenopuedeejecutarelcdigoMSIL,elpuntodeentradaesunpequeaparte
quesaltaalafuncin_CorExeMainenmscoree.dll.
Lafuncin_CorExeMaincomienzalaejecucindelcdigoMSILquefuecolocadoenelPE.
DadoqueelcdigoMSILnopuedeserejecutadodirectamente(porquenoestununformatodemquina
ejecutable)elCLRcompilaelMSILusandouncompiladorjustintime(JIToJITter)dentrodeinstrucciones
CPUnativastalcomoprocesaelMSIL.
JITers
El managed code generado por C# es el cdigo IL, aunque el cdigo IL es empaquetado en un formato de archivo PE
vlido,noesposibleejecutarlosinconvertirloaunmanagedcodenativo.
Cuandountipoescargado,ellaodercreayagregaunstub(piezapequea)acadamtododeltipo,ascuandoelmtodo
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%3

9/63

14/2/2015

Manuales.NET:ManualC#

esinvocadoporvezprimera,elstubpasaelcontrolalJIT.
El JIT compila el IL a cdigo nativo y cambia el stub para que apunte al cdigo nativo que est en cache, as las
subsecuentesinvocacionespodranejecutarelcdigonativo.
El CLR incluye tres diferentes JITers que pueden ser usados para convertir MSIL en cdigo nativo, dependiendo de las
circunstancias:
PreJIT (Generacin de cdigo Installtime), opera como un compilador tradicional, aunque est basado
sobreelcompiladorJITprincipal,seejecutacuandouncomponenteNGWSesintaladoycompilaelcdigo
ILamanagedcodenativo.
La generacin de cdigo en tiempo de instalacin compilar un ensamble completo dentro de un cdigo
binariodeCPUespecifico,talcomolohaceelcompiladorC++.Unensambleelcdigoempaquetadoquees
enviadoalcompilador.Lacompilacinsehaceentiempodeinstalacin,cuandoelusuariofinalesmenos
probableparanotificarqueelensambleestasiendocompiladoJIT.
La ventaja de la generacin de cdigo en tiempo de instalacin, es que permite compilar el ensamble
completojustounavezantesdeserejecutado.Alsercompiladoelensambleenteronohaypreocupacin
referentealdesempeointermitentecadavezqueunmtodoenelcdigoesejecutadoporprimeravez.
Alusarestautilidaddependedeltamaodelsistemaydelambientededistribucin.
JIT,compiladorpordefaultutilizadoporelCLR,esuncompiladoroptimizado,elcualrealizaelanlisisdel
flujodedatos,administraelcdigonativocomosalida.
ElJITteresinvocadoentiempodeejecucin.
EconoJIT,realizaunaconversinmuyvelozdelILamanagedcodenativo
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
algunasinvocacionescodepitching,quepermitenalEconoJITdescartarelcdigogeneradoocompiladosi
el sistema comienza a ejecutarse fuera de memoria, siendo el beneficio el reclamo de memoria. La
desventajaesquesielcdigoespitched(lanzado)esinvocadootravezporloquedebesercompiladode
nuevo.
Es posible determinar que tipo de JIT esta siendo utilizado y cuanta memoria utiliza a travs de una pequea utilidad
llamadaJITCompilerManager(jitman.exe),queresideeneldirectoriobindeldirectoriodeinstalacindelNGWSSDK.
SistemadeTipoUnificado
Elruntimede.NEThacemsquedaraldesarrolladorunsimplesistemadetipounificadoqueesusadoatravsdetodos
loslenguajes,tambindejaaloslenguajesescribirextensionesdesistematipo,agregandonuevostiposqueparezcany
actuencomotiposdesistemasbuilt.in.
ElSistemaVirtualdeObjetosVOS
Lasreglasquesesiguencuandosedeclaran,utilizanyadministrantipossonmodeladasenelSistemaVirtualdeObjetos
(VirtualObjectSystemVOS).
ElVOSestableceunaplataformaquepermitelaintegracindelenguajesytypesafety.
Labasedelaarquitecturadelruntimeeslaplataformaquepuededescribirencuatroreas:
VOS Type System, provee un sistema de tipos que intenta soportar la implementacin completa de una
rangoampliodelenguajesdeprogramacin.
Metadata,describeyhacereferenciaalostiposdefinidosporelVOS.
CommonLanguageSpecificationCLS,defineelsubconjuntodetiposdelVOS.Siunabibliotecadeclases
essoportadaporlasreglasdelCLS,garantizaquelabibliotecadeclasespuedaserutilizadaporlosdems
lenguajesqueimplementenelCLS.
Virtual Execution System VES, es responsable de la carga y ejecucin de los programas que fueron
escritosporelCLR.
VOSTypeSystem
El VOS define tipos que describen valores y especifican un contrato en donde todos los valores de tipo deben soportar.
Existendosentidades:valoresyobjetos.
Paraunvaloreltipodescribelarepresentacindealmacenamientoylasoperacionesquepuederealizar.
Losobjetossonmspoderososporqueeltipoesalmacenadoexplicitamenteensurepresentacin,cadaobjetotieneuna
identidadquelodistinguedelosdemsobjetos.
Metadata
ElcompiladorCLStomaelcdigofuentecomoentradayproducecdigoMSILparaelruntimeparacompilaratravsde
losJITtersyejecutar.AdemssemapeaelcdigofuenteasecuenciasdeinstruccionesMSIL,elcompiladorCLStieneotra
tareaimportante:envolvermetadatosdentrodelEXEresultante.
LosMetadatossondatosquedescribendatos.
Los metadatos son la coleccin de elementos programticos que constituyen el EXE, como los tipos declarados y los
mtodosimplementados.
EstosmetadatossonsimilaresalostiposdebibliotecasgeneradasconcomponentesCOM(ComponentObjectModel).
La razn para usar metadatos es simple ya que permiten al runtime .NET conocer en tiempo de ejecucin que tipos
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

10/63

14/2/2015

Manuales.NET:ManualC#

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
llamadoreflection.
Los metadatos por cada objeto .NET registran toda la informacin que es requerida para usar el objeto, con esta
informacinelruntime.NETescapazderesolvercomocrearobjetos,invocarfuncionesmiembrooaccederalosdatosde
unobjetoyelcompiladorpuedeutilizarlainformacinparaencontrarqueobjetosestndisponiblesycomoesutilizado
unobjeto.Lainformacinincluyelosiguiente:
Elnombredelobjeto
Losnombresdetodosloscamposdelobjetoysustipos
Losnombresdetodaslasfuncionesmiembro,incluyendotiposparmetroynombres
Losmetadatostambinpermitenaotrasherramientasaccederalainformacindetalladaacercadelcdigo
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
disponibleparausuariosfinalesparadeterminarcomosonlosobjetos,bsquedadeatributosoejecutarmtodosenlos
quelosnombresnosonconocidoshastaeltiempodeejecucin.
Losmetadatossonutilizadosparavariastareas:
PararepresentarlainformacinqueelCLRutilizaparalocalizarycargarclases.
Parasacarlasinstanciasdelasclasesenmemoria.
Pararesolverlainvocacindemtodos.
ParatraducirILacdigonativo.
Paraforzarlaseguridad.
ElencargadodegenerarlosmetadatoseselcompiladorC#,alpasarelcdigoaIL,emitiendolainformacinbinariadelos
metadatosenunarchivoPE.
Laprincipalventajadelacombinacindelosmetadatosconelcdigoejecutableesquelainformacinacercadelostipos
espersistente.
Una herramienta que toma ventaja de reflection es el ILDASM (Microsoft .NET Framework IL Disassembler), el cual
analizalaaplicacindemetadatosfuenteyentoncespresentainformacinacercadelaaplicacinenlajerarquadelrbol.
Seguridad
Lafacetamsimportantedecualquierambientededesarrollodeaplicacionesdistribuidasescomomanejarlaseguridad.
LaseguridadcomienzatanprontocomounaclaseescaragadaporelCLRporquelaclaseloaderespartedelesquemade
seguridad.NET,laseguridadrelacionadaafactorestalescomoreglasdeaccesibilidadyrequerimientosdeconsistenciason
verificados.
Deployment
LallaveparaelDeploymentdeaplicaciones.NETeselconceptode(ensambles).Losassembliessonpaquetessimplesde
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
tradicionaldeescritorio.
El runtime .NET mantiene el rastreo delos archivos y de las versiones de los archivos asociados con una aplicacin.
Cualquieraplicacinqueesinstaladaesautomticamenteasociadaconlosarchivosquesonpartedeeseensamble.
Si una aplicacin de instalacin intenta sobre escribir un archivo necesario para otra aplicacin, el runtime .NET es lo
bastanteinteligenteparapermitirquelaaplicacindeinstalacin,instalelosarchivosnecesariosperoelCLRnoelimina
lasversionespreviasdeelarchivoporquetodavasonrequeridasporlaprimeraplicacin.
Interoperabilidadconcdigonoadministrado
Elcdigonoadministradonotienelasventajasquetieneelcdigoadministrado,comorecoleccindebasura,sistemade
tipounificadoymetadatos.
Cdigo administrado invocando funciones DLL no administradas, cuando la aplicacin necesita una
interfazparaunaDLLenCylaempresaqueescribelaDLLnoadopta.NETsernecesarioinvocaresaDLL
desdeunaaplicacin.NET.
Cdigo administrado usando componentes COM, es posible lograr esto creando un wrapper .NET para el
componenteCOM,asqueelclienteadministradotrabajaconclases.NET
Cdigo no administrado usando servicios .NET, cuando se desea acceder a .NET desde cdigo no
administrado.
CommonLanguageSpecificationCLS
Esunconjuntodereglasqueunlenguajedebeadherirparacrearaplicaciones.NETqueseejecutanenelCLR.
UnconceptoimportanterelacionadoalaCLReselcdigoadministrado,elcdigoadministradoesjustoelcdigoqueesta
ejecutandosebajoelauspiciodelaCLRyporconsiguientecomienzaasercontroladoporelCLR.
ElCLSdefineunsubconjuntodetiposdelVOS,siunabibliotecadeclasessiguelasreglasdelCLSestagarantizandoser
utilizadaporclientesdeotrolenguajedeprogramacinquetambinseadhierenalaCLS.
ElCLSserefierealainteroperabilidadentrelenguajes,porloqueesnecesarioseguirlostiposycaractersticasdelCLS,
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

11/63

14/2/2015

Manuales.NET:ManualC#

para ello es necesario conocer los tipos primitivos, arreglos, tipos, miembros tipo, mtodos, campos, propiedades,
enumeraciones,excepciones,interfaces,eventos,atributospersonalizables,delegados,identificadores,etc.quelapropia
especicicacindefine.
VirtualExecutionSystemVES
El Sistema Virtual de Ejecucin implementa la VOS y se crea implementando un motor de ejecucin (Execution
EngineEE).LoscomponentesdelaVESson:
LenguajeIntermedio(IntermediateLanguageIL),diseadoparaserfacilmentetraducidoaunaamplia
gamadelenguajes,porloqueelcompiladorC#escapazdegenerarellenguajeintermedio.
CargadelCdigoAdministrado(LoadingManagedCode),resuelvenombres,obtieneclasesdelamemoria,
creastubsquesonnecesariosparalacompilacinJIT.Laclassloaderforzalaseguridad.
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.
CargadeMetadatos,seencargadechecarlaseguridaddetiposylaintegridaddelosmtodos.
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
administradotienequeserproporcionadoporelJITeroporelcompilador.
Servicios de debugging, estos servicios dependeran de la informacin producida por el compilador del
lenguajefuenteyseemitendosmapas,unmapadellenguajefuentedelaconstruccindedireccionesenel
flujodeinstruccionesyunmapadelasdireccionesdelaslocalidadesenelapiladodeframes.
AdministracindeHilos,elVESproprorcionaesteservicioalcdigoadministrado.
TiposdeDatos
C#soportaelconjuntodetiposdedatosusual,paracadatipodedatoqueC#soporta,existeunacorrespondenciatipode
lenguajecomnentiempodeejecucin.NETsubyacente.
TodoslostiposruntimepuedenencontrarseenelnamespaceSystemdellenguajecomnentiempodeejecucin.NET.
Tipo

Bytes Tiporuntime

Descripcin

byte

Byte

sbyte

SByte

Unsignedbyte
Signedbyte

short

Int16

Signedshort

ushort

UInt16

Unsignedshort
Signedinteger

int

Int32

uint

UInt32

Unsignedint

long

Int64

Signedbiginteger

ulong

UInt64

Unsignedbiginteger

float

Single

Floatingpointnumber

double

double

Doubleprecisionfloatingpointnumber

decimal

Decimal

Fixedprecisionnumber

string

String

Unicodestring

char

Char

Unicodecharacter

bool

Boolean

Booleanvalue

Lostiposdedatossonseparadosenvaluetypesyreferencetypes.Losvaluetypessonasignadosenestructurasdepilas
oenlnea.Losreferencetypessonasignadosalaglomerado.
Lasreferenciasytiposdevaloressonderivadosdelaltimaclasebaseobjet,deestamaneraencasodequeuntipode
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
contieneporejemploint,aesteprocesoseleconocecomoboxingyelprocesodereversaseleconocecomounboxing
Lapalabrareservadaclassesempleadaparadeclararuntiporeferencia(heapallocated),ylapalabrareservadastructes
empleada para declarar un tipo valor, una estructura es utilizada para objetos ligeros que necesitan actuar como
tiposbuiltin,lasclasessonutilizadasencualquierotrocaso.
Porejemplountipointesunvalortipoyuntipostringesuntiporeferencias,estotrabajariaas:

inti=2005;

strings="Septiembre";
i

2005

o >

Septiembre

ConstantesyCamposSoloLectura
EnC#losvalorespuedenserdefinidoscomoconstantesyparaqueunvalorseaconstantesuvalordebeseralgoque
puedaserescritocomounaconstante.
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

12/63

14/2/2015

Manuales.NET:ManualC#

publicconststringsDominio="informatique.com.mx";
La restriccin de tipos constantes es que son conocibles en tiempo de compilacin, en vez de ello es posible utilizar el
modificadorreadonlyelcualestdiseadoparaaquellassituacionesendondelasconstantestienenrestriccin.
Aplicandoelmodificadorreadonlyunvalorpuedeserestablecidoenelconstructoroenunainicializacinperonopuede
sermodificadodespus.
EjemploHelloWorld!
ElcdigoC#puedeserescritoencualquiereditor,tambinpuedeescribirseconVisualStudio7.
ElcdigoC#debealmacenarseenunarchivoconextensin.cs
ParacompilarelcdigoC#esnecesariotenerinstaladolaPlataforma.NETqueincluyeelcompiladorC#,puedebuscarel
ejecutableenlaruta:
C:WINDOWSMicrosoft.NETFrameworkv1.1.4322csc.exe
Aseguresedetenerestarutaenelpathparapoderejecutarelcompiladordesdecualquierubicacin.
Paracompilarsuarchivo.csesnecesarioabrirlaconsola(DOS)yescribirelcomandocsseguidodelnombredesuarchivo
porejemplo:
cdhelloworld.cs
Lasalidaexitosadelacompilacinpodraseras:

Microsoft(R)VisualC#.NETCompilerversion7.10.6001.4
forMicrosoft(R).NETFrameworkversion1.1.4322
Copyright(C)MicrosoftCorporation20012002.Allrightsreserved.

Si existe algn error el compilador lo notificar. El archivo es compilado y ligado a helloworld.exe, (el archivo .exe
generadotendrelnombredelarchivofuente)paraejecutarelprogramasloesnecesarioescribirelnombredelarchivo
ejecutable.
Algointeresanteesqueesposibleespecificarelnombredelarchivoejecutableatravsdeunswitch:

csc/out:nuevoNombre.exenombreArchivoFuente.cs

Elsiguienteeselejemplotpicodeloslenguajesdeprogramacin:

classHelloWorld{

publicstaticvoidMain(){

System.Console.WriteLine("HelloWorld");

}
ElmtodoMaindebeestarcontenidoenlaclaseyescritoconlaprimerletraenmayscula.Eltipodeestemtodopuede
servoidoint.Tambinestemtodopuedeespecificarargumentos:

publicstaticvoidMain(string[]args)
SystemeselmbitodelnamespaceenelcualelobjetoConsoleestcontenido.
Esposibleimportarelnamespaceenlasaplicacionesindicandoloaliniciodelcdigoconlapalabrareservadausingquees
unadirectivaparaelnamespaceSystem.ExistenmsnamespacesenlaPlataforma.NET

usingSystem;
EjemploArgs
Examinemoselsiguienteejemplo,elcualrecibelosargumentosconlosqueelcomponentefueinvocado:
EjemplodeArgsconfor:

usingSystem;

classArgs{

publicstaticvoidMain(string[]args){

Console.WriteLine("Argumentos:{0}",args.Length);

for(intitera=0;itera<args.Length;itera++)

Console.WriteLine("Argumento{0}:{1}",itera,args[itera]);

}
EjemplodeArgsconforeach:

usingSystem;
classApp{

publicstaticvoidMain(string[]args){

foreach(stringinputinargs){

Console.WriteLine(input);

}
}
usingSystem;,defineelnamespaceSystem,elcualcontieneentreotraslaclaseConsolela cual es utilizada
paracomunicarseconlalneadecomandos.
usingpermitealusuarioomitirelnamespacealutilizareltipoalqueesreferenciadoenestecasoSystem,por
loqueenvezdeescribir:
System.Console.WriteLine();
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

13/63

14/2/2015

Manuales.NET:ManualC#

Solamenteseescribe:
Console.WriteLine();
usingnopuedeserutilizadoconunnombredeclaseporloquenoespermitidoescribirusingSystem.Console
classArgs,AlnoexistirlasfuncionesglobalesenC#,sedeclaraunaclasellamadaArgs.
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
argumentosproporcionadosalinvocarelcomponente.
Alserunmtododearranquedebeserdeclaradoconelmodificadorstaticporquenoestasociadoconuna
instanciadeunobjeto.
Elmtodoindicaquerecibeunarreglodetipostringllamadoargs
Console.WriteLine("Argumentos : {0}", args.Length);, invoca el mtodo WriteLine de la clase Console para
escribirenlalneadecomandoloqueseindicaentrelosparntesis.
Laprimerpartedeloqueseencierraentreparntesisesunstringdondeesnecesariodestacarque{0},es
unanotacinqueindicaentrellavesunndicequehacereferenciaaunavariableasociadaaeste,eneste
casoasociadaconargs.Length
args.Length,Lengthesunmtododelaclaseargselcualobtieneelnmerodeelementosquecontieneeste
arreglo.
El ciclo for comienza una iteracin desde 0 hasta el nmero de elementos que contiene el
arregloargs.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}correspondeaargs[itera],locualindicaobtenerelelementoencuestindelarregloargs.
ParacompilarelcomponenteutilicecscArgs.cs
Paraejecutarelcomponentesinparmetrosescribaenlalneadecomando:cscArgs
Salida:Argumentos:0
Paraejecutarelcomponenteconparmetrosescribaenlalneadecomando:
cscArgsp1p2p3p4p5p6...pn
Porejemplo:argshttp:www.informatique.com.mx
Salida:

Argumentos:8
Argumento0:http
Argumento1::
Argumento2:www
Argumento3:.
Argumento4:informatique
Argumento5:.
Argumento6:com
Argumento7:.
Argumento8:mx

EjemploInput/Output
Es posible leer datos de la consola utilizando el mtodo ReadLine y es posible mostrarlos utilizando el
mtodoWriteoWriteLinedelobjetoConsole:

usingSystem;

classinOut{

publicstaticvoidMain(){

Console.Write("FechadeNacimiento:");

StringstrFecNac=Console.ReadLine();

Console.WriteLine("FecNac="+strFecNac);

NotequeimportarladirectivaSystemhaceposibleomitirescribirelnamespace,deestaformasloesnecesarioescribirel
nombredelobjetoseguidodelnombredelmtodo.
EjemploStringFormat
Esposibledarformatoalasalidadedatosauntipostring,utilizandolasintaxis{nmero}dondenmeroesreemplazado
porlavariablecorrespondiente:

usingSystem;

classstrFormat{

publicstaticvoidMain(){

Console.Write("Nombre:");
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

14/63

14/2/2015

}
FuncinMain

Manuales.NET:ManualC#

StringstrNombre=Console.ReadLine();
Console.Write("Edad:");
StringstrEdad=Console.ReadLine();
Console.Write("Telfono:");
StringstrTel=Console.ReadLine();
Console.Write("Direccin:");
StringstrDir=Console.ReadLine();

Console.WriteLine("Datos:{0}{1}{2}{3}",strNombre

,intEdad,strTel,strDir);

Es posible incluir una funcin esttica en la clase para poder probarla, en C# esta funcin esttica puede ser escrita
comoMain()eindicaeliniciodelaejecucindeunprograma:

usingSystem;

classApp{

publicstaticvoidMain(){

Console.WriteLine("Helloworld!");

}
ElejemploanteriordefinealafuncinMaincomovoidlocualindicaquenoregresaunvalor,peroesposibleindicarquesi
regreseunvalorescribiendoeltipodelafuncincomointporejemplo,queindicaqueregresaunvalordetipoentero:

usingSystem;

classApp{

publicstaticintMain(){

Console.WriteLine("Helloworld!");

return(1);

}
Tambin es posible que la funcin Main reciba parmetros de la lnea de comandos, para ello es necesario especificar
unarreglodestringscomoparmetro:

usingSystem;

classApp{

publicstaticvoidMain(string[]args){

foreach(stringinputinargs){

Console.WriteLine(input);

}
MltiplesFuncionesMain
EsposiblequeexistanenunaaplicacinvariasclasesquecontenganlafuncinMain()yporelloalcompilarseindicar
unerror.
Para evitar el error o indicar que funcin Main() de que clase deseamos que se ejecute, es necesario utilizar el
siguienteswitchalcompilar:
/main:nombreClase
Porejemplo

usingSystem;

classClaseA{

publicstaticvoidMain(){

Console.WriteLine("MaindelaclaseA");

classClaseB{

publicstaticvoidMain(){

Console.WriteLine("MaindelaclaseB");

classClaseC{

publicstaticvoidMain(){

Console.WriteLine("MaindelaclaseC");

}
Alcompilarutilice:cscmultiplesmain.cs/main:ClaseB
Salida:MaindelaclaseB
Preprocesamiento
Lo ms importante en este punto es que en C# no existe elpreprocesador, el motivo por el cual no existe es para
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

15/63

14/2/2015

Manuales.NET:ManualC#

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
compilacindearchivosindividualesnoesimportanteyesequivalenteaunarchivodegrantamao.
Unidentificadoreselnombrequeesusadoparaalgnelementodeunprogramacomounavariableofuncinydeben
tenerunaletraoguinbajocomoprimercaracter.
C#soportalassiguientesdirectivasdepreprocesamiento:
Tamao

Valor

#define Define un identificador, los identificadores tambin pueden ser definidos via la lnea de
comando
#undef

Eliminaladefinicindeunidentificador

#if

Elcdigodelaseccinescompiladosilaexpresinesverdadera

#elif

ConstructorElseif,siladirectivaanteriornosecumplioysilaexpresinesverdaderael
cdigodelaseccinescompilado

#else

Siladirectivaanteriornosecumplioelcdigodelaseccinescompilado

#endif

Marcaelfinaldelaseccin

Losidentificadoresdebenprecederacualquiercdigoreal.
Esposibleutilizarlossiguientesoperadoresenexpresionespreprocesador:
!
==
!=
&&
||
Esposibleutilizarparntesisparaagruparexpresiones.
Comentarios
Esposiblecomentarelcdigo,paraelloexistendosmodalidades:
//,queseutilizaparacomentarunalnea,esdecir,todoloquesiguea//esignorado.
/**/,queseutilizaparacomentarsegmentosdecdigo.
ValueTypes
Unavariablecontieneunvalordeciertotipo,C#forzaainicializarlasvariablesantesdeutilizarlasenunaoperacin.
Cuandoseasignaunvaloraunvaluetypeelvaloractualescopiadoadiferenciadelosreferencetypesloquesecopiaes
lareferenciaactualnoelvalor.
C#agrupalosvaluetypesen:
TiposSimples
TiposEstructura
TiposEnumeracin
TiposSimples
Los Tipos Simples de C# comparten caractersticas como las de alias con los tipos de sistema de .NET, expresiones
constantesconsistendeTiposSimplesevaluadossolamenteentiempodecompilacinnoentiempodeejecucinylos
TiposSimplespuedenserinicializadosconliterales.
LosTiposSimplesdeC#seagrupanen:
Integral
RepresentavaloresenterosyexistennuevetiposintegralenC#:
Tipo

Tamao

sbyte Enteroconsigno

8bit

128a127

byte

Enterosinsigno

8bit

0a255

short

Enteroconsigno

16bit

32,768a32,767

ushort Enterosinsigno

16bit

0a65,535

int

Enteroconsigno

32bit

2,147,483,648a2,147,483,647

uint

Enterosinsigno

32bit

0a4,294,967,295

long

Enteroconsigno

64bit

9,223,372,036,854,775,808a9,223,372,036,854,775,807

64bit

0a18,446,744,073,709,551,615

ulong Enterosinsigno

Valor

Bool
Representa valores booleanos verdadero y falso, por lo que es posible asignar a una variable un valor
booleanooelresultadodeunaexpresin:
boolbContinuar=(a>b);
En C# el valor verdadero no es posible representarlo con algn valor diferente de cero, no hay una
conversinentreeltipointegralaboolqueforceestaconversin.
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

16/63

14/2/2015

Manuales.NET:ManualC#

Char
RepresentauncaracterUnicodede16bitdetamao,porejemplo:
charcSexo='M';
TambinesposibleasignarunvalorhexadecimalutilizandolasecuenciadeescapexounvalorUnicodecon
lasecuenciadeescapeu:

charcHexadecimal='x0068';

charcUnicode='u0068';

No existen conversiones implicitas de char a otro tipo de datos disponible, esto significa por ejemplo que
tratardeconvertirunavariablecharauntipodedatointegralnoesposibleenC#,porloquesetendrque
haceruncastexplicito:

charcCaracter=(char)65;
intnNumero=(int)'A';

FloatingPoint
Representandostiposdedatos,flotantes(float)ydobles(double):
Tipo
float

Valor
1.5x1045a3.4x1038conunaprecisinde7dgitos

double 5.0x10324a1.7x10308conunaprecisinde1516dgitos

AlrealizaroperacionesconFloatingPointpuedenproducirselossiguientesvalores:
Ceropositivoynegativo
Infinitopositivoynegativo
NaN,NotaNumber
Nota: Si una expresin un valor es de tipo Floating Point todos los otros valores son convertidos a
tiposFloatingPointantesderealizarelclculo.
Decimal
Representa un tipo de alta precisin de 128 bit el cual es posible utilizarlo para calculos financieros y
monetarios.Losvaloresposiblescomprendenlosrangos1.0x10 28a7.9x10 28conunaprecisinde28a29
dgitos.
Nohayconversionesimplicitasentredecimalesydobles,sepodragenerarunoverflowoperderprecisin,
porloqueesnecesariounaconversinexplcitaconuncast.
Cuando se define una variable y se le asigna un valor se utiliza el sufijompara denotar que es un valor
decimal:
decimaldecDecimal=1.0m
Siseomitelaletramlavariablepodrasertratadacomodoubleporelcompiladorantesdeserasignado.
TiposEstructura
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
heredardecualquierotrotipo,nitampocootraclasepuedeheredardeunaestructura.
Lasestructurasdeberanserutilizadassloparatiposquesonrealmenteunapiezadedatos.
LadiferenciaentrestructyclassenC#esquestructesunvaluetypeyclassesunareferencetype.
LaprincipalideadeutilizarstructesparacrearobjetosligeroscomoPoint,FileInfo,etc.,deestamaneraseconserva
memoriaporquenohayreferenciasadicionalesquesoncreadascomosenecesitenporobjetosclase.

usingSystem;

structIP{

publicbyteb1,b2,b3,b4;

classip{

publicstaticvoidMain(){

IPmiIP;

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);

}
TiposEnumeracin
Es posible establecer un conjunto de constantes relacionadas, por default los elementos de una enumeracin son de
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

17/63

14/2/2015

Manuales.NET:ManualC#

tipointdondeelprimerelementotieneelvalor0ycadaelementosubsecuenteseincrementaen1.Esposibleestablecer
elvalordelprimerelementosimplementeasignandoaesteelvalordeseado,ascomoesposibleespecificareltipodedato
de los valores contenidos especificandolo despus del nombre de la enumeracin aunque estn restringidos a los
tipos:long,int,shortybyte.
Sintaxis:

enumNombreEnumeraciones{

constante1,

constante2,

constante3,

constanteN

}
Ejemplo:

usingSystem;

publicclassEnumeracion{

enumenumDias{Sabado,Domingo,Lunes,Martes,Mircoles,Jueves,Viernes};

enumenumMeses{Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto,Septiembre,_

Octubre,Noviembre,Diciembre};

enumenumFecha{Dia=21,Mes=9,Ao=1971};

publicstaticvoidMain(){
TypeeDias=typeof(enumDias);
TypeeMeses=typeof(enumMeses);

TypeeFecha=typeof(enumMeses);
Console.WriteLine("Losdasdelasemana,ysuvalorcorrespondienteenlaenumeracines:");

foreach(stringsinEnum.GetNames(eDias))
Console.WriteLine("{0,11}={1}",s,Enum.Format(eDias,Enum.Parse(eDias,s),"d"));
Console.WriteLine();
Console.WriteLine("Losmesesdelao,ysuvalorcorrespondienteenlaenumeracines:");
foreach(stringsinEnum.GetNames(eMeses))
Console.WriteLine("{0,11}={1}",s,Enum.Format(eMeses,Enum.Parse(eMeses,s),"d"));
}

}
TiposBase
LosTiposBaseparalasenumeracionesseespecificanlistandoeltipobasedespusdelnombredelaenumeracin:

enumeDias:int{

Lunes,

Martes,

Mircoles,

Jueves,

Viernes

};
Lostiposbasevlidosparalasenumeracionesson:byte,sbyte,short,ushort,int,uint,longyulong.
Sieltipobasenoesespecificado,eltipobasepordefaultesint.
TiposReferencia
Es contraste a value types los reference types no almacenan el dato actual que representan, porque almacenan una
referenciaaldatoactual.
LosreferencetypesqueC#utilizason:
TipoObjeto
TipoClase
Interfaces
Delegados
Tipostring
Arreglos
TipoObjeto
ElTipoObjetoeslaClaseBasedetodoslostipos,alserlaclasebasedetodoslostiposesposibleasignarlevaloresde
cualquiertipo.
ElTipoObjetoesutilizadocuandoelvaluetypeestaboxed,esdecir,queestdisponiblecomounobjeto.
TipoClase
ElTipoClasecontienedatosmiembro,funcionesmiembroytiposanidados.Losdatosmiembrosonconstantes,campos
yeventos.Lasfuncionesmiembroincluyenmtodos,propiedades,ndices,operadores,constructoresydestructores.
Interfaces
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

18/63

14/2/2015

Manuales.NET:ManualC#

Una interface declara un tipo referencia que tiene slo miembros abstractos. Slo existe la firma pero no tiene
implementadotodoelcdigo,porloquenoesposibleinstanciarunainterface,slounobjetoquederivadelainterface.
Paracrearunainterfaceseemplealapalabrareservadainterface:

usingSystem;

interfaceIuno{

voidAccionUno();

classImplementa:Iuno{

publicvoidAccionUno(){

Console.WriteLine("Accinuno...");

classApp{

publicstaticvoidMain(){

ImplementaI=newImplementa();

I.AccionUno();

}
Es posible definir mtodos, propiedades e ndices en una interface, cuando se define una Clase es posible derivar de
mltiplesinterfaces,mientrasquealdefinirunainterfacesloesposiblederivardeslounaclase.
Lasinterfacesestnestrechamenterelacionadasaclasesabstractas,separecenaunaclaseabstractaquetienetodossus
miembrosabstractos.
Cuandounobjetoimplementaunainterface,unareferenciaalainterfacepuedeserobtenidaporuncastdelainterface.
Unaclasepuedeimplementarmsdeunainterface.
classNombreClase:InterfaceA,InterfaceB{}
ExisteunatcnicallamadaImplementacindelaInterfaceExplcitayseutilizapararesolvercolisionesconnombresde
mtodosigualesentreinterfaces:

usingSystem;

interfaceIuno{

voidAccionUno();

interfaceIdos{

voidAccionUno();

classImplementa:Iuno,Idos{

voidIuno.AccionUno(){

Console.WriteLine("ColisinresueltaconelnombredelmtodoIuno");

voidIdos.AccionUno(){

Console.WriteLine("ColisinresueltaconelnombredelmtodoIdos");

classApp{

publicstaticvoidMain(){

ImplementaI=newImplementa();

Iunouno=(Iuno)I;

uno.AccionUno();

Idosdos=(Idos)I;

dos.AccionUno();

}
Esposibleocultaralusuariodelaclaselaimplementacindeunainterfaz,ascomotambinesposiblecrearinterfaces
basadasdeotrasinterfaces.
Delegados
Losdelegadossonsimilaresalasinterfaces,especificanuncontratadoentreuncalleryunimplementer(implementador).
Undelegadoespecificalaformadeunafuncinenvezdeespecificartodaunainterface.
Lasinterfacessecreanentiempodecompilacinylosdelegadossoncreadosentiempodeejecucin.
Un delegado encapsula un mtodo con cierta firma, bsicamente un delegado es un typesafe y secure version. Un
delegadoesunaimplementacindefunctionpointersorientadaaobjetosysonutilizadosenmuchassituacionesdonde
uncomponentenecesitavolverainvocarelcomponentequeloestausando.
Esposibleencapsularmtodosestticoseinstanciasenunainstanciadelegado.
Elprincipalusodelosdelegadosesconloseventosnoconlasclases.
Laespecificacindeldelegadodeterminalaformadelafuncinycreaunainstanciadeldelegado,seusalafuncinque
coincideconlaforma.
Losdelegadosalserdenaturalezadinmicaseutilizancuandoelusuariodeseacambiarelcomportamiento,porejemplo
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

19/63

14/2/2015

Manuales.NET:ManualC#

sideseamosqueunaclaseOrdenamientosoportediferentesmtodosdeordenacin,laordenacinpodrasercontrolada
enbaseaundelegadoquedefinalafuncindecomparacin.
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.
Tipostring
El Tipo string se utiliza para manipular datos string. La clase string deriva directamente de object y no es posible
derivarla.
TodoslosstringsenC#soninstanciasdeltipoSystem.StringenelCLR.
stringesunaliasparalaclasepredefinidaSystem.Stringysuusoesmuysencillo:
stringsWebSite="http://www.informatique.com.mx";
Paraaccederauncaracter,simplementeaccedaasundice:
sWebSite[11];
Es posible hacer un barrido de los caracteres que componen el string utilizando la propiedad Length que poseen los
arreglosyporqueesposibleaccederaestostratandoalstringcomounarreglo:

usingSystem;

classApp{

publicstaticvoidMain(){

stringsWebSite="http://www.informatique.com.mx";

Console.WriteLine("sWebSitecontiene:"+sWebSite.Length+"caracteres");

for(intiElemento=0;iElemento<sWebSite.Length;iElemento++){

Console.WriteLine("Elemento"+iElemento+":"+sWebSite[iElemento]);

}
Esposibleconcatenarstringsutilizandoeloperador+.
Sirequierecompararstringsporigualdadutiliceeloperadordecomparacin==
Aunquestringesunreferencetypelacomparacinserealizacomparandolosvaloresnolasreferencias.
La clase String es un ejemplo de tipo inmutable, es decir, que los caracteres contenidos en el string no puede ser
modificadosporlosusuariosdelstring,todaslasoperacionesquesonrealizadasporlaclaseStringregresanunaversin
modificadadelstringenvezdemodificarlainstanciaenlacualseinvocoelmtodo.
LaclaseStringsoportalossisguientesmtodosdecomparacinybsqueda:
Mtodo
Compare()

Descripcin
Comparadosstrings.

CompareOrdinal() Comparadosregionesdestringsutilizandounacomparacinordinal
CompareTo()

Comparalainstanciaactualconotrainstancia.

EndsWith()

Determinacuandounsubstringexistealfinaldeunstring

StartsWith()

Determinacuandounsubstringexistealprincipiodeunstring.

IndexOf()

Regresalaposicindelaprimerocurrenciadeunsubstring

LastIndexOf()

Regresalaposicindelaltimaocurrenciadeunsubstring

Concat()

Concatenadosomsstringsuobjetos,sisepasanobjetoslafuncinToStringesinvocada

CopyTo()

Copiaunnmeroespecficodecaracteresdeunaubicacindelstringdentrodelarreglo

Insert()

Regresaunnuevostringconunsubstringinsertadoenlaubicacinespecfica

Join()

Uneunarreglodestringsjuntoconunseparadorentrecadaelementodelarreglo

PadLeft()

Alineaalaizquierdaunstring

PadRight()

Alineaaladerechaunstring

Remove()

Eliminacaracteresdeunstring

Replace()

Reemplazatodaslasinstanciasdeuncaracterconcaracteresdiferentes

Split()

Creaunarreglodestringsdividiendounstringencualquierocurrenciadeunoomscaracteres

Substring()

Extraeunsubstringdeunstring

ToLower()

regresaunaversindeunstringenminsculas

ToUpper()

regresaunaversindeunstringenmaysculas

Trim()

Eliminaespaciosenblancodeunstring

TrimEnd()

Eliminaunstringdecaracteresalfinaldeunstring

TrimStart()

Eliminaunstringdecaracteresaliniciodeunstring

object.ToString(),convierteunobjetoaunarepresentacinstring.String.Format()puedeserutilizadaparacrearun
stringbasadoenlosvaloresdeotrostring.
LaclaseStringBuildersoportalassiguientespropiedadesymtodos:
Propiedad

Descripcin

Capacity

RecuperaoestableceelnmerodecaracteresqueStringBuilderpuedecontener

[]

ndiceStringBuilderutilizadoparaobteneroestableceruncaracterenlaposicinespecfica

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

20/63

14/2/2015

Manuales.NET:ManualC#
Length

Recuperaoestablecelalongitud

MaxCapacity RecuperalacapacidadmximadelStringBuilder
Mtodo

Descripcin

Append()

Agregalarepresentacinstringdeunobjeto

AppendFormat()

Agregalarepresentacinstringdeunobjeto,utilizandounformatoespecficoparaelobjeto

EnsureCapacity() AseguraqueStringBuildertienesuficienteespacioparaunnmerodecaracteresespecfico
Insert()

Insertalarepresentacinstringdeunobjetoespecficoenunaposicinespecfica

Remove()

Eliminaloscaracteresespecficos

Replace()

Reemplazatodaslasinstanciasdeuncaractesconunnuevocaracter

Arreglos
Unarreglocontienevariablesalascualesseaccedeatravsdendices,todaslasvariablescontenidasenelarregloson
referidoscomoelementosloscualesdebenserdelmismotipo,porloqueeltipodelarreglo.
LosarreglosenC#sonreferenciasaobjetos.Unarreglovaluetypenocontieneinstanciasboxed.
Elvalorinicialdeunarregloesnull,unarreglodeobjetosescreadoutilizandonew.
Cuandounarregloescreadoinicialmentecontienelosvalorespordefaultparalostiposqueestecontendr.
Sintaxis:
tipo[]identificador;
Notequeparadefinirunarregloseutilizanloscorchetes[]despusdeltipodelarreglo.
Ejemplo:
string[]aPersonas;
Esposibleinicializarunarregloalmomentodecrearlo:
string[]asPersonas=newstring[]{"TimBernersLee","BrendanEich","DennisRitchie","JamesGosling"};
Durantelainicializacinesposibleomitirnewtipo[x]y el compilador podra determinar el tamao de almacenamiento
paraelarreglodelnmerodeitemsenlalistadeinicializacin:
string[]asPersonas={"TimBernersLee","BrendanEich","DennisRitchie","JamesGosling"};
Cadaelementodeunarreglodeintsesunintconelvalor0:
int[]aiNumeros=newint[5];
Cadaelementodeunarreglodestringsesunstringconelvalornull:
string[]asNombres=newstring[5];
Ladimensindelarreglopuedesersimpleomultidimensional,dondecadadimensincomienzaconelndice0,sirequiere
hacerunbarridodetodosloselementosdelarreglo,comienceapartirdelndice0hastalalongituddelarreglomenosuno
(nombreArreglo.Length1onIndice<nombreArreglo.Length)

usingSystem;

classArreglo{

staticpublicvoidMain(){

string[]aNombres={"Hugo","Paco","Luis"};

Console.WriteLine(aNombres[0]);

Console.WriteLine(aNombres[1]);

Console.WriteLine(aNombres[2]);

}
Otraalternativaalejemploanteriores:

int[]aiNumeros=newint[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
reservadanewseguidodeltipoyentrecorcheteselnmerodeelementosquecontendr.
Es posible ordernar y buscar los elementos de un arreglo gracias a que los arreglos en C# estn basados en el
tipoSystem.Array del runtime NET. El mtodo Sort() podra ordenar los elementos de un arreglo, los
mtodosIndexOf()yLastIndexOf()yBinarySearchpodran buscar elementos en un arreglo. El mtodo Reverse podra
invertirelordendeloselementosdeunarreglo.
ArreglosMultidimensionales
LosArreglosMultidimensionalessonaquellosquetienenmsdeunadimensin.
Sintaxis:
tipo[,]identificador;
Ejemplo:
string[,]asBidimensional=newstring[2,4];
Paradefinirunarreglomultidimensional,simplementedefinaarregloscomoelementosdelarreglo:
string[,]asMulti={{"a","1"},{"b","2"},{"c","3"}};
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

21/63

14/2/2015

Manuales.NET:ManualC#

Ejemplo:
usingSystem;
classApp{
publicstaticvoidMain(){

string[]asPersonas={"TimBernersLee","BrendanEich","DennisM.Ritchie","JamesGosling"};
Console.WriteLine("LongituddelarregloasPersonas:"+asPersonas.Length);

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

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

Console.WriteLine("LongituddelarregloasBidimensional:"+asBidimensional.Length);

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

}
}

for(inti=0;i<iRenglon;i++){
for(intj=0;j<iColumna;j++){

Console.WriteLine("Dimensin"+i+"elemento"+j+":"+aiBidimensional[i,j]);
}
}
Console.WriteLine("LongituddelarregloaiBidimensional:"+aiBidimensional.Length);

int[]aiNumeros=newint[3]{1,2,3};
Console.WriteLine("LongituddelarregloaiNumeros:"+aiNumeros.Length);
//Define4arreglosde2dimensiones
intiRenglon=4;
intiColumna=2;

string[,]asBidimensional=newstring[iRenglon,iColumna];
//4renglones*2columnas=8Elementos
asBidimensional[0,0]="00";
asBidimensional[0,1]="01";

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

ArreglodeArreglos
UnArreglodeArreglosestambinconocidocomojaggedarrayporquenotienequeserrgido.
Porejemplo:
int[][]aiIDs=newint[3][];
Esteejemplodefineunarreglodearreglodetipointdonde su dimensin es 3 elementos, donde estos elementos son
arreglos.
ArreglosdeObjetos
Unarreglodeobjetosescreadoutilizandonew.
Esposibledeclararymanipulararreglosdeobjetosdelasiguientemanera:

usingSystem;

publicclassPersona{

//Propiedades

publicstringsNombre;

publicintiEdad;

//Constructor

publicPersona(stringsNombre,intiEdad){

this.sNombre=sNombre;

this.iEdad=iEdad;

//Mtodos

publicstringTipo(){

return"Persona";

//HerenciaSimple

publicclassEmpleado:Persona{

publicEmpleado(stringsNombre,intiEdad):base(sNombre,iEdad){}

publicnewstringTipo(){

return"Empleado";

}
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

22/63

14/2/2015

Manuales.NET:ManualC#

classApp{

//Aplicacin

publicstaticvoidMain(){

PersonaMexicano=newPersona("GeradongelesNava",33);

Console.WriteLine("Mexicano.sNombre:"+Mexicano.sNombre);

Console.WriteLine("Mexicano.iEdad:"+Mexicano.iEdad);

Console.WriteLine("Mexicano.Tipo:"+Mexicano.Tipo());

Console.WriteLine("ArreglodeObjetos");

Empleado[]aProgramadores=newEmpleado[2];

aProgramadores[0]=newEmpleado("BillGates",50);

aProgramadores[1]=newEmpleado("EricS.Raymond",60);

for(inti=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());

}
ConversindeArreglos
Unaconversinimplcitaesposiblesilosarreglostienenelmismonmerodedimensiones,siloselementosdeunarreglo
tienen una conversin de referencia implcita para los tipos de elementos del otro arreglo y ambos arreglos son tipos
referencia.
Unaconversinexplcitatienelosmismosrequerimientosdeunaconversinimplcitaexceptoqueloselementosdeun
arreglodebenserconvertiblesexplcitamentealostiposdeelementosdelotroarreglo.
ClaseArray
LaclaseArrayproveeentreotras,funcionesdebsquedayordenamiento.
Enelsiguienteejemplosemuestracomoesordenadounarreglodestrings:

Salida:

usingSystem;
classApp{
publicstaticvoidMain(){

string[]aLenguajes={"Java","Pascal","ActionScript","PHP","C#","SQL",

"JavaScript","C","Java","Prolog","VisualBasic","C++"};

Array.Sort(aLenguajes);

for(intelemento=0;elemento<aLenguajes.Length;elemento++)

Console.WriteLine("Elemento["+elemento+"]="+aLenguajes[elemento]);
}
}

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]=VisualBasic
LafuncinSort(),tambinsepuedeutilizarconnmeros:

Salida:

usingSystem;
classApp{
publicstaticvoidMain(){

double[]aNumeros={8.7,6.9,6.5,4.2,102.09,1.9,0.01,0.002,99.87};

Array.Sort(aNumeros);

for(intelemento=0;elemento<aNumeros.Length;elemento++)

Console.WriteLine("Elemento["+elemento+"]="+aNumeros[elemento]);
}
}

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

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

23/63

14/2/2015

Manuales.NET:ManualC#

InterfaceIComparable
La funcin sort no trabaja con clases o estructuras porque no conoce su orden, pero si desea ordenarlas utilice la
interfaceIComparable,porejemplounaordenacinutilizandounapropiedadnumrica:

Salida:

usingSystem;

PHP1
JavaScript2
C3
ActionScript5
Java8

publicclassLenguaje:IComparable{

stringnombre;

intid;

publicLenguaje(stringnombre,intid){

this.nombre=nombre;

this.id=id;

intIComparable.CompareTo(objecto){

LenguajelenguajeB=(Lenguaje)o;

if(this.id>lenguajeB.id){return1;}

if(this.id<lenguajeB.id){

return1;

}else{

return0;

publicoverridestringToString(){

returnnombre+""+id;

}
}
classApp{

publicstaticvoidMain(){

Lenguaje[]aLenguaje=newLenguaje[5];

aLenguaje[0]=newLenguaje("C",3);

aLenguaje[1]=newLenguaje("ActionScript",5);

aLenguaje[2]=newLenguaje("JavaScript",2);

aLenguaje[3]=newLenguaje("Java",8);

aLenguaje[4]=newLenguaje("PHP",1);

Array.Sort(aLenguaje);

foreach(LenguajeleninaLenguaje)

Console.WriteLine(len);

}
}

InterfaceIComparer
EsposibledefinirmltiplestiposdeordenamientosgraciasaqueeldiseodelFrameworkproveeestacapacidad.
Cada clase slo puede implementar una interface a la vez, por lo que solamente se podra permitir un tipo de
ordenamiento,entoncesserequiereunaclaseseparadaparacadatipodeordenamientoqueimplementenIComparery
podratambinimplementarlafuncinComapare():

usingSystem;
usingSystem.Collections;
publicclassLenguaje:IComparable{

stringnombre;

intid;

publicLenguaje(stringnombre,intid){

this.nombre=nombre;

this.id=id;

intIComparable.CompareTo(objecto){

LenguajelenguajeB=(Lenguaje)o;

if(this.id>lenguajeB.id){return1;}

if(this.id<lenguajeB.id){

return1;

}else{

return0;

publicoverridestringToString(){

returnnombre+""+id;

publicclassOrdenaNombres:IComparer{

publicintCompare(objectoA,objectoB){

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

24/63

14/2/2015

Salida:

Manuales.NET:ManualC#

LenguajelenA=(Lenguaje)oA;
LenguajelenB=(Lenguaje)oB;
returnString.Compare(lenA.nombre,lenB.nombre);

classApp{

publicstaticvoidMain(){

Lenguaje[]aLenguaje=newLenguaje[5];

aLenguaje[0]=newLenguaje("C",3);

aLenguaje[1]=newLenguaje("ActionScript",5);

aLenguaje[2]=newLenguaje("JavaScript",2);

aLenguaje[3]=newLenguaje("Java",8);

aLenguaje[4]=newLenguaje("PHP",1);

ArrayListaList=newArrayList();

aList.Add(aLenguaje[0]);

aList.Add(aLenguaje[1]);

aList.Add(aLenguaje[2]);

aList.Add(aLenguaje[3]);

aList.Add(aLenguaje[4]);

aList.Sort((IComparer)newLenguaje.OrdenaNombres());

foreach(LenguajeleninaList)

Console.WriteLine(len);

}
}

ActionScript5

C3

Java8

JavaScript2

PHP1
IComparerComoPropiedad
EnelejemploanteriorelusuariotienequecrearunainstanciadelordenamientodeseadoyhaceruncastdeIComparer,
peroesposiblesimplificarestoutilizandounapropiedadestticayhacerloporelusuario:

usingSystem;
usingSystem.Collections;
publicclassLenguaje:IComparable{

stringnombre;

intid;

publicLenguaje(stringnombre,intid){

this.nombre=nombre;

this.id=id;

intIComparable.CompareTo(objecto){

LenguajelenguajeB=(Lenguaje)o;

if(this.id>lenguajeB.id){return1;}

if(this.id<lenguajeB.id){

return1;

}else{

return0;

publicoverridestringToString(){

returnnombre+""+id;

publicstaticIComparerOrdena{

get{

return(IComparer)newOrdenaNombres();

publicclassOrdenaNombres:IComparer{

publicintCompare(objectoA,objectoB){

LenguajelenA=(Lenguaje)oA;

LenguajelenB=(Lenguaje)oB;

returnString.Compare(lenA.nombre,lenB.nombre);

}
}
classApp{

publicstaticvoidMain(){

Lenguaje[]aLenguaje=newLenguaje[5];

aLenguaje[0]=newLenguaje("C",3);

aLenguaje[1]=newLenguaje("ActionScript",5);

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

25/63

14/2/2015

Salida:

Manuales.NET:ManualC#

aLenguaje[2]=newLenguaje("JavaScript",2);
aLenguaje[3]=newLenguaje("Java",8);
aLenguaje[4]=newLenguaje("PHP",1);

Array.Sort(aLenguaje,Lenguaje.Ordena);
foreach(LenguajeleninaLenguaje)

Console.WriteLine(len);

ActionScript5

C3

Java8

JavaScript2

PHP1
ExpresionesRegulares
LasExpresionesRegularesproveenunmtodomuypoderosoparahacerfuncionesdebusquedasyreemplazamiento.
Operadoras
ElOperadoraschecaeltipodeloperadorizquierdoysipuedeserconvertidoexplicitamenteaeloperadorderecho,se
obtiene como resultado el objeto convertido a el operador derecho, si no puede ser convertido la operacin falla y
regresanull.Esteoperadorslopuedeseutilizadoconclases.
SecuenciasdeEscape
SecuenciadeEscape

Descripcin

'

Comillasimple

"

Comilladoble

Diagonalinvertida
Nulo

Alert

Retroceso

FormFeed

Nuevalnea

Retornodecarro

Tabulador

Tabuladorvertical

Boxing
Boxingesunmecanismoquecreaunaligaentrelostiposdevaloresylastiposdereferenciapermitiendoauntipode
valorserconvertidoauntipoobjetoyviceversa.

usingSystem;

classApp{

publicstaticvoidMain(){

intiEdad=33;

objectoNumero=iEdad;//Box

intiNumero=(int)oNumero;//Unbox

//castnecesarioporqueoNumeropodracontenercualquiertipodeobjeto

}
Nota, durante la conversin unboxing el tipo debe coincidir exactamente, un valor de tipo boxed no puede
serunboxed(convertido)auntipocompatible.Sirequiereobtenerotrotipodevalordiferentealquecontieneelboxed,en
esecasoprimeroobtengaelvalorcorrectoydespusrealiceuncastaltipoquerequiera:(valorRequerido)
valorRequeridovr=(valorRequerido)(valorBoxed)objeto;
Otra forma de definir el concepto boxing es que este mecanismo permite que los value types parezcan o tengan la
aparienciadereferencetypes.
ConversionesBoxing
Boxing un valor se refiere a la conversin implcita de cualquier tipo de valor al tipo objeto. Cuando un tipo de valor
esboxedseasignaespacioaunainstanciadeobjetoyelvalordelvaluetypeescopiadoalnuevoobjeto.
Observelassiguienteslneas:

int

iNumero=2012;
object oNumero=iNumero;//invocacinimplicitaaunaoperacinboxing

Al asignar el valor de la variable entera nNumero a una variable objeto se realiza internamente una operacin boxing,
dondeelvalordelavariablenNumeroescopiadoalobjetooNumero,entonceslasvariablesenterayobjetoexistenenlapila
perolosvaloresdelosobjetosresidenenelreaoespacioasignado,loqueimplicaquelosvaloressonindependientesy
nohayunaligaentreellos:

usingSystem;
classBox{

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

26/63

14/2/2015

Manuales.NET:ManualC#

publicstaticvoidMain(){

intiNumero=2012;

objectoNumero=iNumero;//invocacinimplicitaaunaoperacinboxing

oNumero=2005;

Console.WriteLine(iNumero);

Console.WriteLine(oNumero);

}
AlejecutarelcdigonotarqueelvalordeoNumeroes2005yelvalordeiNumeronocambiopermaneceen2012.
ConversionesUnboxing
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
typequeserequiereestealmacenadoenlainstanciadelobjeto,silaverificacinesexitosaelvaloresUnboxing.
Supongaquetieneunavariabledetipointyasignaelvalordeestavariableintaunobjeto,despusdeclaraunavariable
detipodoubleyaplicauncast(double)alobjetoparaasignarsuvaloralavariabledouble, el objeto contiene slo un
valor inty no puede ser asignado a la variable double porque el CLR dispara una excepcin
(System.InvalidCastException):

intiNumero=2012;

objectoNumero=iNumero;//invocacinimplicitaaunaoperacinboxing

doubledNumero=(double)oNumero;//invocacionexplcita(cast)

//CLRdisparalaexcepcinSystem.InvalidCastException
ConstructoresyDestructores
Antesdeaccederalosmtodosopropiedadesdeunaclase,primeroseejecutaelconstructordelaclaseelcualcontiene
cdigodeinicializacin,sinoseescribeunconstructorparalaclaseelcompiladorproveeautomticamenteunconstructor
default.
Enelruntime.NETelprogramadornopuedecontrolarladestruccindeobjetos.
Unconstructorpuedeinvocarunconstructordeltipobaseutilizandolasintaxisbase.
Losconstructoressoninvocadosinvocadosautomaticamenteslocuandounainstanciadeunobjetoescreadaconnew.

classNombreClase{

publicNombreClase():base(){}//Constructorqueproveeelcompilador

}
Lascaractersticasdeunconstructorson:
Siempretieneelmismonombrequelaclase.
Notienedeclaradountipoderegreso.
Porlogeneraltienenelmodificadorpblico.
Sonutilizadosparainicializarvaribles.
Silaclaseslocontienemiembrosestticos,esposiblecrearunconstructorprivate,locualsignificaque
nopodrseraccesiblefueradelacalseoqueslosepuedeaccederdesdelaclase.
Nopuedeserinvocadodesdeladefinicindelaclase.
Unobjetonopuedeserinstanciadodesdeladefinicindelaclase.
Al codificar no se est limitado a los parmetros del constructor, es posible enviar argumentos iniciales para inicializar
ciertosmiembros.

usingSystem;
classVehiculo{

//Propiedades:

privateintiRueda;

privateintiPuerta;

privateintiVentana;

privateintiHelice;

privateintiMotor;

privateintiAsiento;

privatestringsTipo;//Aereo,anfibio,terrestre,espacial

//Constructor:
publicVehiculo(intRueda,intPuerta,intVentana,intHelice,_
intMotor,intAsiento,stringTipo){

iRueda=Rueda;

iPuerta=Puerta;

iVentana=Ventana;

iHelice=Helice;

iMotor=Motor;

iAsiento=Asiento;

sTipo=Tipo;
}
//Lectura/escrituradepropiedades:

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

27/63

14/2/2015

Manuales.NET:ManualC#

publicintRuedas{

get{returniRueda;}

set{iRueda=value;}

publicintPuertas{

get{returniPuerta;}

set{iPuerta=value;}

publicintVentanas{

get{returniVentana;}

set{iVentana=value;}

publicintHelices{

get{returniHelice;}

set{iHelice=value;}

publicintMotores{

get{returniMotor;}

set{iMotor=value;}

publicintAsientos{

get{returniAsiento;}

set{iAsiento=value;}

publicstringTipo{

get{returnsTipo;}

set{sTipo=value;}

//Aplicacin:

classAplicConstructor{

publicstaticvoidMain(){

VehiculoMiAvion=newVehiculo(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);

}
EnunsentidoestrictoenC#nosetienendestructores,peroelterminodestructorserefierealaliberacinderecursos.
Esposibleescribirunmtodoquelibererecursosdespusdeserutilizados,peroporqueescribirunmtodoparaliberar
recursossiexisteundestructor:

public~NombreClase(){

//liberarrecursos

}
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
intervalosocondicionesdememoria.
Loquepodrasucederesquelosrecursosseagotenantesdeserutilizados,entoncesesbuenaideaproveerunmtodo
explcitoRelease,elcualtambinpuedeserinvocadoporeldestructor:

publicvoidRelease(){

//Liberarrecursos

public~NombreClase(){

Release();

}
La invocacin del mtodoReleaseen el destructor no es obligatoria, la coleccingarbage de cualquier forma realiza la
liberacindecualquierobjeto,peroesunabuenaprcticanoolvidarliberarlosrecursos.
ConstructorEsttico
Un Constructor Esttico podra ser invocado antes de ser creada la primer instancia de un objeto, y es til para
configurareltrabajoquenecesitahacerseunavez.
Enelruntime.NETelusuarionotienecontrolsobrecuandoelconstructorestticoesinvocado,yaqueelruntimeslo
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

28/63

14/2/2015

Manuales.NET:ManualC#

garantizaquealgoesinvocadodespusdeliniciodelprogramayantesdesercreadalaprimerinstanciadeunobjeto,lo
quesignificaquenopuedeserdeterminadalainstanciaqueescreadaenelconstructoresttico.
Paradeclararunconstructorestticoseutilizaelmodificadorstatic:

classNombreClase{

staticNombreClase(){

}
Mtodos
La mayor parte de la funcionalidad es implementada en los mtodos, los mtodos son parte del Tipo (class), pero los
mtodosnosonpartedelainstancia(object).
Parmetros
Dealgnmodosedebenpasarvaloresaunmtodoytambinsedeberegresarelresultadodeunmtodo,losvalores
sonmanipuladosen:
ValoresenParmetrosin
Seutilizanvaloresenparmetrosparapasarunavariableporvaloraunmtodo,lavariabledelmtodoesinicializadacon
unacopiadelvalordelcaller(quienrealizlainvocacin).

usingSystem;
publicclassFecha{

publicstringMayor(intiDiaA,intiMesA,intiAoA,intiDiaB,intiMesB,intiAoB){

intiA=(iDiaA*10000)+(iMesA+100)+(iAoA);

intiB=(iDiaB*10000)+(iMesB+100)+(iAoB);

Console.WriteLine(iA+">"+iB);
//TestLine(Delete)

if(iA>iB){

returniDiaA+"/"+iMesA+"/"+iAoA;

}else{

returniDiaB+"/"+iMesB+"/"+iAoB;

publicstringMenor(intiDiaA,intiMesA,intiAoA,intiDiaB,intiMesB,intiAoB){

intiA=(iDiaA*10000)+(iMesA+100)+(iAoA);

intiB=(iDiaB*10000)+(iMesB+100)+(iAoB);

Console.WriteLine(iA+"<"+iB);
//TestLine(Delete)

if(iA<iB){

returniDiaA+"/"+iMesA+"/"+iAoA;

}else{

returniDiaB+"/"+iMesB+"/"+iAoB;

}
}

Console.WriteLine("Lafechamayores:"+MiFecha.Mayor(21,10,2000,21,9,1971));
Console.WriteLine("Lafechamenores:"+MiFecha.Menor(21,10,2000,21,9,1971));

}
}

Console.WriteLine("Lafechamayores:"+MiFecha.Mayor(21,10,2000,21,9,2005));
Console.WriteLine("Lafechamenores:"+MiFecha.Menor(21,10,2000,21,9,2005));

classAplicFecha{
publicstaticvoidMain(){

FechaMiFecha=newFecha();

Console.WriteLine("Lafechamayores:"+MiFecha.Mayor(21,9,1971,21,10,2000));

Console.WriteLine("Lafechamenores:"+MiFecha.Menor(21,9,1971,21,10,2000));

Al pasar un valor y no una referencia a la variable, es posible utilizar expresiones constantes, el resultado de los
mtodosMayor y Menor es pasado a el caller como un valor de regreso y es manipulado sin ser almacenarlo en una
variableintermedia.
Sinohaymodificadoreslosparmetrossonsiemprepasadosporvalor.
ValoresenParmetrosref
Esposiblepasarunvalorcomoparmetroaunmtodo,modificarelvaloryregresarlocomoresultadodelmtodo,para
elloseutilizaelmodificadorrefseguidodeltipoydelnombredelparmetro.
Alcontrariodelosvaloresenparmetrosnosepasaunacopiadelvalor,sinolareferenciadelvaloryporelloalmodificar
elvalorsehacelamodificacindirecta,tambinesnecesarioinicializarelvalorquesepasacomoparamtropormediode
unavariableintermediaynodirectamenteatravsdeunaexpresinconstante:

usingSystem;
publicclassParam{

publicvoidParametroRef(refintRefParametro){//Noregresaunvalorexplcito

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

29/63

14/2/2015

Manuales.NET:ManualC#

RefParametro*=RefParametro;//Semodificaelvalordirectamente

//Noseregresaunvalor,porquesemodificodemaneradirecta

classParametros{

publicstaticvoidMain(){

ParamMiParam=newParam();

intiValorRef=5;
//Serequiereinicializarelvalor

MiParam.ParametroRef(refiValorRef);//Seinvocaelmtodo

pasandolareferenciadelvalor

Console.WriteLine("ref:"+iValorRef);

}
GoodPractice,serecomiendatenerdosvariables,unaenelparmetroyotraenelparmetroref.
Recuerde,elcompiladordeC#nopermiteutilizarvariablesquenohansidoinicializadas,porloqueantesdeutilizaro
establecerlosvaloresdeunavariabledebeserinicializada,paraelloexistendosformasdehacerlo:
Inicializarlavariablealdeclararla.
usingSystem;
classMiClase{

privateintMiPropiedad;

publicvoidAsignarValor(refintMiRefParam){

this.MiPropiedad=MiRefParam;

publicstaticvoidMain(){

MiClaseMiObjeto=newMiClase();

intMiEdad=33;//Seinicializalavariablealdeclararla

MiObjeto.AsignarValor(refMiEdad);

Console.WriteLine("MiEdad:"+MiEdad);

Console.WriteLine("MiObjeto.MiPropiedad:"+MiObjeto.MiPropiedad);

}
}

Porejemplocambiarladefinicindelafuncinyutilizarunparmetrooutenvezdeunparmetroref.
usingSystem;
classMiClase{

privateintMiPropiedad;

publicvoidAsignarValor(outintMiOutParam){//Secambialadefinicindelafuncin

MiOutParam=33;

this.MiPropiedad=MiOutParam;

publicstaticvoidMain(){

MiClaseMiObjeto=newMiClase();

intMiEdad;//Noseinicializalavariable

MiObjeto.AsignarValor(outMiEdad);

Console.WriteLine("MiEdad:"+MiEdad);

Console.WriteLine("MiObjeto.MiPropiedad:"+MiObjeto.MiPropiedad);

}
}

Losparmetrosoutsonexactamentecomolosparmetrosrefexceptoqueunavariablesininicializarpuedeserpasada
comoparmetroyelcallerdefineunparmetrooutenvezderef.
ValoresenParmetrosout
Un parmetro out puede ser utilizado slo para contener el resultado de un mtodo, es necesario especificar el
modificadorout para indicar el tipo de parmetro, a diferencia de los parmetros ref el caller no necesita inicializar la
variableantesdeinvocarelmtodo:

usingSystem;

publicclassParam{

publicvoidParametroOut(outintOutParametro){

OutParametro=4*4;

//Nosegregresaunvalor,porqueesregresadoenelparmetroout

}
}
classParametros{

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

30/63

14/2/2015

Manuales.NET:ManualC#

publicstaticvoidMain(){

ParamMiParam=newParam();

intiValorOut;//Noserequiereinicilizarelvalor

MiParam.ParametroOut(outiValorOut);//Seinvocaelmtodoconunparmetroout

Console.WriteLine("out:"+iValorOut);//Resultadodelainvocacindelmtodo

}
EjemplodeParmetrosIn,RefyOut

usingSystem;

publicclassParam{

publicintParametroIn(intInParametro){

returnInParametro*InParametro;

publicvoidParametroRef(refintRefParametro){//Noregresaunvalorexplcito

RefParametro*=RefParametro;//Semodificaelvalordirectamente

//Noseregresaunvalor,porquesemodificodemaneradirecta

publicvoidParametroOut(outintOutParametro){

OutParametro=4*4;

//Nosegregresaunvalor,porqueesregresadoenelparmetroout

classParametros{

publicstaticvoidMain(){

ParamMiParam=newParam();

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

intiValorRef=5;
//Serequiereinicializarelvalor

MiParam.ParametroRef(refiValorRef);//Seinvocaelmtodopasandolareferenciadelvalor

Console.WriteLine("ref:"+iValorRef);

intiValorOut;//Noserequiereinicilizarelvalor

MiParam.ParametroOut(outiValorOut);//Seinvocaelmtodoconunparmetroout

Console.WriteLine("out:"+iValorOut);//Resultadodelainvocacindelmtodo

}
RedefinicindeMtodos(Overriding)
Unodelosprincipiosbsicosdelaprogramacinorientadaaobjetoseselpolimorfismo, 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
emplealapalabrareservadavirtual:
virtualvoidNombreMetodo_PuedeSerRedefinido
Despus,alderivardelaclasebaseseagregalapalabrareservadaoverrideenelnuevomtodo:
overridevoidNombreMetodo_PuedeSerRedefinido()
Noesposiblecambiarlaaccesibilidaddeunmtodoqueesredefinido,esdecir,noesposiblecambiarlosmodificadores
quedefinenalmtodo.
Cuandoseinvocaunmtodovirtualseestderivandoelmtododeclasequeesinvocadoynoelmtododelaclase
base:
((ClaseBase)InstanciaClaseDerivada).NombreMetodo_PuedeSerRedefinido();
Paraindicarqueunaclasederivadeotraseutilizaeloperador:elcualdenotaestaaccin:
classClaseDerivada:ClaseBase{}
Elsiguienteejemplomuestracomoseredefineunmtodo:

usingSystem;
classClaseBase{

publicvirtualintCalculo(intiA,intiB){

returniA+iB;

}
}
classClaseDerivada:ClaseBase{//Sederivadelaclasebase
publicoverrideintCalculo(intiA,intiB){//Seespecificaqueelmtodoserredefinido

returniAiB;//Seredefinelafuncionalidaddelmtodo
}
}
classRedefinirMetodos{

publicstaticvoidMain(){

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

31/63

14/2/2015

Manuales.NET:ManualC#

ClaseBaseClsBase=newClaseBase();

Console.WriteLine("Clasebase:"+ClsBase.Calculo(5,3));

//Secreaunainstanciadelaclasederivada:

ClaseDerivadaClsDer=newClaseDerivada();

//Seinvocaelmtodoredefinidoenlaclasederivada:

Console.WriteLine("Clasederivada:"+ClsDer.Calculo(5,3));

}
OcultamientodeMtodos(Hiding)
Esposibleocultarmtodosdelaclasebase,estoselograhaciendousodeunacaractersticaespecialdelaredefinicinde
mtodosllamadaocultamientodemtodosyalderivardelaclasebase:

usingSystem;

classClaseBase{

//Sincdigo

classClaseDerivada:ClaseBase{//Clasederivadadelaclasebase

publicvoidMetodoOculto(){//MtodoOculto

Console.WriteLine("HidingMethods");

classHiding{

publicstaticvoidMain(){

ClaseDerivadaMiClaseDerivada=newClaseDerivada();

MiClaseDerivada.MetodoOculto();

}
Elcdigoanteriordemuestraqueesposiblederivarunaclasequeimplementaunmtodoquelaclasebasenocontiene.
Porotroladosilaclasebasecontieneelmtodoysetratadederivarunaclasequetratadeimplemetarunmtodoquesi
contienelaclase,seproduceunerror:

usingSystem;

classClaseBase{

publicvoidMetodoOculto(){

Console.WriteLine("HidingMethods");

classClaseDerivada:ClaseBase{//Clasederivadadelaclasebase

publicvoidMetodoOculto(){//Seimplementaunmtodoquesiexiste

Console.WriteLine("HidingMethods");

classHiding{

publicstaticvoidMain(){

ClaseDerivadaMiClaseDerivada=newClaseDerivada();

MiClaseDerivada.MetodoOculto();

}
Elcompiladorindicarunmensajesimilaralsiguiente:

Hiding.cs(10,14):warningCS0108:Thekeywordnewisrequiredon'ClaseDerivada.MetodoOculto()'

becauseithidesinheritedmember'ClaseBase.MetodoOculto()'

Hiding.cs(4,14):(Locationofsymbolrelatedtopreviouswarning)
Elerrorprincipalesquenosehaceusodelmodificadornew,yaquesiesposibleocultarunmtodocontenidoenlaclase
base:

usingSystem;

classClaseBase{

publicvoidMetodoOculto(){//MtodoOculto

Console.WriteLine("HidingMethods");

classClaseDerivada:ClaseBase{//Clasederivadadelaclasebase

newpublicvoidMetodoOculto(){//MtodoOculto

Console.WriteLine("HidingMethodsusingnew");

classHidingClassMet{

publicstaticvoidMain(){
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

32/63

14/2/2015

Manuales.NET:ManualC#

ClaseDerivadaMiClaseDerivada=newClaseDerivada();

MiClaseDerivada.MetodoOculto();

}
Al hacer uso del modificadornew, se le indica al compilador que se est redefiniendo el mtodo de la clase base y que
deberaocultarestemtodo.
Sepuedeasegurardeinvocarelmtodoqueredefinelaclasederivadautilizandolasiguientesintaxis:
((ClaseBase)MiClaseDerivada).MetodoOculto();
Propiedades
Laspropiedadessonconvenientesparasepararlainterfazdeunobjetodesuimplementacin,envezdepermitiraun
usuario acceder directamente a un campo o arreglo, una propiedad permite especificar a un conjunto de sentencias
realizarelaccesomientrassepermitautilizarelcampooarreglo.

classNombreClase{

intiNombrePropiedad;//declaracindelapropiedad

//Especificacindelaccesoalapropiedad

publicintNombrePropiedad{

get{returniNombrePropiedad;}

set{iNombrePropiedad=value;}

}
Ejemplo:

usingSystem;

classPropiedades{

privateintiEdad;

publicintEdad{

get{returniEdad;}

set{iEdad=value;}

privatestringsNombre;

publicstringNombre{

get{returnsNombre;}

set{sNombre=value;}

privateboolbMexicano;

publicboolMexicano{

get{returnbMexicano;}

set{bMexicano=value;}

publicstaticvoidMain(){

PropiedadesCiudadano=newPropiedades();

Ciudadano.Edad=33;

Console.WriteLine("EdadCiudadano:"+Ciudadano.Edad);

Ciudadano.Nombre="GerardongelesNava";

Console.WriteLine("NombreCiudadano:"+Ciudadano.Nombre);

Ciudadano.Mexicano=true;

Console.WriteLine("MexicanoCiudadano:"+Ciudadano.Mexicano);

}
Existendosmanerasdeexponerelnombredelosatributos:
Campos(fields)
Propiedades(properties)
Losatributossonimplementadoscomovariablesmiembroconaccesopblicoviaaccessors(getoset).
Losaccessors(getoset)especificanlassentenciasquesonejecutadascuandoserequiereleeroescribirelvalordeuna
propiedad.
Losaccessorsparalalecturadelvalordeunapropiedadsonmarcadosconlapalabrareservadagetylosaccessorspara
modificarelvalordeunapropiedadsonmarcadosconlapalabrareservadaset.
Elsiguienteejemplomuestracomoseimplentanlosaccessorsparalaspropiedades:

usingSystem;
classPersona{

privateintiSueldo;

publicintSueldo{

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

33/63

14/2/2015

Manuales.NET:ManualC#

get{returniSueldo;}

set{iSueldo=value;}

classAplicPersona{

publicstaticvoidMain(){

PersonaEmpleado=newPersona();

Empleado.Sueldo=33;

Console.WriteLine("Edad:"+Empleado.Sueldo);

}
Note,queseutilizaelparmetrovalue,yaqueelvaloractualesalmacenadoenestequeesaccesibledentrodelaclase.
Sienvezdeutilizarpropiedadesdeseautilizarcamposdeberdejarfueralosaccessorsyredefinirlavariablecomo:
publicintSueldo;
Accessors
Es posible ocultar los detalles de la estructura de almacenamiento de la clase reordenando losaccessors, en este caso
elaccessorssetespasadoenelnuevovalorparalapropiedadenelparmetrovalue.
Lasoperacionesquepuedenrealizarseconlosatributosson:
Implementargetyset,esposibleteneraccesoalvalordelapropiedadparaleerloyescribirlo.
getonly,sloesposibleleerelvalordelapropiedad.
setonly,sloesposibleestablecerelvalordelapropiedad.
PropiedadesEstticas
Propiedadesestticasnopuedenserdeclaradasconlosmodificadoresvirtual,abstractuoverride.
Laspropiedadesestticaspuedenserinicializadashastaqueseanecesariohacerlo,elvalorpuedeserfabricadocuandose
necesitesinalmacenarlo.

usingSystem;

classPersona{

intiPiernas;

intiBrazos;

intiOjos;

publicPersona(intpiernas,intbrazos,intojos){

this.iPiernas=piernas;

this.iBrazos=brazos;

this.iOjos=ojos;

publicstaticPersonaPiernas{

get{

return(newPersona(2,0,0));

publicstaticPersonaBrazos{

get{

return(newPersona(0,4,0));

publicstaticPersonaOjos{

get{

return(newPersona(0,0,8));

classApp{

publicstaticvoidMain(){

PersonaET=Persona.Piernas;

Console.WriteLine(ET);

}
ndices
Esposibleincluirunaformadeaccesoindexadoalaclasetalcomosilaclasesetratardeunarreglo,paraelloseutiliza
lacaractersticadeC#indexer,sintaxis:
atributosmodificadoresdeclarador{instrucciones}
Los ndices oindexers regresan o establecen un string en un ndice dado, los indexers no tienen atributos por lo que
utilizanelmodificadorpublic.
Lapartedeldeclaradorconsistedeltipostringylapalabrareservadathisparadenotarelindexerdelaclase:

publicstringthis[intiIndex]{

get{intrucciones}
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

34/63

14/2/2015

Manuales.NET:ManualC#

set{intrucciones}

}
Lasreglasdeimplementacinparagetysetsonlasmismasreglasdelaspropiedades,lanicadiferenciaesquelalista
deparmetrossedefinelibrementeentreloscorchetes,tambinexistenrestriccionescomoqueesnecesarioespecificar
almenosunparmetroylosmodificadoresrefyoutnoestnpermitidos.
Ejemplo:

usingSystem;

usingSystem.Net;//DirectivanamespaceparalaclaseDNS

classResolverDNS{

IPAddress[]aIPs;

publicvoidResolver(stringstrHost){

IPHostEntryIPHE=Dns.GetHostByName(strHost);

aIPs=IPHE.AddressList;

publicIPAddressthis[intiIndex]{

get{returnaIPs[iIndex];}

publicintContador{

get{returnaIPs.Length;}

classAplicResolverDNS{

publicstaticvoidMain(){

ResolverDNSMiDNS=newResolverDNS();

MiDNS.Resolver("www.informatique.com.mx");

intiContador=MiDNS.Contador;

Console.WriteLine("Seencontro{0}paraelhost",iContador);

for(inti=0;i<iContador;i++){

Console.WriteLine(MiDNS[i]);

}
SielnamespaceparalaclaseDNSnoestcontenidaenlabibliotecacentral,alcompilarincluyalareferenciaalabiblioteca
quelacontiene:
csc/r:System.Net.dll/out:resolver.exeAplicResolverDNS.cs
Losndicespuedentenermsqueunparmetroparasimularunarreglovirtualmultidimensional.
Eventos
Unaclasepuedeusaruneventoparanotificaraotraclaseoclasesquealgoocurrio,loseventosusanelidioma"publish
subscribe", ya que una clase publica el evento que puede lanzar y las clases que estn interesadas en un evento
especficopuedensubscribiralevento.
Larutinaotareaqueuneventopodrainvocaresdefinidaporundelegado.
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
acercadeleventoelcualsiemprederivadelaclaseEventArgs.
Loseventospuedenserdeclaradoscomocamposopropiedadesdeclase,ambosaccesoscompartenlacomodidaddetipo
queeleventodebetenerdelegate.
Cadaeventopuedeserutilizadoporceroomsclientesyunclientepuedeutilizaruneventoencualquiermomento.
Losdelegadospuedenserimplementadoscomomtodosoinstanciasestticas.
Modificadores
Losmodificadorespuedenclasificarseen:
ModificadoresdeClase
ModificadoresMiembro
ModificadoresdeAcceso
ModificadoresdeClase
Existendostiposdemodificadoresdeclase:
abstract
Unaclaseabstractanopuedeserinicializada
Sloclasesderivadasquenosonabstractaspuedenserinicializadas
Lasclasesderivadasdebenimplementartodoslosmiembrosabstractosdelaclasebaseabstracta
Nopuedeaplicarseunmodificadorsealedaunaclaseabstracta
sealed
Clasessealednopuedenserheredadas
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

35/63

14/2/2015

Manuales.NET:ManualC#

Utiliceestemodificadorparaprevenirherenciaaccidental
Ejemplo:

usingSystem;

abstractclassClaseAbstracta{

abstractpublicvoidMiMetodo();

sealedclassClaseDerivada:ClaseAbstracta{

publicoverridevoidMiMetodo(){

Console.WriteLine("Clasesealed");

publicclassModificadorClase{

publicstaticvoidMain(){

ClaseDerivadaCD=newClaseDerivada();

CD.MiMetodo();

}
ModificadoresMiembro
Algunosmodificadoresmiembroson:
abstract
Indicaqueunmtodooaccessornocontieneunaimplementacin,quesonimplicitamentevirtual.
Laclasequerecibelaherenciadebeproveerlapalabrareservadaoverride.
const
Estemodificadoraplicaacamposyvariableslocales
Laexpresinconstanteesevaluadaentiempodecompilacin,porlotantonopuedecontenerreferencias
delaclase.
event
Defineuncampoopropiedadcomotipoevent
Utilizadoparaligaralcdigoclienteaeventosdelaclase
extern
Indicaalcompiladorqueelmtodoesimplemetadoexternamente
override
Utilizadoparamodificarunmtodooaccessorqueesdefinidovirtualencualquieradelasclasesbase
Lafirmaderedefinicinymtodobasedebeserelmismo
readonly
Un campo declarado con el modificador readonly puede ser cambiado slo en su declaracin o en el
constructordelaclasecontenedora
static
Miembrosquesondeclaradosstaticpertenecenalaclaseynoaunainstanciadelaclase
Puedenutilizarsemodificadoresstaticconcampos,mtodos,propiedades,operadoresyconstructores.
virtual
Indicanqueunmtodooaccessorpuedenserredefinidosporlasclasesquerecibenlaherencia.
ModificadoresdeAcceso
Losmodificadoresdeaccesodefinenelniveldeaccesoqueciertocdigotieneenlosmiembrosdelaclasecomomtodos
ypropiedades.Esnecesarioaplicarelmodificadordeaccesodeseadoacadamiembro,deotraformaeltipodeaccesopor
defaultesimplcito.
Losmodificadoresdeaccesoson:
public,elmiembroesaccesibledesdecualquierparte,estemodificadordeaccesoeselmenosrestrictivo.
protected,elmiembroesaccesibleenlaclaseytodaslasclasesderivadas.Noespermitidoelaccesodesde
fuera.
Elaccesoprotectedpermiteaotrasclasesdependerdelaimplementacininternadelaclaseyporlotanto
deberanserotorgadosslocuandoseanecesario.
private, slo el cdigo dentro de la misma clase puede acceder este miembro. Las clases derivadas no
puedenaccederalcdigo.
internal,estetipodeaccesoesotorgadoatodoelcdigoqueespartedelmismocomponente(aplicacino
biblioteca).NET,esvistocomopblicoaniveldelcomponente.NETyprivadofueradeeste.Estemodificador
permitequeunmiembroseaaccesibledesdelasclasesenelmismoensamblaje, pero no desde las clases
fueradeeste.
Elmodificadorinternalprotectedproveemayorflexibilidadencomounaclaseesdefinidayseutilizapara
indicarqueunmiembropuederseraccedidodesdeunaclaseinternaloprotected,enotraspalabrasinternal
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

36/63

14/2/2015

Manuales.NET:ManualC#

protectedpermiteaccesointernaloprotected.
SentenciasdeControl
LasSentenciasdeControlseempleanparacontrolarlaejecucinyflujodelcdigo,lascualessedividenen:
SentenciasdeSeleccin
SentenciasdeIteracin
SentenciasdeSeleccin
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
condicindada,existendostiposdesentenciasdeseleccin:
Sentenciaif
Sentenciaswitch
Sentenciaif
Alescribirunoovariosflujosdeaccinelcdigocontenidoenestosseejecutarsiempreycuandolaevaluacindela
expresinenlasentenciaifseevaluecomoverdadera(tengacuidadoenC#if(0){}oif(1){}noesvlido).
if(expresinbooleana){laexpresinseevaluoverdadera}
Esposibleindicarcdigoalternoencasodequelaexpresinbooleanaseevaluefalsa:

if(expresinbooleana){

laexpresinseevaluoverdadera
}else{

laexpresinseevaluofalsa

}
NotaC#nopuedeconvertirvaloresnumricosabooleanos,solopuedehacercomparacionesentreellosparaevaluarel
resultadodelaexpresinelcualesunvalorbooleano.

usingSystem;

classSeleccionIf{

publicstaticvoidMain(){

if(1==1){

Console.WriteLine("seevaluoverdadero");

/*NoessoportadoporC#

if(0){

Console.WriteLine("?");

*/

}
NotaeloperadordeigualdadenC#es==,siesthabituadoaotraforma,seracosatiempoacostumbrarseaescribirlo
correctamente,enlasiguientetablasemuestranlosoperadoresvlidosenC#:
Operador

Evalua

==

Verdadero,siambosvaloressonlosmismos

!=

Verdadero,silosvaloressondiferentes

<,<=,>,>= Verdadero,sielvalorcumpleconlacondicin

Losoperadoresdelatablasonimplementadosvialasobrecargadeoperadoresylaimplementacinesespecificaparael
tipodedato,sisecomparandosvariablesdediferentetiposerealizaunaconversinimplcitaquedebeexistirparaqueel
compiladorcreeelcdigonecesarioautomticamente.Recuerdequesiemprepodrrealizaruncastexplcito.
Ejemplo

usingSystem;

classCaracteres{

publicstaticvoidMain(){

stringsNombre="GerardoAngelesNava";

charchLetra=sNombre[0];//Extraeelprimercaracterdelstring

if(Char.IsDigit(chLetra)){

Console.WriteLine(chLetra+"esundgito");

}else{

EsMayuscula(chLetra);

EsMinuscula(chLetra);

chLetra=sNombre[1];//Extraeelsegundocaracterdelstring

if(Char.IsDigit(chLetra)){

Console.WriteLine(chLetra+"esundgito");
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

37/63

14/2/2015

Manuales.NET:ManualC#

}else{

EsMayuscula(chLetra);

EsMinuscula(chLetra);

sNombre="123";

chLetra=sNombre[2];//Extraeeltercercaracterdelstring

if(Char.IsDigit(chLetra)){

Console.WriteLine(chLetra+"esundgito");

}else{

EsMayuscula(chLetra);

EsMinuscula(chLetra);

publicstaticvoidEsMayuscula(charchCaracter){

if(chCaracter>='A'&&chCaracter<='Z'){

Console.WriteLine(chCaracter+"mayscula");

publicstaticvoidEsMinuscula(charchCaracter){

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
claseChar,tambinsemuestracomodeterminarsiuncaractercorrepondealasletrasmaysculasominsculas.
GoodPractice:nuncaasignevaloresavariablesdentrodeunacondicinqueutilizaoperadoreslgicos(&&,||,!), 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))){}
Enelejemploanterior,silaexpresina==bseevaluaverdaderaentonceslavariableiValornuncacontendrelvalord.
Sentenciaswitch
La sentencia de seleccin switch tiene una expresin de control y los flujos de cdigo alternos son ejecutados
dependiendodelvalorconstanteasociadoconestaexpresin.

switch(expresiondecontrol){

caseexpresioncontante:

sentencias;

break;

caseexpresioncontante:

gotocase2;

caseexpresioncontante:

gotodefault;

default:

sentencias;

}
Los
tipos
de
datos
permitidos
para
la
expresin
de
control
sonsbyte,byte,short,ushort,uint,long,ulong,char,stringountipoenumeracin(enumeration).
Cmofuncionalasentenciadeseleccinswitch?
Seevalualaexpresindecontrol
Silaexpresinconstanteenlasetiquetascasecoincide con el valor evaluado en la expresin de control,
entonceslassentenciascontenidasparaesecasosonejecutadas
Silaexpresinconstanteenlasetiquetascasenocoincideconelvalorevaluadoenlaexpresindecontrol,
entonceselcdigocontenidoenelcasopordefaultesejecutado
Silaexpresinconstanteenlasetiquetascasenocoincideconelvalorevaluadoenlaexpresindecontrol
ynoexisteuncasopordefault,entonceselcontrolestransferidoalfinaldelbloqueswitch
Ejemplo:

usingSystem;
classSentenciaSwitch{

publicstaticvoidMain(){

for(inti=0;i<=12;i++){

Mes(i);

publicstaticvoidMes(intiMes){

switch(iMes){

case1:

Console.WriteLine("Enero");

break;

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

38/63

14/2/2015

Manuales.NET:ManualC#

case2:

Console.WriteLine("Febrero");

break;

case3:

Console.WriteLine("Marzo");

break;

case4:

Console.WriteLine("Abril");

break;

case5:

Console.WriteLine("Mayo");

break;

case6:

Console.WriteLine("Junio");

break;

case7:

Console.WriteLine("Julio");

break;

case8:

Console.WriteLine("Agosto");

break;

case9:

Console.WriteLine("Septiembre");

break;

case10:

Console.WriteLine("Octubre");

break;

case11:

Console.WriteLine("Noviembre");

break;

case12:

Console.WriteLine("Diciembre");

break;

default:

Console.WriteLine("Mesnovlido");

break;

}
Esposibleutilizarsentenciasgotodentrodelswitchdelasiguientemanera:
gotocaseexpresioncontante
gotodefault
Ejemplo:

usingSystem;
classSentenciaSwitch{

publicstaticvoidMain(){

intiOpcion=4;

Opcion(iOpcion);

iOpcion=2;

Opcion(iOpcion);

iOpcion=8;

Opcion(iOpcion);

iOpcion=10;

Opcion(iOpcion);

publicstaticvoidOpcion(intiValor){

switch(iValor){

case2:

gotocase6;

case4:

Console.WriteLine("cuatro");

break;

case6:

Console.WriteLine("seis");

break;

case8:

gotodefault;

case10:

Console.WriteLine("diez");

break;

default:

Console.WriteLine("pordefecto");

break;

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

39/63

14/2/2015

Manuales.NET:ManualC#

}
SentenciasdeIteracin(repeticin)
LasSentenciasdeIteracin(tambinconocidascomoloopingstatements)sonaquellasquenospermitenejecutarun
bloquedecdigorepetidamentemientrasunacondiconespecficaseaverdadera:
for
foreach
while
do
Sentenciafor
La Sentencia for se utiliza cuando se conoce previamente cuantas veces ha de repetirse un bloque de cdigo. Este
bloqueserepetiramientraslacondicinevalueunaexpresinbooleanaverdadera,noserposibleevaluarotrotipode
expresin.
Sintaxis:
for(inicializador;condicin;iterador)
Loscomponentesdelasentenciafor:inicializador,condicin,iterador,nosonobligatorios.
Esposiblesalirdeuncicloforatravsdelasinstrucciones:
break
goto
Ejemplo:

usingSystem;
classFactorial{
publicstaticvoidMain(string[]aArgs){

if(aArgs.Length==0){

Console.WriteLine("Debeproporcionarunargumento,Ejemplo:Factorial5");

return;

longlFactorial=1;

longlCalcular=Int64.Parse(aArgs[0]);

longlAux=1;

for(lAux=1;lAux<=lCalcular;lAux++){

lFactorial*=lAux;

//TestLineConsole.WriteLine("{0}!*{1}",lAux,lFactorial);

Console.WriteLine("{0}!es{1}",lCalcular,lFactorial);

}
Sentenciaforeach
LaSentenciaforeachesuncomandoparaenumerarloselementosdeunacoleccin.
foreach(Tipoindentificadorinexpresin){}
LavariabledeiteracinesdeclaradaporelTipo,indentificadoryexpresincorrespondientealacoleccin.
Lavariabledeiteracinrepresentaelelementodelacoleccinparacadaiteracin.
Elsiguienteejemplomuestraelusodefor:

usingSystem;

classApp{

publicstaticvoidMain(string[]aArgs){

for(inti=0;i<aArgs.Length;i++){

Console.WriteLine("Elemento"+i+"="+aArgs[i]);

}
Elejemploanteriorimplementadoconforeach:

usingSystem;

classApp{

publicstaticvoidMain(string[]aArgs){

foreach(StringsinaArgs){

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
parmetrorefoout.
Para que una clase soporte la sentenciaforeach, la clase debe soportar un mtodo con la firmaGetEnumerator() y la
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

40/63

14/2/2015

Manuales.NET:ManualC#

estructura,claseointerfacequeregresadebetenerunmtodopblicoMoveNextyunapropiedadpblicaCurrent.
En el siguiente ejemplo el mtodo GetEnvironmentVariables() regresa una interfaz de tipo IDictionary. Es posible
accederalascoleccionesKeysyValuesdelainterfazIDictionary:

usingSystem;

usingSystem.Collections;

classSentenciaForEach{

publicstaticvoidMain(){

IDictionaryVarsAmb=Environment.GetEnvironmentVariables();

Console.WriteLine("Existen{0}variablesdeambientedeclaradas",VarsAmb.Keys.Count);

foreach(StringstrIteradorinVarsAmb.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
puedeserdetectadoporelcompilador,perosidetectadoentiempodeejecucinycausarunaexcepcin.
Sentenciawhile
LaSentenciawhileseutilizacuandonoseconocepreviamentecuantasveceshaderepetirseunbloquedecdigo,por
lo que puede ejecutarse 0 o ms veces. Este bloque se repetira mientras la condicin evalue una expresin booleana
verdadera,noserposibleevaluarotrotipodeexpresin.
while(condicional){}
Ejemplo:

usingSystem;

usingSystem.IO;

classSentenciaWhile{

publicstaticvoidMain(){

if(!File.Exists("test.html")){

Console.WriteLine("Elarchivotest.htmlnoexiste");

return;

StreamReaderSR=File.OpenText("test.html");

StringstrLinea=null;

while(null!=(strLinea=SR.ReadLine())){

Console.WriteLine(strLinea);

SR.Close();

}
Esposibleutilizarlasentenciabreakparasalirdelcicloocontinueparasaltarunaiteracin.
Sentenciado
La diferencia entre la sentencia while y do es que do se evalua despus de su primer iteracin, por lo que al menos
siempreseejecutaunavez:

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
sentenciacontinue
Elsiguienteejemplolelaentradadelaconsolatomaelprimercaracterleido,loconvierteenunTipodoubleysumasu
valormientraslaentradasea's'ohastaquelaentradasea'n'.

usingSystem;
classConsola{

publicstaticvoidMain(){

ConsolaLeerDatos=newConsola();

LeerDatos.Run();

publicvoidRun(){

charchContinuar='s';

stringstrDatos;

doubledSuma=0;

do{

Console.Write("Proporcioneunnmero:");

strDatos=Console.ReadLine();

dSuma+=Double.Parse(strDatos);

Console.Write("Continuars/n?");

strDatos=Console.ReadLine();

chContinuar=strDatos[0];

if(chContinuar=='n')break;

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

41/63

14/2/2015

Manuales.NET:ManualC#

}
SentenciasdeSalto

}while(chContinuar=='s');
Console.WriteLine("Lasumadelosnmeroses:"+dSuma);

LasSentenciasdeSaltocomobreak,continue,gotoyreturnsirvenparairdeunasentenciaaotra
break
La Sentencia break es utilizada para salir de la iteracin en curso o sentencia switch y continuar con la ejecucin
despusdeesasentencia.
continue
LaSentenciacontinuesaltatodaslassentenciassiguientesenlaiteracinencursoyentoncescontinualaejecucinen
lasentenciadeiteracin(siguienteiteracin).
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
transferirelcontrolfueradeunloopanidado.
Nota,comobuenaprcticanoserecomiendaelusodegoto.
return
LaSentenciareturnregresaalafuncininvocadorayopcionalmenteretornaunvalor.
AsignacinDefinitiva
Las reglas de Asignacin definitiva previenen la observacin del valor de una variable no asignada, ya que C# no
permiteutilizarvariablesquenohansidoinicializadas,ascomotambinnopuedenrealizarseoperacionesconvariables
declasequenohansidoinicializadas.
Puede accederse al elemento de un arreglo an si no ha sido inicializado, ya que el compilador no puede rastrear la
asignacindefinitivaentodaslassitucaciones.
PrecedenciadeOperadores
Cuando una expresin contiene mltiples operadores, la precedencia de operadores controla el orden en el cual los
elementosdelaexpresinsonevaluados.
Categora
Primary

Operador
(x),x.y,f(x),a[x],x++,x,new,typeof,sizeof,checked,unchecked
+,,!,~,++x,x,(T)x

Unary

*,/,%

Multiplicative

+,

Additive

<<,>>

Shift

<,>,<=,>=,is

Relational

==,!=

Equality
LogicalAND

&

LogicalXOR

LogicalOR

ConditionalAND

&&

ConditionalOR

||

Conditional

?:

Assignment

=,*=,/=,%=,+=,=,<<=,>>=,&=,^=,|=

typeof
Eloperadortypeofregresaeltipodelobjeto,elcualesunainstanciadelaclaseSystem.Type
UnainstanciayaexistentepuedeobtenereltipodeobjetoconelmtododelainstanciaGetType().
is
Eloperadorisesutilizadoparadeterminarcuandounareferenciaaunobjetopuedeserconveritdaauntipoespecfico
ointerface.
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
regresanull.
Utilizarasesmseficientequeutilizaris,porqueasslo necesita checar el tipo del objeto una vez eis checa el tipo
cuandoeloperadoresutilizadoylochecaotravezcuandolaconversinserealiza.
Utilizandois

if(UnObjetoisUnTipo){

UnTipout=(UnTipo)UnObjeto;

}
Utilizandoas

UnTipout=UnObjetoasUnTipo;

if(ut!=null){
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

42/63

14/2/2015

Manuales.NET:ManualC#

sentencias;

Conversiones
En C# lasconversionesse dividen enconversiones explcitas y conversiones implcitas que son aquellas que podran
siempreocurrir:

//conversionesimplcitas

sbytea=55;

shortb=a;

intc=b;

longd=c;

//conversionesexplcitas

c=(int)d;

b=(short)c;

a=(sbyte)b;
AcontinuacinsepresentalajerarquadeconversinenC##
ManejodeExcepciones
Lasexcepcionessonelmtodofundamentaldemanejodecondicionesdeerror.
Ejemplo:

usingSystem;

classDivisionCero{

publicstaticvoidMain(){

intiA=33;

intiB=0;

try{

//Sentenciaquepuedelanzarunaexcepcin

Console.WriteLine("{0}/{1}={2}",iA,iB,iA/iB);

}catch(Exceptione){

//Manejodelaexcepcin

Console.WriteLine("Laoperacin{0}/{1}generolaexcepcion:{2}",iA,iB,e);

Console.WriteLine("Continualaejecucindelcdigo...");

}
El ejemplo encierra el bloque de cdigo que podra lanzar una excepcin contry. En caso de generarse una excepcin
elruntime.NETdetienelaejecucindelcdigoybuscaelbloquetryenelcuallaexcepcintuvolugar,entoncesbuscasi
este bloque tiene relacionado un bloque catch, puede ser que encuentre ms de un bloque catch relacionado al
bloquetryquegenerolaexcepcin,porloquesedeterminaquebloquecatcheselquemejoryejecutaelcdigoque
contiene.
El compilador de C# puede manejar silenciosamente situaciones que podran producir un error sin notificarnos
explicitamentedeello,porejemplounasituacincomounoverflowqueescuandoelclculodeunaoperacinexcedeel
rangovlidoderesultadosposiblesparaeltipodedato.
El caso del cdigo para calcular un factorial, el compilador no prodruce una advertencia, pero si trata de obtener
elfactorialde2000daraporresultado0,elcompiladoractuoenmodosilenciosoporquepordefaultelcompiladortiene
deshabilitadalaopcindechequeodeoverflow.
Esposiblecambiarelcomportamientodechequeodeoverflowutilizandounswitchalcompilar.
JerarquadeExcepciones
TodaslasexcepcionesderivandelaclaseException,lacualespartedellenguajecomnentiempodeejecucin(CLR),
donde la propiedad catch determina por coincidencia el tipo de excepcin a el nombre de la excepcin generada. Un
bloquecatchconunacoincidenciaespecificahacenmsgenerallaexcepcin:

usingSystem;

classExceptionDivision0{

publicstaticvoidMain(){

intiA=33;

intiB=0;

try{

Console.WriteLine("{0}/{1}={2}",iA,iB,iA/iB);

}catch(DivideByZeroException){

Console.WriteLine("Segenerolaexcepcion:DivideByZeroException");

Console.WriteLine("Continualaejecucindelcdigo...");

}
EnesteejemploelbloquecatchqueatrapalaexcepcinDivideByZeroExceptionesunacoincidenciamsespecfica,porlo
que es la nica que ser ejecutada, pero si adems de escribir el catch para DivideByZeroException escribe
elcatchparaException,elcompiladorlenotificaraqueexisteunaexcepcinqueatrapatodaslasexcepcionesyestoes
porqueExceptionocupalacimadelajerarquadetodaslasexcepciones.
TrabajarconExcepciones
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

43/63

14/2/2015

Manuales.NET:ManualC#

Existentresformasbsicasdetrabajarconexcepciones:
CallerBeware
Laprimerformaesnoatraparlaexcepcin,locualprovocardejaralobjetoenunestadoincorrecto,ycausardaos
cuandoelcallertratedeutilizarladenuevo.
CallerConfuse
Lasegundaformaesatraparlaexcepcinytratardehaceraccionesquedejenlaoperacincomoestabahastaantesde
generarselaexcepcinyentoncesrelanzarlaexcepcin,estousualmenteeslomenosqueseesperariadelmanejode
excepcionesyaqueunobjetodeberasiempremantenerunestadovlidodespusdegenerarseunaexcepcin.
Se llama Caller Confuse, porque despus de generase una excepcin, el caller con frecuencia tiene poca informacin
respectoalentendimientodelosdetallesdelaexcepcinocomopodrasersolucionada.
CallerInform
LastercerformaCallerInformagregainformacinqueesdevueltaalusuario,laexcepcinatrapadaesenvueltaenuna
excepcinquetieneinformacinadicional:

usingSystem;

classExcDivZeroInf{

publicstaticvoidMain(){

intiA=33;

intiB=0;

try{

Console.WriteLine("{0}/{1}={2}",iA,iB,iA/iB);

}catch(DivideByZeroExceptione){

Console.WriteLine("Segenerolaexcepcion:DivideByZeroException");

throw(newDivideByZeroException("Informacinadicional...",e));

Console.WriteLine("Continualaejecucindelcdigo...");

}
ChequeodeOverflow
Si requerimos controlar el chequeo de overflow para la aplicacin completa, el compilador de C# debe establecerse
comochecked.Pordefaultelcompiladortienedeshabilitadalaopcindechequeo.
Paraindicarexplicitamentequeelcompiladorchequeeloverflowescriba:
cscFactorial.cs/checked+
Unavezquesecompilodeconlaopcindechequeodeoverflowhabilitado,alintentarobtenerelfactorialde2000de
presentalaventanaJustInTimedebbugingnotificandonosqueocurriounaexcepcinenFactorial.exe:
System.OverflowException
Estetipodesituacionesesposibleatraparlasymanejarlasatravsdelasexcepcionesqueseproducen.
ChequeoprogramticodeOverflow
ExisteotraopcinsiesquenodeseamosactivarelChequeodeOverflowparalaaplicacincompletayhabilitarslamente
partesespecificasdecdigo,paraelloseutilizalasentenciachecked:

usingSystem;
classFactorialChecked{
publicstaticvoidMain(string[]aArgs){

if(aArgs.Length==0){

Console.WriteLine("Debeproporcionarunargumento,Ejemplo:Factorial5");

return;

longlFactorial=1;

longlCalcular=Int64.Parse(aArgs[0]);

longlAux=1;

for(lAux=1;lAux<=lCalcular;lAux++){

checked{lFactorial*=lAux;}//Habilitarchequeodeoverflow

//TestLineConsole.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
especificasdecdigo,paraelloseutilizalasentencia:
unchecked{sentencias;}
SentenciasparaelManejodeExcepciones
Esposibleatrapar,manejarylimpiarlasexcepcionesqueseproducenutilizandolassentenciassiguientes:
trycatch
tryfinally
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

44/63

14/2/2015

Manuales.NET:ManualC#

trycatchfinally
trycatch
Para evitar que se muestre el mensaje que indica que una excepcin ocurrio, es necesario atrapar la excepcin y lo
mejordetodoesquecontinuelaejecucindelprograma,paraelloseutilizatryycatch.
trycontieneelcdigoquequizpuedalanzarunaexcepcinycatchmanejalaexcepcinsiestaocurre:

try{

//sentenciasquepuedenlanzarunaexcepcin

}catch(nombreExcepcin){

//manejodelaexcepcin

}
ElsiguienteejemplomanejalaexcepcinFileNotFoundExceptionqueseproducecuandoseintentamanipularunarchivo
quenoexiste,siestoocurresepresentaunmensajequemuestraelnombredelarchivoqueseintentomanipularyno
seencontroatravsdeunapropiedadpblicadelaexcepcinllamadaFileName.

usingSystem;

usingSystem.IO;

classSentenciaWhile{

publicstaticvoidMain(){

try{

StreamReaderSR=File.OpenText("test.html");

StringstrLinea=null;

while(null!=(strLinea=SR.ReadLine())){

Console.WriteLine(strLinea);

SR.Close();

}catch(FileNotFoundExceptione){//Encasodequeelarchivonoexista

Console.WriteLine("Noseencontroelarchivo:"+e.FileName);

return;

}
tryfinally
Esposiblelimpiarelmanejodeerroresutilizandotryyelconstructorfinally,sineliminarelmensajedeerror,peroel
cdigocontenidoenelbloquefinallyesejecutadoandespusdeocurrirunaexcepcin.
Elsiguientecdigomanejaunavariablebooleanaqueindicasiseprodujounerror,simplementeponiendoladentrodel
bloquetry,sielcdigocontenidofuejecutadolavariablebooleanaesfalselocualindicaquenoocurrieronexcepciones,
sielbloquenoseejecutolavariablebooleanamantienesuvaloriniciallocualsignificaquesiocurrieronexcepcionesy
entonces se ejecuta el bloque Finally el cual evalua el valor de la variable booleana y presenta la indicacin
correspondiente.

usingSystem;

usingSystem.IO;

classSentenciaTryFinally{

publicstaticvoidMain(){

boolbExcepcion=true;

try{

StreamReaderSR=File.OpenText("test.html");

StringstrLinea=null;

while(null!=(strLinea=SR.ReadLine())){

Console.WriteLine(strLinea);

SR.Close();

bExcepcion=false;

finally{

if(bExcepcion){

Console.WriteLine(">>>Noseencontroelarchivo");

}else{

Console.WriteLine(">>>Noocurrieronexcepciones");

}
Notequeencasodenoexistirelarchivoseproduceunaexcepcinysepresentaelmensajequeindicaquehaocurrido
una excepcin pero tambin fu ejecutado el bloque finally, el cdigo que contiene el bloque finally siempre es
ejecutadoocurraonounaexcepcin.
Puedeemplearlasentenciafinallyparareestablecerlosvalorespreviosalageneracindelaexcepcin.
trycatchfinally
Combinar try para controlar el cdigo que puede lanzar excepciones, atrapar la excepcin con catch y llevar acabo
instruccionesnecesariasconfinallyhacenunamejorsolucincuandoocurrenlasexcepciones.
Es posible utilizar una sentencia catch por cualquier excepcin que pudiera ocurrir, es decir, tener ms de un
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

45/63

14/2/2015

Manuales.NET:ManualC#

bloque catch, pero es necesario conocer la jerarqua de las excepciones porque puede ocurrir que un bloque
previocatchseamsgeneralycontengatodaslasexcepcioneslocualproduciriaunerror.

usingSystem;

usingSystem.IO;

classSentenciaTryCatchFinally{

publicstaticvoidMain(){

boolbExcepcion=true;

boolbModificacion=false;

try{

bModificacion=true;

StreamReaderSR=File.OpenText("test.htmlX");

StringstrLinea=null;

while(null!=(strLinea=SR.ReadLine())){

Console.WriteLine(strLinea);

SR.Close();

bExcepcion=false;

}catch(FileNotFoundExceptione){//Encasodequeelarchivonoexista

Console.WriteLine("Noseencontroelarchivo:"+e.FileName);

return;

finally{

if(bExcepcion){

bModificacion=false;//Valorantesdegenerarselaexcepcin

if(!bModificacion){

Console.WriteLine("Entroenmodomodificacin,_

perolasmodificacionesnoserealizaron");

Console.WriteLine("Causa:Noseencontroelarchivo");

}else{

Console.WriteLine("Noocurrieronexcepciones");

}
LanzamientodeExcepciones
Paraatraparunaexcepcinconlasentenciacatchprimerodebegenerarselaexcepcin,peroesposiblequeatravsde
codigoselanzeoinvoqueunaexcepcin:
thrownewNombreExcepcion(excepcion);
Elpoderlanzaroinvocarunaexcepcinesutilcuandonosehacontempladociertoescenariooparanuevosescenarios,al
crearunaclasepodriancrearsetambinexcepcionespropiasdeestaclase.
Acontinuacinsepresentaunatablaquecontienelasexcepcionesestndarqueproveeelruntime:
Tipo

Descripcin

Exception

Clasebaseparatodaslosobjetosexception

SystemException

Clasebaseparatodosloserroresgeneradosentiempodeejecucin

IndexOutRangeException

Lanzadaentiempodeejecucincuandoelndicedeunarregloestfueraderango

NullreferenceException

Disparadaentiempodeejecucincuandounobjetonullesreferenciado

InvalidOperationException

Lanzadaporciertosmtodoscuandoinvocanamtodosquesoninvlidosparael
estadodelosobjetosactuales

ArgumentException

Clasebasedetodoslosargumentosdelasexcepciones

ArgumentNullException

Lanzada por un mtodo, en caso de que un argumento sea null cuando no sea
permitido

ArgumentOutOfRangeException Lanzadaporunmtodocuandounargumentonoestenelrangopermitido
InteropException

Clase base para excepciones que son originadas u ocurren en ambientes fuera
delCLR

ComException

ExcepcinquecontieneinformacinHRESULTCOM

SEHException

Excepcin que encapsula informacin del manejo de excepciones destructurada


Win32

RelanzamientodeExcepciones
Elsiguientecdigomuestracomoesposibleatraparunaexcepcin,manejarlaysevolverlaainvocar:

usingSystem;

classFactorialCheckedReThrow{

publicstaticvoidMain(string[]aArgs){

if(aArgs.Length==0){

Console.WriteLine("Debeproporcionarunargumento,Ejemplo:Factorial5");

return;

}
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

46/63

14/2/2015

Manuales.NET:ManualC#

longlFactorial=1;

longlCalcular=Int64.Parse(aArgs[0]);

longlAux=1;

try{

checked{//Habilitarchequeodeoverflow

for(lAux=1;lAux<=lCalcular;lAux++){

lFactorial*=lAux;

//TestLineConsole.WriteLine("{0}!*{1}",lAux,lFactorial);

}
}catch(OverflowException){

Console.WriteLine("Elfactorial{0}!causounaexcepcin",lCalcular);

throw;
}
Console.WriteLine("{0}!es{1}",lCalcular,lFactorial);
}
}

CreacindeClasesException
Es recomendable utilizar las clases predefinidas para excepciones, para ciertos escenarios es posible crear clases de
excepcionesapropiadas,porejemplocuandocreamosunaclase,tambinpodemoscrearexcepcionesparaestaclase,esto
esconvenientecuandoseutilizalaclaseymanejarposiblesescenariosdeerrorconlasclasesdeexcepcionescreadas.

usingSystem;

publicclassMiExcepcion:Exception{

publicMiExcepcion(stringstr):base(str){}

publicclassAplicMisExcepciones{

publicstaticvoidProbar(){

thrownewMiExcepcion("ocurriounerror");

publicstaticvoidMain(){

try{

AplicMisExcepciones.Probar();

}catch(Exceptione){

Console.WriteLine(e);

}
Sedebentomarciertasconsideracionesalcrearexcepciones:
Allanzarunaexcepcinsedebeproporcionaruntextosignificativo
Lanzarexcepcionessolocuandosepresenteunacondicinrealmenteexcepcional
LanzarunArgumentExceptionsielmtodoopropiedadenviomallosparmetros
LanzarunInvalidOperationExceptioncuandolaoperacininvocadanoesapropiadaparaelestadoactualde
losobjetos
Lanzarlaexcepcinmsapropiada
Usarexcepcionesencadenadas
Noutilizarexcepcionesparaerroresesperadosonormales
Nousarexcepcionesparacontroloflujonormal
NolanzarNullReferenceExceptionoIndexOutOfRangeExceptionenmtodos
Componentes
Ascomoesposibleescribirclasesyhacerusodeestasenunmismoarchivo,tambinesposibleescribirenunarchivo
(ejecutable)unicamentelaclaselocualesconocidocomocomponenteyenotroarchivo(tambinejecutable)elusode
laclaselocualesconocidocomocliente.
CreacindeComponentes
ParacrearuncomponenteunicamenteesnecesarioescribirlaClasecontodossusmiembros(Constructores,Propiedades,
Mtodos),almacenarlaenunarchivoycompilarelcomponente.

usingSystem;
publicclassClsPersona{

privateintiSueldo;

publicintSueldo{

get{returniSueldo;}

set{iSueldo=value;}

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

47/63

14/2/2015

Manuales.NET:ManualC#

publicstringsNombre;

publicvoidAsignarNombre(stringsValor){

sNombre=sValor;

publicstringObtenerNombre(){

returnsNombre;

}
CompilacindeComponentes
Alcompilaruncomponentesecreaunabibliotecaynosecreaunaaplicacin,comoeselcasocuandosetrabajaenun
sloarchivolaclaseylaaplicacinquehaceusodelaclase:
csc/t:library/out:ClsPersona.dllClsPersona.cs
Siutilizanombresdeespacio:
csc/r:System.nombreBiblioteca.dll/t:library/out:NombreComponente.dllNombreComponente.cs
Dondeelswitch/t:libraryindicaalcompiladordeC#crearunabibliotecaynobuscarelmtodoestticoMain.
Si su clase requirio de nombres de espacio (namespace) es necesario hacer referencia a estas bibliotecas mediante
elswitch/r:NombreBiblioteca.dll
Recuerdequeelswitch/outnoesobligatorioyaqueseutilizaparaespecificarunnombredistintoalnombredelarchivo
fuente,aunqueesbuenaprcticaespecificarloyaquealgunasaplicacionesnoslotienenunarchivofuente,entoncesel
compiladorpodrallamaralabibliotecaconelprimernombredearchivofuenteenlalista.
UnavezquehacompiladosucomponentepuedeescribirunaAplicacinCliente.
CreacindeunaAplicacinCliente
Parahacerusodeloscomponentescreadosesposiblecrearaplicacionesclientedondesecreeninstanciasdelasclases
creadas:

usingSystem;

classAplicClsPersona{

publicstaticvoidMain(){

ClsPersonaEmpleado=newClsPersona();

Empleado.Sueldo=33;

Console.WriteLine("Edad:"+Empleado.Sueldo);

Empleado.AsignarNombre("GerardongelesNava");

Console.WriteLine("Nombre:"+Empleado.ObtenerNombre());

}
CompilacindeClientes
EsnecesarioindicarlealcompiladorunareferenciaalanuevabibliotecadecomponentesDLL:
csc/r:NombreComponente.dllNombreCliente.cs
Notaparahacerusodeunaclaseesnecesarioquetengaelmodificadordeaccesopublic.
Namespaces
Los nombres de espacionamespaceenel runtime .NET son utilizados para organizar las clases y otros tipos en una
estructura jerarquica. El propsito del uso denamespace hacen las clases fciles de usar y prevenir colisiones con las
clasesescritasporotrosprogramadores.
LosnamespaceenC#seutilizanparaorganizarprogramasylajerarquanaturaldelaorganizacinfacilitapresentarlos
elementosdeunprogramaaotrosprogramas.Losnamespacesonutilesparalaorganizacininternadeaplicaciones.
Un namespace contiene tipos que pueden ser utilizados en la construccin de programas: clases, estructuras,
enumeraciones,delegadoseinterfaces,porejemploparapoderescribiralaconsolaseutilizaelnamespaceSystem.
No es obligatorio jerarquizar los namespace pero es una buena prctica organizar los namespace creados de manera
jerarquicaparadarclaridadalaaplicacin.
Losnombresdeespaciosondefinidosutilizandolasentencia:
namespace
Paramltiplesnivelesdeorganizacinlosnamespacespuedenseranidados:

namespaceNombreNamespaceA{

namespaceNombreNamespaceB{

classNombreClase{

publicstaticvoidFunction(){}

}
Elcdigoanteriorpuedesersimplificadodelasiguientemanera:

namespaceNombreNamespaceA.NombreNamespaceB{

classNombreClase{

publicstaticvoidFunction(){}

}
}

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

48/63

14/2/2015

Manuales.NET:ManualC#

Lascolisionesentretiposonombresdeespacioquetienenelmismonombresepuedenresolverutilizandounavariante
delaclusulausingquepermitedefinirunaliasparalaclase:

usingAlias=System.Console;

classNombreClase{

publicstaticvoidMain(){

Alias.WriteLine("Aliasdeunaclase");

}
EnvolverClasesenNamespace
Es posible envolver (wrapping) las clases en un namespace, para ello slo es necesario utilizar la palabra
reservadanamespaceseguidadeunnombrequeloidentifiqueyencerrarentrellaveselcdigoquedeseamospertenezcaa
este.

usingNombreOtrosEspacios;

namespaceNombreEspacio{

publicclassNombreClase{

//propiedades

//mtodos

}
Ejemplo:

usingSystem;

namespaceinformatique.com.mx{

publicclassiPersona{

privateintiSueldo;

publicintSueldo{

get{returniSueldo;}

set{iSueldo=value;}

publicstringsNombre;

publicvoidAsignarNombre(stringsValor){

sNombre=sValor;

publicstringObtenerNombre(){

returnsNombre;

}
Compilar:
csc/t:library/out:iPersona.dlliPersona.cs
UtilizarNamespaceenAplicacionesCliente
Aldesarrollarcomponentesutilizandonamespacelaaplicacinclientedebeimportarlo:
usingNombreEspacio;
Otra posibilidad es hacer una referencia absoluta a los elementos del namespace, aunque para evitar conflictos es
preferibleutilizarladirectiva:
Ejemplo:

usingSystem;

usinginformatique.com.mx;

classiAplicClsPersona{

publicstaticvoidMain(){

iPersonaEmpleado=newiPersona();

Empleado.Sueldo=33;

Console.WriteLine("Edad:"+Empleado.Sueldo);

Empleado.AsignarNombre("GerardongelesNava");

Console.WriteLine("Nombre:"+Empleado.ObtenerNombre());

}
Compilar:
csc/r:iPersona.dlliAplicPersona.cs
Especificardemaneraabsolutaelnamespace:

usingSystem;
classiAplicClsPersonaAbs{

publicstaticvoidMain(){

informatique.com.mx.iPersonaEmpleado=newinformatique.com.mx.iPersona();

Empleado.Sueldo=33;

Console.WriteLine("Edad:"+Empleado.Sueldo);

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

49/63

14/2/2015

}
Compilar:

Manuales.NET:ManualC#

Empleado.AsignarNombre("GerardongelesNava");
Console.WriteLine("Nombre:"+Empleado.ObtenerNombre());

csc/r:iPersonaAbs.dlliAplicPersonaAbs.cs
AgregarMltiplesClasesaUnNamespace
Enelpuntoanteriorenvolvimosunaclaseaunnamespace,peroesposibleagregaryenvolvermsclasesocomponentes
almismonamespace,sinimportarqueestencontenidosendiferentesarchivos,despusdelacompilacinsonpartedel
mismonamespace:
csc/t:library/out:NombreComponente.dllarchivoFuente1.csarchivoFuente2.cs
Agregandootraclasealnamespaceinformatique.com.mx:

usingSystem;

namespaceinformatique.com.mx{

classiVehiculo{

privateintiRueda;

privateintiPuerta;

privateintiVentana;

privateintiHelice;

privateintiMotor;

privateintiAsiento;

privatestringsTipo;//Aereo,anfibio,terrestre,espacial

//Constructor

publiciVehiculo(intRueda,intPuerta,intVentana,_

intHelice,intMotor,intAsiento,stringTipo){

iRueda=Rueda;

iPuerta=Puerta;

iVentana=Ventana;

iHelice=Helice;

iMotor=Motor;

iAsiento=Asiento;

sTipo=Tipo;

publicintRuedas{

get{returniRueda;}

set{iRueda=value;}

publicintPuertas{

get{returniPuerta;}

set{iPuerta=value;}

publicintVentanas{

get{returniVentana;}

set{iVentana=value;}

publicintHelices{

get{returniHelice;}

set{iHelice=value;}

publicintMotores{

get{returniMotor;}

set{iMotor=value;}

publicintAsientos{

get{returniAsiento;}

set{iAsiento=value;}

publicstringTipo{

get{returnsTipo;}

set{sTipo=value;}

}
Compilar:
csc/t:library/out:informatique.com.mx.dlliPersona.csiVehiculo.cs
AplicacinCliente:
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

50/63

14/2/2015

Manuales.NET:ManualC#

usingSystem;

usinginformatique.com.mx;

classiAplic{

publicstaticvoidMain(){

iPersonaEmpleado=newiPersona();

Empleado.Sueldo=33;

Console.WriteLine("Edad:"+Empleado.Sueldo);

Empleado.AsignarNombre("GerardongelesNava");

Console.WriteLine("Nombre:"+Empleado.ObtenerNombre());

//Clasequeestcontenidaenotroarchivo

iVehiculoMiAvion=newiVehiculo(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.dlliAplic.cs
Recuerdequesusclasesdebentenerelmodificadordeaccesopublic,delocontrarioelcompiladornotificaraunerror
(errorCS0122:isinaccessibleduetoitsprotectionlevel),porloquetendrqueagregarelmodificadordeaccesoyvolver
acompilar.
NamespaceyEnsambles
UnobjetopuedeserutilizadodesdeunarchivofuenteC#slosieseobjetopuedeserlocalizadoporelcompiladorC#,por
defaultelcompiladorsloabreelensambleconocidocomomscorlib.dll,elcualcontienelasfuncionesprincipalespara
elCLR.
Parareferenciarobjetoslocalizadosenotrosensambles,elnombredelarchivodeensambledebeserpasadoalcompilador,
estoesposibleutilizandounswitchalcompilar:
/r:nombreEnsamble
Es as como se crea un correlacin entre elnamespacede un objeto y el nombre del ensamble en el cual reside, por
ejemplolostiposdenamespaceenelSystem.NetresidenenelensambleSystem.Net.dll
CompilacinCondicional
LaCompilacinCondicionalpermiteexcluiroincluircdigo,enC#existendosformasdehaceresto:
UsodelPreprocesador
Atributoconditional
UsodelPreprocesador
C#elcompiladoremulaelpreprocesador,yaquenohayunpreprocesadorporseparado.
ElcompiladordeC#nosoportamacros,encambiosoportalassiguientesdirectivas:
Definicindesmbolos
Exclusindecdigobasadoensmbolos
Lanzamientodeerroresyadvertencias
Definicindesmbolos
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
realizarseantesdecualquierotrasentencia:

#defineDEBUG

#defineRELEASE
Enestecaso#defineDEBUG,defineunsmboloDEBUGysumbitoeselarchivodondeesdefinido,aligualqueelsmbolo
RELEASE.
Otraformautilizadaparadefinirsmbolosesusarelcompiladoryesdembitoglobalparatodoslosarchivos:
csc/define:DEBUGnombreArchivo.cs
Siserequieredefinirmltiplessmbolosutilizandoelcompilador,esnecesariosepararcadasmboloconunacoma(,)
csc/define:DEBUG,RELEASE,DEMOVERSIONnombreArchivo.cs
Sielcdigofuenteincluyedirectivasdedefinicindesmbolos,esposibledeshabilitarlasutilizandoladirectiva#undefcuyo
mbitotambincorrespondealarchivodondeesdefinida:
#undefDEBUG
Exclusindecdigobasadoensmbolos
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

51/63

14/2/2015

Manuales.NET:ManualC#

El principal propsito de los smbolos es la inclusin o exclusin condicional del cdigo, basado sobre si son o no son
definidoslossmbolos.
Elsiguientecdigonodefinesmbolosenelarchivofuente:

sentencia;

#ifNOMBRE_SIMBOLO

sentencia;

#else

sentencia;

#endif

.
Peroesposibledefinironolossmbolosalcompilarlaaplicacin:
csc/define:NOMBRE_SIMBOLONombreAplicacion.cs
Las directivas del preprocesador emulado utilizadas para evaluar el smbolo son:#if,#else y #endif las cuales actuan
comosucontraparte,lasentenciacondicionalifC#,esposibleutilizar&&,||y!:

//#defineSIMBOLO_A

#defineSIMBOLO_B

#defineSIMBOLO_C

#ifSIMBOLO_A

#undefSIMBOLO_C

#endif

usingSystem;

classNombreClase{

publicstaticvoidMain(){

#ifSIMBOLO_A

#elifSIMBOLO_B&&SIMBOLO_C

#else

#endif

}
Lanzamientodeerroresyadvertencias
Existe otro uso de las directivas del preprocesador para lanzar errores del compilador o advertencias dependiendo de
ciertossmbolos,paraelloseutilizanlasdirectivas:
#warning
#error
Porejemplo

#ifSIMBOLO_ERROR

#errorPresentarelmensajedeerrorcorrespondiente

#endif

#ifSIMBOLO_WARNING

#errorPresentarelmensajedeadvertenciacorrespondiente

#endif
Atributoconditional
Unatributoconditionalevalualainvocacindeunafuncincuandosiertosmboloesdefinidoyevaluaanadacuando
unaversinliberadaesconstruida.
Unatributoconditionaldebeteneruntipovoidderegreso,cualquierotrotipoderegresonoespermitido.

[conditional("NOMBRE_SIMBOLO")]

mtodoA

[conditional("NOMBRE_SIMBOLO")]

mtodoB

.
ComentariosdeDocumentacinenXML
EsposibleconstruirautomticamentelaDocumentacinutilizandocomentariosenelcdigo.
LasalidaqueesgeneradaporelcompiladoresXMLpuroypuedeserutilizadacomoentradaparaladocumentacindeun
componente.
La documentacin es una parte extremadamente importante del software y en especial de los componentes por ser
utilizadosporotrosdesarrolladores.
ElementosXML
Nota:todocomentariodedocumentacinsontagsXML(eXtensibleMarkupLanguage).
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

52/63

14/2/2015

Manuales.NET:ManualC#

Paradescribirunelementoseutilizaeltag<summary></summary>,elcualseescribeenelcdigofuenteanteponiendotres
diagonalesquesonindicativodeuncomentariodedocumentacin:
///<summary>Descripcin...</summary>
Encasoderequerirmsunalneaparaelcomentariodedocumentacinutiliceeltag:

///<para>

///.

///.

///</para>
Encasoderequerirunareferenciaaotroselementosutiliceeltag:
///<seecref="NombreElemento"/>
Encasoderequerirunareferenciaauntpicodeinteresutilice:
///<seealsocref="System.Net"/>
Untagcontrarioasummary,paraunvolumenmayordedocumentacines:
///<remarks>
Esposibleincluirlistasutilizandolostags:

///<listtype="bullet">
///
<item>Constructor
///

<seecref="Constructor()"/>

///

<seecref="Constructor(string)"/>

///
</item>

///</list>
Paradescribirparmetrosseutilizaeltag:
///<paramrefname="nombreParametro"/>
Esposibleencerrarenuntagunejemplocompletoeincluirladescripcinycdigo:

///<example>

///
.

///
<code>

///
.

///
</code>

///
.

///</example>
Paradescribirlosparmetrosderegresoutilice:

///<returns>

///
<para>true:valorobtenido</para>

///
<para>false:valornoobtenido</para>

///</returns>
Paradescribirpropiedadesdeclaseseutilizauntagespecial:
///<value>Propiedad...</value>
Unavezqueelprocesodedocumentacinparauncomponenteesterminado,esposiblecrearunarchivoXMLbasadoen
la documentacin descrita en el cdigo fuente y hacerla disponible a quienes utilicen el componente, para ello
simplementeseutilizaalcompilarelswitch/doc:seguidodeldocumentoXML.
csc/doc:Persona.xmlAplicPersona.cc
Ejemplo:
usingSystem;
///
/// ClasePersona
///
Autor:GerardongelesNava
///
Fecha:10/09/2005
///
Descripcin:Clasequedefineloqueesypuedehacerunapersona
///
///
classPersona{

///LapropiedadiSueldoseempleaparaobteneryasignarelvalordelsueldodeunapersona

privateintiSueldo;

publicintSueldo{

get{returniSueldo;}

set{iSueldo=value;}

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

53/63

14/2/2015

Manuales.NET:ManualC#

publicstringsNombre;
///UtilizadoparaasignarelvalordelapropiedadsNombre

publicvoidAsignarNombre(stringsValor){

sNombre=sValor;

publicstringObtenerNombre(){

returnsNombre;

}
}

classAplicPersona{

publicstaticvoidMain(){

PersonaEmpleado=newPersona();

Empleado.Sueldo=33;

Console.WriteLine("Edad:"+Empleado.Sueldo);

Empleado.AsignarNombre("GerardongelesNava");

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
archivofuente,encasodeexistirerroreselcompiladorlonotificaryanaseldocumentoXMLesgeneradoperotendr
unmensajedeerror.
El documento XML tendr algunos identificadores seguidos de dos puntos (:) y la ruta del namespace, los cuales por
ejemplotienenlossiguientesignificados.
N,denotaunnamespace
T,identificauntipo,elcualpuedeserunaclase,interface,estructura,enumeracinodelegado
F,describeuncampooclase
P,serefiereaunapropiedadlacualtambinpuedeserunindceopropiedadndice.
M,identificaunmtodo,incluyendoconstructoresyoperadores.
E,denotaeventos
!,denotaunerrorelcualproveeinformacinacercadeunaligaqueelcompiladorC#nopudoresolver.
Siunelementotieneperodosensunombre,estossonreemplazadosporelsmbolo#.Losparmetrosparamtodosson
encerradosentreparntesisyseparadosporcomas(,).
Componentes.NET
ElcompiladordeC#pordefaultsiemprecreacomponentes.NETparalosejecutables.
UnComponente .NET es la unidad fundamental reusable y compartida en el CLR, un componente .NET tambin es
limitanteparaasegurarlaseguridad,permiteladistribucindeclasesyresolucindetipos.Unaaplicacinpuedecontener
mltiplescomponentes.NET
Uncomponente.NETcontienecuatropartesreferentesalnmerodeversinllamadoversincompatible:
majorversion.minorversion.buildnumber.revision
Laversincompatibleesutilizadaporelclassloaderparadecidircualeslaversindelcomponente.NETquecargar,en
casodeexistirdiferentesversiones.
Seconsideraunaversinincompatiblecuandomajorversion.minorversionesdiferentedelaversinsolicitada.
Sepodraconsiderarunaversincompatiblecuandoelbuildnumberesdiferentealaversinsolicitada.
SeconsideraunaQFE(QuickFixEngineering)compatiblecuandorevisionesdiferente.
Ademsdelnmerodeversin(versincompatible)sealmacenaotronmeroenelcomponentellamado informational
version,elcualesconsideradosloparapropsitosdedocumentacinysucontenidopodraserSuperControlBuild1880,
elcontenidorepresentaalgohumanoynoparalamquina.
Paraindicaralcompiladorqueagregueunversioninformationalcomponenteseutilizaelswitch:
csc/a.version:1.0.1.0/t:library/out:nombreArchivoFuente.dllnombreArchivoFuente.cs
Elswitch/a.versioncreaunabibliotecaconelversioninformation1.0.1.0,estopuedecomprobarseenlaspropiedades
delarchivo.dll.
Componentes.NETPrivados
Al ligar una aplicacin a un componente .NET utilizando el switch /reference:nombreBiblioteca la informacin de
dependenciaregistralasherramientasdedesarrollo,incluyendolaversindelasbibliotecasligadas,esteregistrosehace
enunmanifiestoyelCLRlosnmerosdeversincontenidosparacargarlaversinapropiadadeuncomponente.NET
dependienteentiempodeejecucin.
Cualquiercomponente.NETqueresideeneldirectoriodelaaplicacinesconsideradoprivadoynoesversionchecked
Componentes.NETCompartidos
Si se requiere construir software que se comparta con otras aplicaciones, el componente .NET deber ser instalado
comocompartido.
InteroperabilidadCOM
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

54/63

14/2/2015

Manuales.NET:ManualC#

COMesunatcnicadeinteroperabilidad,porloquelosclientes.NETdebernsercapacesdeinvocarcomponentesCOMy
componentes COM debern hacer uso de los nuevos componentes .NET, esta es una caracterstica de iteroperabilidad
proporcionadaporlaplataforma.NETparatodosloslenguajesdeprogramacinqueemitencdigoadministrado.
UsodeComponentes.NETenComponentesCOM
La interoperabilidad permite a clientes COM utilizar componentes .NET, para hacer esto posible en COM primero es
necesarioregistrarunobjetoantesdepoderserutilizado,pararegistrarunobjetoCOMseutilizalaaplicacinregsvr32y
para registrar un componente .NET se utilizaregasm.exe, esta herramienta permite registrar un componente .NET en
elRegistryytambincrearunarchivoRegistry.
SirequiereexaminarlasentradasagregadasalRegistryescribaenlalneadecomandos:
regasmnombreComponente.dll/regfile:nombreArchivoComponente.reg
AhorapuedeexaminarelarchivogeneradonombreArchivoComponente.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]

@="{37504224213A3943845AE572758E4174}"

[HKEY_CLASSES_ROOTCLSID{37504224213A3943845AE572758E4174}]

@="informatique.com.mx.iPersona"

[HKEY_CLASSES_ROOTCLSID{37504224213A3943845AE572758E4174}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{37504224213A3943845AE572758E4174}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{37504224213A3943845AE572758E4174}ProgId]

@="informatique.com.mx.iPersona"

[HKEY_CLASSES_ROOTCLSID{37504224213A3943845AE572758E4174}ImplementedCategories_

{62C8FE654EBB45E7B4406E39B2CDBF29}]
Elmotordeejecucinmscoree.dlles invocado cuando una instancia del objeto (componente registrado) es requerida,
msnolabibliotecaporsisla.
ElmotordeejecucinesresponsabledeproveerlaCCW(COMCallableWrapper)alobjeto.
Una vez registrado el componente puede ser utilizado por lenguajes de programacin que soporten esta vinculacin,
tambinesposibleemplearlautileriatlbexplacualpermitegenerarunabibliotecatipoparaelcomponente.NET
tlbexpnombreComponente.dll/out:nombreBiblioteca.tlb
Estabibliotecatipopuedeserutilizadaenlenguajesdeprogramacinquesoportenestavinculacin.
ElComponente.NETytodaslasclasesyaestnregistradasysetieneunabibliotecatipoparaambientes
UsodeComponentesCOMenComponentes.NET
Los Clientes .NET pueden interoperar con objetos clsicos COM, para que un componente utilise COM debe tener una
bibliotecatipoparaelCLRestosetraducealosmetadatosquesonalmacenadosconlostipos.
ParaqueseaposibleinvocaruncomponenteCOMdesdeunobjeto.NET,esnecesarioenvolverelcdigounsafe,cuandola
envolturaowrapperesinvocada,unRCW(RuntimeCallableWrapper)esconstruidodesdelainformacindelabiblioteca
tipo.Unaherramientageneraelcdigowrapperbasadoenlainformacinobtenidadelabibliotecatipo.
Laherramientaautilizarestlimp(typelibraryimport):
tlbimpnombreComponente.dll/out:nombreBiblioteca.dll
Esta herramienta importa el tipo de biblioteca COM, crea y almacena un RCW que puede ser utilizado en elCLR en el
archivonombreBiblioteca.dll.
ParaverlosmetadatosparaelRCWutiliceildasm.exe,aspodrdistinguirelnombredelaclasequefugeneradaparael
objetoCOMoriginal,estainformacinesunaayudaparapoderescribirelobjeto.NETqueutilizaelcomponenteCOM.
InvocacindeServicios
Se se requiere invocar una funcin provista por el WIN32 o alguna DLL unmanaged, se utilizan los Servicios de
invocacindeplataforma(PInvoke).
PInvoke se encarga de ejecutar la funcin correcta y tambin de la colocacin de los argumentos para y desde sus
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

55/63

14/2/2015

Manuales.NET:ManualC#

contrapartesunmanaged.
Simplementeutiliceelatributosysimportaldefinirunmtodoexterno:

[sysimport(

dll=nombreDLL,

name=puntoEntrada,

cgarset=conjuntoCaracteres

]
Unicamenteelargumentodllesobligatorioylosdemsopcionales,aunquesiseomiteelatributoname,elnombredela
funcindeimplementacinexternadebecoincidirconelnombredelmtodoestticointerno.
CdigoNoSeguro
Sirequieredeescribircdigonoseguro,deberutilizardospalabrasreservadas:
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,aldeclararunavariableconestemodificadorprevienealrecolectordebasuradereacomodarlo.
Debugging
ElSDK.NETincorporadosherramientasdedepuracindeerrores:
CORDBG,depuradordelneadecomando
SDK,depuradorUI
EldepuradorSDKnosoportaladepuracindecdigonativo,sloesposibledepurarcdigoadministrado.
Noesposibleladepuracindeunamquinaremota
Windowregisterydisassemblyaunqueseimplementannosonfuncionales
Antes de depurar el cdigo de una aplicacin es necesario crear una versin depurada, la cual contiene informacin de
depuracinnooptimizadayunarchivoadicionalPDB(programdatabase)paradepuracinyunestadodeinformacindel
proyectoescreado.
Paracrearunaversindepuradasonnecesariosdosswitchesalcompilar:
csc/optimize/debug+nombreArchivoFuente.cs
Estoscomandosutilizadosalcompilarcreadosarchivos:
nombreArchivoFuente.exey
nombreArchivoFuente.pdb
Para configurar la sesin de depuracin es necesario seleccionar la aplicacin que se desea depurar y comenzar el
depuradorSDKejecutandodbgurt.exe,elcualestaalmacenadoeneldirectorioProgramFilesNGWSSDKGuiDebug
Unavezquelaaplicacindepuradoracomienzaseseleccionaelprogramaquesedeseadepurarendondesertambin
posible especificar argumentos en la lnea de comandos, mismos que son pasados a la aplicacin cuando la sesin de
depuracininicia.
Esposibleestablecerdiferentestiposdebreakpoint:
File,interrumpelaejecucincuandounaubicacinespecficaenelarchivofuentesealcanza
Data,interrumpelaejecucincuandounavariablecambiaaunvalorespecifico
Function,interrumpelaejecucinenunaubicacinespecficadentrodeunafuncinespecfica
Address,interrumpelaejecucincuandounadireccindememoriaespecficasealcanza
Unavezqueseinterrumpelaejecucin,esposiblecontinuarlautilizandoloscomandos:
StepOver
StepInto
StepOut
RuntoCursor
Es posible modificar valores de variables simplemente dando doble clic en la columna valor de aquella variable que se
deseamodificar,ascomotambinesposibleobservarlasvariables,paraelloesnecesariodarclicenlacolumnanombrey
escribirelnombredelasvariablesquesedeseanobservar.
Las excepciones son un punto excelente de comienzo para una sesin de depuracin, cuando una excepcin no es
controladaapropiadamenteporelcdigosemuestralaventanadedepuracinllamadaJITjustintime.
Seguridad
Hoyendaelcdigovienededistintasfuentes,nosoloelqueesinstaladoviaunsetupporelservidor,tambinpuedeser
instaladoviaunapginawebocorreoelectrnico.
.NETplanteadosposiblessolucionesparalaseguridad:
Seguridaddeaccesoalcdigo
Seguridadbasadaenroles
Seguridaddeaccesoalcdigo
LaSeguridaddeaccesoalcdigocontrolaelaccesoprotegiendolosrecursosyoperaciones.Elcdigoesconfiableen
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

56/63

14/2/2015

Manuales.NET:ManualC#

distintosgrados,dependiendosuidentidadydedondeviene.
Funcionesdelaseguridaddeaccesoalcdigo:
Eladministradorpuededefinirlaspolticasdeseguridadasignandociertospermisosparadefinirgruposde
cdigo.
Elcdigopuederequerirquequieninvoca(caller)debetenerpermisosespecificos
Laejecucindecdigoestrestringidoentiempodeejecucin,realizandochequeosparaverificarquelos
permisosotorgadosaquieninvoca(caller)coincidanconelpermisorequeridoparalaoperacin.
Elcdigopuederequerirlospermisosnecesariosdeejecucinylospermisosquepodranserutilizados,es
decir,verificarlospermisosindispensables.
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
estabasadoenelrequerimientodelcdigo,definiendooperacionespermitidasporlaspolticasdeseguridad.
Existendospuntosimportantesdelaseguridaddeaccesoalcdigo,dondeelrequerimientomnimoparabeneficiarsede
laseguridaddeaccesoalcdigoesparageneraruncdigodetiposeguro.
Verificar el tipo de seguridad del cdigo administrado, el runtime forza la restriccin de seguridad del
cdigoadministrado,paradeterminarcuandoelcdigoesseguro.Esimportantequeelruntimeseacapazde
checar los permisos de quien invoca de manera confiable, evadiendo hoyos de seguridad que son creados
cuandocdigomenosconfiableinvocacdigoaltamenteconfiable,paraelloelcdigoadministradodebeser
verificadocomotiposeguro.Cadaaccesoatiposserealizasloenunsentidopermitido.
ElcdigoC#esdetiponoseguro,peroelILylosmetadatossoninspeccionadosantesdedarelvistobueno
deltipodeseguridaddelcdigo.
Permisosquesonrequeridosporelcdigo,elbeneficiodeactivarelrequerimientodepermisosesconocer
cuandosetieneelpermisoapropiadopararealizaraccionesycuandono.Esposiblepreveniralcdigodeel
otorgamiento de permisos adicionales que no son necesarios. Los permisos mnimos garantizan que el
cdigoseejecuteconlosrecursosjustoscuandoelcdigorequieredemuchospermisossinquefalle.
Lacategoriadelospermisoses:
Required,permisoqueelcdigonecesitaparaejecutarsecorrectamente.
Optional,permisosquenosonobligatoriosparalaejecucincorrectadelcdigo,peroquepodraserbueno
tenerlos.
Refused,permisoquesenecesitaparaqueelcdigonuncaseotorgue,aunquelapolticadeseguridadlo
permita,seutilizapararestringirvulnerabilidadespotenciales.
PermisosEstndar
LosPermisosEstndarson:
EnvironmentPermission,clasequedefinepermisosdeaccesoavariablesdeambiente,dondesonposiblesdos
tiposdeacceso,deslolecturayescrituraalvalordeunavariabledeambiente.Eltipodeaccesoescritura
incluyepermisosparacrearyeliminarvariablesdeambiente.
FileDialogPermission,controlaelaccesoaarchivosbasadoenelsistemadearchivosdedilogo.Elusuario
debeautorizarelaccesoalarchivoviaelcuadrodedilogo.
FileIOPermission, es posible especificar tres tipos de acceso a archivos de entrada y
salida: lectura, escritura yadicin, el acceso lectura incluye acceder a la informacin del archivo, el tipo
escrituraincluyeeliminarysobreescribir,elaccesoadicinnopermiteleerotrosbits.
IsolatedStoragePermission, controla el acceso a almacenamientos aislados, este acceso permite utilizacin,
tamaodealmacenamiento,tiempodeexpiracinyalmacenamientodedatos.
ReflectionPermission, controla la capacidad de leer el tipo de informacin de tipos miembro no pblicos y
controlaelusodeReflection.Emit
RegistryPermission,Controldelectura,creacinyescrituraenelregistry
SecurityPermission,coleccindepermisossimplesquesonutilizadosporelsistemadeseguridad,esposible
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,
accesoaeventosyusodelportapapeles.
PermisosIdentidad
LosPermisosIdentidadson:
PubilsherIdentityPermission,lafirmadecomponentes.NETproveeresistenciadesoftwarepublisher
StrongNameIdentityPermission, define el nombre del componente criptograficamente, ya que el nombre
comprometelaidentidad.
ZoneIdentityPermission,definelazonadedondeelcdigotieneorigen,unURLpuedeperteneceraslouna
zona
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

57/63

14/2/2015

Manuales.NET:ManualC#

SiteIdentityPermission,permisosderivadosbasadosenelsitiowebdedondeelcdigotieneorigen
URLIdentityPermission,permisosderivadosbasadosenURLdedondeelcdigotieneorigen
Seguridadbasadaenroles
LaSeguridadbasadaenrolesrepresentaaunusuariooagentequeactuaenrepresentacindeunusuariodado.Las
aplicaciones.NEThacendecisionesbasadasenlaidentidadprincipalosurolecomomiembro.
Unroleesunnombreparaunconjuntodeusuariosquienescompartenlosmismosprivilegios.
Un principal puede ser un miembro de mltiples roles y de esta manera se puede utilizar un role para determinar si
ciertasaccionesrequeridasquizseanrealizadasporunprincipal.
Unprincipalnonecesariamenteesunusuario,tambinpuedeserunagente.
Existentrestiposdeprincipal:
Genericprincipals,representausuariosnoautentificados.
Windows principals, relacin de usuarios windows y sus roles, el acceso a recursos de otro usuario es
permitido.
Customprincipals,definidoporunaaplicacin.Puedenextenderlanocinbsicadelaidentidadylosroles
delprincipal.Larestriccinesquelaaplicacindebeproveerunmdulodeautentificacindelostiposque
elprincipalpuedeimplementar.
La clase Principalpermission provee consistencia con la seguridad de acceso, permitiendo al runtime realizar la
autorizacinenunsentidosimilaralchequeodelaseguridaddeaccesoalcdigo,peroesposibleaccederdirectamentea
lainformacindeidentidadprincipalyrealizarchequeosderoleeidentidadenelcdigocuandoseanecesario.
FuncinToString()
Analiceelsiguienteejemplo:

usingSystem;

classEmpleado{

stringusr;

stringpwd;

publicEmpleado(stringlogin,stringpwd){

this.usr=login;

this.pwd=pwd;

classApp{

publicstaticvoidMain(){

Empleadoempleado=newEmpleado("gangeles","123");

Console.WriteLine("Empleado:"+empleado);

}
Salida:Empleado:Empleado
LasalidafueelnombredelaclaseEmpleadoyaqueeslarepresentacinmscercanaqueencontro.
EsposibleespecificaralgoconmayorsentidoparaellosenecesitaredefinirlafuncinToString():

usingSystem;

classEmpleado{

stringusr;

stringpwd;

publicEmpleado(stringlogin,stringpwd){

this.usr=login;

this.pwd=pwd;

publicoverridestringToString(){

return("Usuario:"+usr+",Password:"+pwd);

classApp{

publicstaticvoidMain(){

Empleadoempleado=newEmpleado("gangeles","123");

Console.WriteLine(empleado);

}
Salida:Usuario:gangeles,Password:123
FuncinEquals()
LafuncinEquals()esutilizadaparadeterminarcuandodosobjetostienenelmismocontenido.
En el siguiente ejemplo se redefinen las funcionesoperator==()yoperator!=(), para permitir la sintaxis del operador,
estosoperadoresdebenserredefinidosenpares,nopuedenserredefinidosseparadamente.
Ejemplo:

usingSystem;
classEmpleado{

stringusr;

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

58/63

14/2/2015

Salida:

Manuales.NET:ManualC#

stringpwd;

publicEmpleado(stringlogin,stringpwd){

this.usr=login;

this.pwd=pwd;

publicoverridestringToString(){

return("Usuario:"+usr+",Password:"+pwd);

publicoverrideboolEquals(objecto){

EmpleadoempB=(Empleado)o;

if(usr!=empB.usr){returnfalse;}

if(pwd!=empB.pwd){returnfalse;}

returntrue;

publicstaticbooloperator==(EmpleadoempA,EmpleadoempB){

returnempA.Equals(empB);

publicstaticbooloperator!=(EmpleadoempA,EmpleadoempB){

return!empA.Equals(empB);

}
}
classApp{
publicstaticvoidMain(){

Empleadoempleado1=newEmpleado("gangeles","123");

Empleadoempleado2=newEmpleado("gangeles","123");

Console.WriteLine("Elempleado1esigualalempleado2:"+empleado1.Equals(empleado2));

Console.Write("empleado1==empleado2:");

Console.Write(empleado1==empleado2);
}
}

Elempleado1esigualalempleado2:True

empleado1==empleado2:True
Al compilar el ejemplo anterior se presentara unwarningindicando que no fue redefinada la funcin GetHashCode() ya
que los valores que regresa son requeridos para ser relacionados al valor de regreso deEquals(). Cuando se invoca la
funcinEquals()ydosobjetossonigualessiempresedeberegresarelmismocdigohash.
Sinoesredefinidoelcdigohashpodrasersloidenticoparalamismainstanciadeunobjetoyunabsquedaparaun
objetoqueesigualperonolamismainstanciapodrafallar.
Esposibleutilizarunmiembroqueesnicoparaelcdigohash,perosinoexisteunvalornicoelcdigohashdeberaser
creadofueradelosvalorescontenidosenlafuncin.
Silaclasenotieneunidentificadornicoperotienetieneotroscampos,podrasserutilizadosporlafuncinhash:

usingSystem;
classEmpleado{

stringusr;

stringpwd;

publicEmpleado(stringlogin,stringpwd){

this.usr=login;

this.pwd=pwd;

publicoverridestringToString(){

return("Usuario:"+usr+",Password:"+pwd);

publicoverrideboolEquals(objecto){

EmpleadoempB=(Empleado)o;

if(usr!=empB.usr){returnfalse;}

if(pwd!=empB.pwd){returnfalse;}

returntrue;

publicstaticbooloperator==(EmpleadoempA,EmpleadoempB){

returnempA.Equals(empB);

publicstaticbooloperator!=(EmpleadoempA,EmpleadoempB){

return!empA.Equals(empB);

publicoverrideintGetHashCode(){

returnusr.GetHashCode()+pwd.GetHashCode();

}
}
classApp{
publicstaticvoidMain(){

Empleadoempleado1=newEmpleado("gangeles","123");

Empleadoempleado2=newEmpleado("gangeles","123");

Console.WriteLine("Elempleado1esigualalempleado2:"+empleado1.Equals(empleado2));

Console.Write("empleado1==empleado2:");

Console.Write(empleado1==empleado2);

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

59/63

14/2/2015

Manuales.NET:ManualC#

}
LaimplementacindelcdigoGetHashCodeanterioragregaloselementosylosregresa.
ClaseHashtable
La clase Hashtable es muy utilizada para realizar una bsqueda de objetos por una llave. Una tabla hash trabaja
utilizandounafuncinhash,lacualproduceunenterollaveparaunainstanciaespecficadeunaclase,dondeestallavees
unaversincondensadadelainstancia.
Unatablahashutilizaestallaveparalimitardrasticamenteelnmerodeobjetosquedebenserbuscadosparaencontrar
unobjetoespecficoenunacoleccindeobjetos.
InterfaceIHashCodeProvider
Si requiere definir diferentes cdigos hash para un objeto especfico, podra hacer esto implementado la
InterfaceIHashCodeProviderparaproveerunafuncinalternahashyademsdequeserequiereunacoincidenciadela
implementacindeIComparer,estasnuevasimplementacionessonpasadasalcontructordelaHashtable:

usingSystem;
usingSystem.Collections;
publicclassLenguaje:IComparable{

publicstringnombre;

intid;

publicLenguaje(stringnombre,intid){

this.nombre=nombre;

this.id=id;

intIComparable.CompareTo(objecto){

LenguajelenguajeB=(Lenguaje)o;

if(this.id>lenguajeB.id){return1;}

if(this.id<lenguajeB.id){

return1;

}else{

return0;

publicoverridestringToString(){

returnnombre+""+id;

publicoverrideintGetHashCode(){

returnid;

publicstaticIComparerOrdenaPorNombre{

get{

return(IComparer)newOrdenaNombres();

publicstaticIHashCodeProviderHashNombre{

get{

return(IHashCodeProvider)newHashNombreCls();

publicclassOrdenaNombres:IComparer{

publicintCompare(objectoA,objectoB){

LenguajelenA=(Lenguaje)oA;

LenguajelenB=(Lenguaje)oB;

returnString.Compare(lenA.nombre,lenB.nombre);

}
}
classHashNombreCls:IHashCodeProvider{

publicintGetHashCode(objecto){

Lenguajelen=(Lenguaje)o;

returnlen.nombre.GetHashCode();

}
}
classApp{
publicstaticvoidMain(){

Lenguaje[]aLenguaje=newLenguaje[5];

aLenguaje[0]=newLenguaje("C",3);

aLenguaje[1]=newLenguaje("ActionScript",5);

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

60/63

14/2/2015

Manuales.NET:ManualC#

aLenguaje[2]=newLenguaje("JavaScript",2);

aLenguaje[3]=newLenguaje("Java",8);

aLenguaje[4]=newLenguaje("PHP",1);

Hashtablelenguajes=newHashtable(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");

Lenguajeclone=newLenguaje("MiLenguaje",12345);

strings=(string)lenguajes[clone];

Console.WriteLine(clone.ToString(),s);

}
FuncinIClonable
Lafuncinobject.MemberWiseClone()puedeserutilizadaparacrearunclondeunobjeto.Laimplementacinpordefault
de esta funcin produce una copia de un objeto, los campos de un objeto son copiados exactamente en lugar de ser
duplicados:

Salida:

usingSystem;
classSaludo{

publicstrings;

publicSaludo(strings){

this.s=s;

}
}
classMiClase{

publicSaludosaludo;

publicMiClase(strings){this.saludo=newSaludo(s);}

publicMiClaseClon(){return(MiClase)MemberwiseClone();}
}
classApp{
publicstaticvoidMain(){

MiClasemiClase=newMiClase("HelloWorld!");

MiClasemiClon=miClase.Clon();

Console.WriteLine("miClase:"+miClase.saludo.s);

Console.WriteLine("miClon:"+miClon.saludo.s);

miClon.saludo.s="HolaMundo";

Console.WriteLine("miClase:"+miClase.saludo.s);

Console.WriteLine("miClon:"+miClon.saludo.s);
}
}

miClase:HelloWorld!

miClon:HelloWorld!

miClase:HolaMundo

miClon:HolaMundo
ElresultadoanterioresporquelacopiahechaporlafuncinMemberWiseClonre()esunacopia,elvalordesaludoes el
mismoenambosobjetosporloquesesecambiaunvalordentrodelobjetoSaludoafectaambasinstanciasdeMiClase.
InterfaceICloneable
Paracrearunacopiadeep,dondeunanuevainstanciadeSaludoescreadaparaparalanuevainstanciadeMiClase,para
ellosehaceunaimplementacindelainterfaceICloneable:

usingSystem;
classSaludo{

publicstrings;

publicSaludo(strings){

this.s=s;

}
}
classMiClase:ICloneable{

publicSaludosaludo;

publicMiClase(strings){this.saludo=newSaludo(s);}

publicobjectClone(){return(newMiClase(this.saludo.s));}
}
classApp{

publicstaticvoidMain(){

MiClasemiClase=newMiClase("HelloWorld!");

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

61/63

14/2/2015

Manuales.NET:ManualC#

MiClasemiClon=(MiClase)miClase.Clone();
Console.WriteLine("miClase:"+miClase.saludo.s);
Console.WriteLine("miClon:"+miClon.saludo.s);
miClon.saludo.s="HolaMundo!";
Console.WriteLine("miClase:"+miClase.saludo.s);
Console.WriteLine("miClon:"+miClon.saludo.s);

Salida:

miClase:HelloWorld!

miClon:HelloWorld!

miClase:HelloWorld!

miClon:HolaMundo
La invocacin a Memberwiseclone() regresa una nueva instancia de Saludo y su contenido puede ser modificado sin
afectarelcontenidodemiClase.
NotequeenestecasoICloneablerequiereimplementarlafuncinClone().
FormatoNumrico
LostiposnumricossonformateadosatravsdelafuncinmiembroFormat()deltipodedato,lacualpuedeserinvocada
directamente a travs de String.Format() la cual invoca a la funcin Format() de cada tipo de dato
oConsole.WriteLine()lacualinvocaaString.Format().
Existendostiposdemtodosparaelformateoespecficonumrico:
FormatoEstndarString
FormatoEstndarString,elcualpuedeserutilizadoparaconvertiruntiponumricoaunarepresentacinespecfica
string.
Este formato consiste del formato especfico del caracter seguido de la secuencia de precisin especfica de digitos, los
formatossoportadosson:
Formato Descripcin

Ejemplo

Salida

C,c

Currency

Console.WriteLine("0:C",
123.8977);

D,d

Decimal

Console.WriteLine("0:D7",
0012345
12345);

E,e

Console.WriteLine("0:E",
Scientific
(exponential) 33345.8977);

3.334590E+004

E,f

Fixedpoint

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

$123,345.90

FormatoPersonalizadoString
ElFormatoPersonalizadoString,sonutilizadosparaobtenermscontrol,sobrelaconversacinqueestdisponiblea
travsdelformatoestndardestrings.
ReemplazodeCerooDigito
Console.WriteLine("{0:000}",12);Salida:012
ReemplazodeEspaciooDigito
Console.WriteLine("{0:#####}",123);Salida:123
PuntoDecimal
Console.WriteLine("{0:#####.000}",12345.2);Salida:12345.200
SeparadordeGrupo
Console.WriteLine("{0:##,###}",1123456789);Salida:1,123,456,789
SeparadordeGrupo
Console.WriteLine("{0:000,.##}",12394);Salida:123.95
Porcentaje
Console.WriteLine("{0:##.000%}",98144);Salida:98.144%
NotacinExponencial
Console.WriteLine("{0:###.000E00}",3.1415533E+04);Salida:314.155E02
SeparadordeSeccin
Console.WriteLine("{0:###.00;0;(###.00)}",456.55);Salida:457
EscapeyLiterales
data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

62/63

14/2/2015

Manuales.NET:ManualC#

Console.WriteLine("{0:###\#}",255);Salida:255#
ParseoNumrico
LosnmerospuedenserparseadosutilizandoelmtodoParse(),estoesposibleyaqueloproveeeltipodedato.

Input/Output

intiValue=Int32.Parse("123");
doubledValue=Double.Parse("1.23");

EllenguajeComnenTiempodeEjecucin.NETproveefuncionesdeentrada/salidaenelnamespaceSystem.IO.
LalecturayescrituralarealizalaclaseStream,lacualdescribecomolosbytespuedenserescritosoleidos.Streamesuna
claseabstractaqueenlaprcticalasclasesderivandeStreamparaserutilizadas.
Clasesdisponibles:
FileStream,flujoenunarchivodedisco
MemoryStream,flujoqueesalmacenadoenmemoria
NetworkStream,flujoenunaconexindered
BufferedStream,implementaunbufferenlacimadeotrostream.
LecturayEscrituradeArchivos
Existen dos formas de obtener flujos (streams) que conectan a un archivo, uno utilizando la clase FileStream, la cual
proveeuncontroltotalsobreelaccesodearchivos,incluyendomododeacceso,compartidoybuffering.
A continuacin se muestra un ejemplo donde, cada vez que el programa es ejecutado se sobreescribe el contenido del
archivoencasodequeesteexista,sinoexistesecrea:

usingSystem;

usingSystem.IO;

classApp{

publicstaticvoidMain(){

FileStreamf=newFileStream("nuevo.txt",FileMode.Create);

StreamWriters=newStreamWriter(f);

for(intiNumberLine=1;iNumberLine<=10;iNumberLine++){

s.WriteLine("Linea"+iNumberLine);

s.Close();

f.Close();

}
Salida,ArchivoNuevo.txtcuyocontenidoes:

Linea1

Linea2

Linea3

Linea4

Linea5

Linea6

Linea7

Linea8

Linea9

Linea10
Serializacin
LaSerializacineselprocesoutilizadoporelruntimepara objetos persistentes en algn orden de almacenamiento o
paratransferirlosdeunlugaraotro.
Lainformacindelosmetadatosenunobjetocontieneinformacinsuficienteparaqueelruntimeserialice los campos,
peroesnecesarioindicaralruntimehacerlocorrectamenteatravsdedosatributos[Serializable]elcualesutilizado
paramarcarunobjetoqueesposibleserializary[NonSerialized]queesaplicadoparauncampoopropiedadparaindicar
quenodeberaserserializado.
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
sentencialock.
lock utiliza la clase System.Threading.Monitor y provee funcionalidad similar a la invocacin de CriticalSection en
Win32.
AgradecimientosaJuanGarciaporenviareltutorialoriginaldeinformatique.com.mx

data:text/htmlcharset=utf8,%3Cp%20class%3D%22vbTitle%22%20style%3D%22margin%3A%201px%201px%203px%3B%20padding%3A%201px%

63/63

También podría gustarte