Sei sulla pagina 1di 261

El lenguaje de programacin C# ndice

INTRODUCCIN A LA OBRA ............................................................................................... 5


REQUISITOS PREVIOS RECOMENDADOS.......................................................................................5
ESTRUCTURA DE LA OBRA............................................................................................................5
CONVENCIONES DE NOTACIN UTILIZADAS...............................................................................5
TEMA 1: INTRODUCCIN A MICROSOFT.NET ............................................................... 8
MICROSOFT.NET.......................................................................................................................... 8
COMMON LANGUAGE RUNTIME (CLR)......................................................................................8
MICROSOFT INTERMEDIATE LANGUAGE (MSIL).....................................................................11
METADATOS................................................................................................................................. 13
ENSAMBLADOS............................................................................................................................. 14
LIBRERA DE CLASE BASE (BCL)...............................................................................................1!
COMMON T"PE S"STEM (CTS)..................................................................................................18
COMMON LANGUAGE SPECIFICATION (CLS)............................................................................18
TEMA #: INTRODUCCIN A C$ ......................................................................................... #%
ORIGEN " NECESIDAD DE UN NUEVO LENGUA&E.......................................................................#%
CARACTERSTICAS DE C$...........................................................................................................#%
ESCRITURA DE APLICACIONES....................................................................................................#5
TEMA 3: EL PREPROCESADOR ......................................................................................... 34
CONCEPTO DE PREPROCESADOR................................................................................................34
DIRECTIVAS DE PREPROCESADO.................................................................................................34
TEMA 4: ASPECTOS L'(ICOS ........................................................................................... 4#
COMENTARIOS............................................................................................................................. 4#
IDENTIFICADORES........................................................................................................................43
PALABRAS RESERVADAS..............................................................................................................43
LITERALES................................................................................................................................... 45
OPERADORES............................................................................................................................... 4!
TEMA 5: CLASES ................................................................................................................... 54
DEFINICIN DE CLASES...............................................................................................................54
CREACIN DE OB&ETOS...............................................................................................................5!
)ERENCIA " M'TODOS VIRTUALES............................................................................................*%
LA CLASE PRIMEGENIA: S"STEM.OB&ECT.................................................................................**
POLIMORFISMO............................................................................................................................ *+
OCULTACIN DE MIEMBROS.......................................................................................................!4
MIEMBROS DE TIPO.....................................................................................................................8%
ENCAPSULACIN..........................................................................................................................8%
TEMA *: ESPACIOS DE NOMBRES ................................................................................... 84
Jos Antonio Gonzlez Seco Pgina 1
El lenguaje de programacin C# ndice
CONCEPTO DE ESPACIO DE NOMBRES........................................................................................84
DEFINICIN DE ESPACIOS DE NOMBRES.....................................................................................84
IMPORTACIN DE ESPACIOS DE NOMBRES.................................................................................85
ESPACIO DE NOMBRES DISTRIBUIDOS........................................................................................8+
TEMA !: VARIABLES " TIPOS DE DATOS ...................................................................... +1
DEFINICIN DE VARIABLES.........................................................................................................+1
TIPOS DE DATOS B,SICOS...........................................................................................................+#
TABLAS......................................................................................................................................... +4
CADENAS DE TE(TO..................................................................................................................1%%
CONSTANTES.............................................................................................................................. 1%5
VARIABLES DE SLO LECTURA.................................................................................................1%*
ORDEN DE INICIALIZACIN DE VARIABLES..............................................................................1%!
TEMA 8: M'TODOS ............................................................................................................ 1%+
CONCEPTO DE M'TODO............................................................................................................1%+
DEFINICIN DE M'TODOS.........................................................................................................1%+
LLAMADA A M'TODOS..............................................................................................................11%
TIPOS DE PAR,METROS. SINTA(IS DE DEFINICIN.................................................................111
M'TODOS E(TERNOS................................................................................................................114
CONSTRUCTORES.......................................................................................................................115
DESTRUCTORES......................................................................................................................... 1#1
TEMA +: PROPIEDADES .................................................................................................... 1#5
CONCEPTO DE PROPIEDAD........................................................................................................1#5
DEFINICIN DE PROPIEDADES...................................................................................................1#5
ACCESO A PROPIEDADES...........................................................................................................1#*
IMPLEMENTACIN INTERNA DE PROPIEDADES........................................................................1#!
TEMA 1%: INDIZADORES ................................................................................................... 1#+
CONCEPTO DE INDIZADOR........................................................................................................1#+
DEFINICIN DE INDIZADOR.......................................................................................................1#+
ACCESO A INDIZADORES...........................................................................................................13%
IMPLEMENTACIN INTERNA DE INDIZADORES........................................................................131
TEMA 11: REDEFINICIN DE OPERADORES .............................................................. 133
CONCEPTO DE REDEFINICIN DE OPERADOR..........................................................................133
DEFINICIN DE REDEFINICIONES DE OPERADORES.................................................................134
REDEFINICIONES DE OPERADORES DE CONVERSIN...............................................................138
TEMA 1#: DELEGADOS " EVENTOS .............................................................................. 143
CONCEPTO DE DELEGADO.........................................................................................................143
DEFINICIN DE DELEGADOS.....................................................................................................143
MANIPULACIN DE OB&ETOS DELEGADOS...............................................................................145
Jos Antonio Gonzlez Seco Pgina
El lenguaje de programacin C# ndice
LA CLASE S"STEM.MULTICASTDELEGATE.............................................................................148
LLAMADAS ASNCRONAS...........................................................................................................14+
IMPLEMENTACIN INTERNA DE LOS DELEGADOS...................................................................15#
EVENTOS.................................................................................................................................... 154
TEMA 13: ESTRUCTURAS ................................................................................................. 15!
CONCEPTO DE ESTRUCTURA.....................................................................................................15!
DIFERENCIAS ENTRE CLASES " ESTRUCTURAS........................................................................15!
BO(ING " UNBO(ING.................................................................................................................158
CONSTRUCTORES.......................................................................................................................1*%
TEMA 14: ENUMERACIONES ........................................................................................... 1*3
CONCEPTO DE ENUMERACIN..................................................................................................1*3
DEFINICIN DE ENUMERACIONES.............................................................................................1*3
USO DE ENUMERACIONES..........................................................................................................1*5
LA CLASE S"STEM.ENUM.........................................................................................................1**
TEMA 15: INTERFACES ..................................................................................................... 1*!
CONCEPTO DE INTERFAZ..........................................................................................................1*!
DEFINICIN DE INTERFACES.....................................................................................................1*!
IMPLEMENTACIN DE INTERFACES..........................................................................................1*+
ACCESO A MIEMBROS DE UNA INTERFAZ.................................................................................1!#
TEMA 1*: INSTRUCCIONES .............................................................................................. 1!5
CONCEPTO DE INSTRUCCIN....................................................................................................1!5
INSTRUCCIONES B,SICAS..........................................................................................................1!5
INSTRUCCIONES CONDICIONALES.............................................................................................1!*
INSTRUCCIONES ITERATIVAS....................................................................................................1!+
INSTRUCCIONES DE E(CEPCIONES............................................................................................185
INSTRUCCIONES DE SALTO........................................................................................................1+3
OTRAS INSTRUCCIONES.............................................................................................................1+*
TEMA 1!: ATRIBUTOS ....................................................................................................... #%#
CONCEPTO DE ATRIBUTO..........................................................................................................#%#
UTILIZACIN DE ATRIBUTOS....................................................................................................#%#
DEFINICIN DE NUEVOS ATRIBUTOS........................................................................................#%4
LECTURA DE ATRIBUTOS EN TIEMPO DE E&ECUCIN..............................................................#%*
ATRIBUTOS DE COMPILACIN..................................................................................................#1%
TEMA 18: CDIGO INSEGURO ........................................................................................ #1#
CONCEPTO DE CDIGO INSEGURO............................................................................................#1#
COMPILACIN DE CDIGOS INSEGUROS..................................................................................#1#
MARCACIN DE CDIGOS INSEGUROS.....................................................................................#13
DEFINICIN DE PUNTEROS........................................................................................................#14
Jos Antonio Gonzlez Seco Pgina !
El lenguaje de programacin C# ndice
MANIPULACIN DE PUNTEROS..................................................................................................#15
OPERADORES RELACIONADOS CON CDIGO INSEGURO..........................................................#1+
FI&ACIN DE VARIABLES APUNTADAS......................................................................................##1
TEMA 1+: DOCUMENTACIN (ML ................................................................................ ##4
CONCEPTO " UTILIDAD DE LA DOCUMENTACIN (ML.........................................................##4
INTRODUCCIN A (ML............................................................................................................##4
COMENTARIOS DE DOCUMENTACIN (ML.............................................................................##*
ETIQUETAS RECOMENDADAS PARA DOCUMENTACIN (ML ................................................##8
GENERACIN DE DOCUMENTACIN (ML...............................................................................#33
ESTRUCTURA DE LA DOCUMENTACIN (ML..........................................................................#3*
SEPARACIN ENTRE DOCUMENTACIN (ML " CDIGO FUENTE..........................................#38
TEMA #%: EL COMPILADOR DE C$ DE MICROSOFT ................................................. #4%
INTRODUCCIN.......................................................................................................................... #4%
SINTA(IS GENERAL DE USO DEL COMPILADOR........................................................................#4%
OPCIONES DE COMPILACIN.....................................................................................................#4#
ACCESO AL COMPILADOR DESDE VISUAL STUDIO.NET.........................................................#55
DOCUMENTACIN DE REFERENCIA ............................................................................ #58
BIBLIOGRAFA............................................................................................................................ #58
INFORMACIN EN INTERNET SOBRE C$...................................................................................#58
PORTALES.................................................................................................................................. #5+
GRUPOS DE NOTICIAS " LISTAS DE CORREO............................................................................#5+
Jos Antonio Gonzlez Seco Pgina "
El lenguaje de programacin C# #ntroduccin a la o$ra
Introduccin a Ia obra
Requisitos previos recomendados
En principio% para entender con &acilidad esta o$ra es recomenda$le estar &amiliarizado
con los conceptos $sicos de programacin orientada a o$jetos% en particular con los
lenguajes de programacin C'' o Ja(a de los )ue C# deri(a*
Sin em$argo% estos no son re)uisitos &undamentales para entenderla +a )ue cada (ez )ue
en ella se introduce alg,n elemento del lenguaje se de&inen + e-plican los conceptos
$sicos )ue permiten entenderlo* A,n as.% sigue siendo recomenda$le disponer de los
re)uisitos antes mencionados para poder mo(erse con ma+or soltura por el li$ro +
apro(ec/arlo al m-imo*
Estructura de la obra
0sicamente el eje central de la o$ra es el lenguaje de programacin C#% del )ue no slo
se descri$e su sinta-is sino )ue tam$in se intenta e-plicar cules son las razones )ue
justi&ican las decisiones tomadas en su dise1o + cules son los errores ms di&.ciles de
detectar )ue pueden producirse al desarrollar de aplicaciones con l* Sin em$argo% los
2 temas utilizados para ello pueden descomponerse en tres grandes $lo)ues3
B-./01 1: I234.5066782 9 C$ : .NET 3 Antes de empezar a descri$ir el lenguaje
es o$ligatorio e-plicar el por)u de su e-istencia% + para ello es necesario antes
introducir la plata&orma *4E5 de 6icroso&t con la )ue est mu+ ligado* Ese es el
o$jeti(o de los temas 1 + % donde se e-plican las caracter.sticas + conceptos
$sicos de C# + *4E5% las no(edosas aportaciones de am$os + se introduce la
programacin + compilacin de aplicaciones en C# con el t.pico 78ola 6undo9
B-./01 #: D1;647<6782 51- -12=09>1: Este $lo)ue constitu+e el grueso de la
o$ra + est &ormado por los temas comprendidos entre el ! + el 1:* En ellos se
descri$en pormenorizadamente los aspectos del lenguaje mostrando ejemplos de
su uso% e-plicando su por)u + a(isando de cules son los pro$lemas ms
di&.ciles de detectar )ue pueden surgir al utilizarlos + cmo e(itarlos*
B-./01 3: D1;647<6782 51- 6.?<7-95.4 3 Este ,ltimo $lo)ue% &ormado solamente
por el tema 2% descri$e cmo se utiliza el compilador de C# tanto desde la
(entana de consola como desde la /erramienta ;isual Studio*4E5* Como al
descri$ir el lenguaje% tam$in se intenta dar una e-plicacin lo ms e-/austi(a%
,til + &cil de entender posi$le del signi&icado% por)u + aplica$ilidad de las
opciones de compilacin )ue o&rece*
Convenciones de notacin utilizadas
El lenguaje de programacin C# #ntroduccin a la o$ra
Para a+udar a resaltar la in&ormacin cla(e se utilizan di&erentes con(enciones respecto
a los tipos de letra usados para representar cada tipo de contenido* <stas son3
El te-to correspondiente a e-plicaciones se /a escrito usando la &uente 5imes
4e= >oman de 1 puntos de tama1o% como es el caso de este prra&o*
?os &ragmentos de cdigo &uente se /an escrito usando la &uente Arial de 12
puntos de tama1o tal + como se muestra a continuacin3
class HolaMundo
{
static void Main()
{
System.Console.WriteLine(Hola Mundo!);
}
@
Esta misma &uente es la )ue se usar desde las e-plicaciones cada (ez )ue se
/aga re&erencia a alg,n elemento del cdigo &uente* Si adems dic/o elemento es
una pala$ra reser(ada del lenguaje o (iene prede&inido en la li$rer.a de *4E5% su
nom$re se escri$ir en negrita para as. resaltar el carcter especial del mismo
?as re&erencias a te-tos de la inter&az del sistema operati(o Anom$res de
&ic/eros + directorios% te-to de la l.nea de comandos% etc* B se /an escrito usando
la &uente Courier 4e= de 12 puntos de tama1o* Por ejemplo3
csc HolaMundo.cs
Cuando adems este tipo de te-to se utilice para /acer re&erencia a elementos
prede&inidos tales como e-tensiones de &ic/eros recomendadas o nom$res de
aplicaciones incluidas en el SCD% se escri$ir en negrita*
Al descri$irse la sinta-is de de&inicin de los elementos del lenguaje se usar
&uente Arial de 12 puntos de tama1o + se representarn en cursi(a los elementos
opcionales en la misma% en negrita los )ue de$an escri$irse tal cual% + sin
negrita + entre s.m$olos E + F los )ue representen de te-to )ue de$a colocarse
en su lugar* Por ejemplo% cuando se dice )ue una clase /a de de&inirse as.3
cIass <nombreClase>
{
<miembros>
}
?o )ue se est diciendo es )ue /a de escri$irse la pala$ra reser(ada class%
seguida de te-to )ue represente el nom$re de la clase a de&inir% seguido de una
lla(e de apertura AGB% seguido opcionalmente de te-to )ue se corresponda con
de&iniciones de miem$ros + seguido de una lla(e de cierre A@B
Si lo )ue se de&ine es la sinta-is de llamada a alguna aplicacin concreta%
entonces la notacin )ue se usar es similar a la anterior slo )ue en (ez de
&uente Arial se utilizar &uente Courier 4e= de 12 puntos de tama1o*
El lenguaje de programacin C# #ntroduccin a la o$ra
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
TEMA 1: Introduccin a Microsoft.NET
Microsoft.NET
6icroso&t*4E5 es el conjunto de nue(as tecnolog.as en las )ue 6icroso&t /a estado
tra$ajando durante los ,ltimos a1os con el o$jeti(o de o$tener una plata&orma sencilla +
potente para distri$uir el so&t=are en &orma de ser(icios )ue puedan ser suministrados
remotamente + )ue puedan comunicarse + com$inarse unos con otros de manera
totalmente independiente de la plata&orma% lenguaje de programacin + modelo de
componentes con los )ue /a+an sido desarrollados* <sta es la llamada <-939@.4?9
.NET% + a los ser(icios antes comentados se les denomina ;14A767.; B1C*
Para crear aplicaciones para la plata&orma *4E5% tanto ser(icios He$ como aplicaciones
tradicionales Aaplicaciones de consola% aplicaciones de (entanas% ser(icios de Hindo=s
45% etc*B% 6icroso&t /a pu$licado el denominado Iit de desarrollo de so&t=are conocido
como .NET F49?1D.4E SDF% )ue inclu+e las /erramientas necesarias tanto para su
desarrollo como para su distri$ucin + ejecucin + V7;09- S3057..NET% )ue permite
/acer todo la anterior desde una inter&az (isual $asada en (entanas* Am$as /erramientas
puede descargarse gratuitamente desde /ttp3JJ===*msdn*microso&t*comJnet% aun)ue la
,ltima slo est disponi$le para su$scriptores 6SC4 Kni(ersal Alos no su$scriptores
pueden pedirlo desde dic/a direccin + se les en(iar gratis por correo ordinarioB
El concepto de 6icroso&t*4E5 tam$in inclu+e al conjunto de nue(as aplicaciones )ue
6icroso&t + terceros /an Ao estnB desarrollando para ser utilizadas en la plata&orma
*4E5* Entre ellas podemos destacar aplicaciones desarrolladas por 6icroso&t tales como
Hindo=s*4E5% 8ailstorm% ;isual Studio*4E5% 6S4*4E5% L&&ice*4E5% + los nue(os
ser(idores para empresas de 6icroso&t ASM? Ser(er*4E5% E-c/ange*4E5% etc*B
Common Language Runtime (CLR
El C.??.2 L92=09=1 R0237?1 ACLRB es el n,cleo de la plata&orma *4E5* Es el
motor encargado de gestionar la ejecucin de las aplicaciones para ella desarrolladas + a
las )ue o&rece numerosos ser(icios )ue simpli&ican su desarrollo + &a(orecen su
&ia$ilidad + seguridad* ?as principales caracter.sticas + ser(icios )ue o&rece el C?> son3
M.51-. 51 <4.=49?96782 6.2;7;31231: A todos los ser(icios + &acilidades
o&recidos por el C?> se accede de la misma &orma3 a tra(s de un modelo de
programacin orientado a o$jetos* Esto es una di&erencia importante respecto al
modo de acceso a los ser(icios o&recidos por los algunos sistemas operati(os
actuales Apor ejemplo% los de la &amilia Hindo=sB% en los )ue a algunos ser(icios
se les accede a tra(s de llamadas a &unciones glo$ales de&inidas en C??s + a
otros a tra(s de o$jetos Ao$jetos CL6 en el caso de la &amilia Hindo=sB
M.51-. 51 <4.=49?96782 ;1267--.: Con el C?> desaparecen muc/os elementos
complejos incluidos en los sistemas operati(os actuales Aregistro de Hindo=s%
GK#Cs% 8>ESK?5S% #KnIno=n% etc*B El C?> no es )ue a$straiga al
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
programador de estos conceptos% sino )ue son conceptos )ue no e-isten en la
plata&orma *4E5
E-7?7296782 51- G72@7142. 51 -9; DLL;H: En la plata&orma *4E5 desaparece el
pro$lema conocido como Nin&ierno de las C??sO )ue se da en los sistemas
operati(os actuales de la &amilia Hindo=s% pro$lema )ue consiste en )ue al
sustituirse (ersiones (iejas de C??s compartidas por (ersiones nue(as puede
)ue aplicaciones )ue &ueron dise1adas para ser ejecutadas usando las (iejas
dejen de &uncionar si las nue(as no son 122P compati$les con las anteriores* En
la plata&orma *4E5 las (ersiones nue(as de las C??s pueden coe-istir con las
(iejas% de modo )ue las aplicaciones dise1adas para ejecutarse usando las (iejas
podrn seguir usndolas tras instalacin de las nue(as* Esto% o$(iamente%
simpli&ica muc/o la instalacin + desinstalacin de so&t=are*
E>1606782 ?0-37<-939@.4?9: El C?> act,a como una m)uina (irtual%
encargndose de ejecutar las aplicaciones dise1adas para la plata&orma *4E5* Es
decir% cual)uier plata&orma para la )ue e-ista una (ersin del C?> podr
ejecutar cual)uier aplicacin *4E5* 6icroso&t /a desarrollado (ersiones del
C?> para la ma+or.a de las (ersiones de Hindo=s3 Hindo=s :Q% Hindo=s :R%
Hindo=s 6E% Hindo=s 45 "*2% Hindo=s 222% Hindo=s SP + Hindo=s CE
A)ue puede ser usado en CPKs )ue no sean de la &amilia -RTB Por otro lado
6icroso&t /a &irmado un acuerdo con Corel para portar el C?> a ?inu- +
tam$in /a+ terceros )ue estn desarrollando de manera independiente (ersiones
de li$re distri$ucin del C?> para ?inu-* As.mismo% dado )ue la ar)uitectura
del C?> est totalmente a$ierta% es posi$le )ue en el &uturo se dise1en (ersiones
del mismo para otros sistemas operati(os*
I231=496782 51 -12=09>1;: Cesde cual)uier lenguaje para el )ue e-ista un
compilador )ue genere cdigo para la plata&orma *4E5 es posi$le utilizar cdigo
generado para la misma usando cual)uier otro lenguaje tal + como si de cdigo
escrito usando el primero se tratase* 6icroso&t /a desarrollado un compilador de
C# )ue genera cdigo de este tipo% as. como (ersiones de sus compiladores de
;isual 0asic A;isual 0asic*4E5B + C'' AC'' con e-tensiones gestionadasB )ue
tam$in lo generan + una (ersin del intrprete de JScript AJScript*4E5B )ue
puede interpretarlo* ?a integracin de lenguajes esta )ue es posi$le escri$ir una
clase en C# )ue /erede de otra escrita en ;isual 0asic*4E5 )ue% a su (ez% /erede
de otra escrita en C'' con e-tensiones gestionadas*
G1;3782 51 ?1?.479: El C?> inclu+e un 416.-163.4 51 C9;049 )ue e(ita )ue el
programador tenga )ue tener en cuenta cundo /a de destruir los o$jetos )ue
dejen de serle ,tiles* Este recolector es una aplicacin )ue se acti(a cuando se
)uiere crear alg,n o$jeto nue(o + se detecta )ue no )ueda memoria li$re para
/acerlo% caso en )ue el recolector recorre la memoria dinmica asociada a la
aplicacin% detecta )u o$jetos /a+ en ella )ue no puedan ser accedidos por el
cdigo de la aplicacin% + los elimina para limpiar la memoria de No$jetos
$asuraO + permitir la creacin de otros nue(os* Gracias a este recolector se
e(itan errores de programacin mu+ comunes como intentos de $orrado de
o$jetos +a $orrados% agotamiento de memoria por ol(ido de eliminacin de
o$jetos in,tiles o solicitud de acceso a miem$ros de o$jetos +a destruidos*
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
S1=047595 51 37<.;: El C?> &acilita la deteccin de errores de programacin
di&.ciles de localizar compro$ando )ue toda con(ersin de tipos )ue se realice
durante la ejecucin de una aplicacin *4E5 se /aga de modo )ue los tipos
origen + destino sean compati$les*
A7;-9?7123. 51 <4.61;.;: El C?> asegura )ue desde cdigo perteneciente a un
determinado proceso no se pueda acceder a cdigo o datos pertenecientes a otro%
lo )ue e(ita errores de programacin mu+ &recuentes e impide )ue unos procesos
puedan atacar a otros* Esto se consigue gracias al sistema de seguridad de tipos
antes comentado% pues e(ita )ue se pueda con(ertir un o$jeto a un tipo de
ma+or tama1o )ue el su+o propio% +a )ue al tratarlo como un o$jeto de ma+or
tama1o podr.a accederse a espacios en memoria ajenos a l )ue podr.an
pertenecer a otro proceso* 5am$in se consigue gracias a )ue no se permite
acceder a posiciones ar$itrarias de memoria*
T4939?7123. 51 1I61<67.21;: En el C?> todo los errores )ue se puedan
producir durante la ejecucin de una aplicacin se propagan de igual manera3
mediante e-cepciones* Esto es mu+ di&erente a como se (en.a /aciendo en los
sistemas Hindo=s /asta la aparicin de la plata&orma *4E5% donde ciertos
errores se transmit.an mediante cdigos de error en &ormato Hin!% otros
mediante 8>ESK?5s + otros mediante e-cepciones*
El C?> permite )ue e-cepciones lanzadas desde cdigo para *4E5 escrito en un
cierto lenguaje se puedan capturar en cdigo escrito usando otro lenguaje% e
inclu+e mecanismos de depuracin )ue pueden saltar desde cdigo escrito
para *4E5 en un determinado lenguaje a cdigo escrito en cual)uier otro* Por
ejemplo% se puede recorrer la pila de llamadas de una e-cepcin aun)ue sta
inclu+a mtodos de&inidos en otros mdulos usando otros lenguajes*
S.<.431 ?0-37J7-.: El C?> es capaz de tra$ajar con aplicaciones di(ididas en
m,ltiples /ilos de ejecucin )ue pueden ir e(olucionando por separado en
paralelo o intercalndose% seg,n el n,mero de procesadores de la m)uina so$re
la )ue se ejecuten* ?as aplicaciones pueden lanzar nue(os /ilos% destruirlos%
suspenderlos por un tiempo o /asta )ue les llegue una noti&icacin% en(iarles
noti&icaciones% sincronizarlos% etc*
D7;347C06782 3492;<941231: El C?> o&rece la in&raestructura necesaria para
crear o$jetos remotos + acceder a ellos de manera completamente transparente a
su localizacin real% tal + como si se encontrasen en la m)uina )ue los utiliza*
S1=047595 9A92K959: El C?> proporciona mecanismos para restringir la
ejecucin de ciertos cdigos o los permisos asignados a los mismos seg,n su
procedendecia o el usuario )ue los ejecute* Es decir% puede no darse el mismo
ni(el de con&ianza a cdigo procedente de #nternet )ue a cdigo instalado
localmente o procedente de una red localU puede no darse los mismos permisos a
cdigo procedente de un determinado &a$ricante )ue a cdigo de otroU + puede
no darse los mismos permisos a un mismo cdigos seg,n el usuario )ue lo est
ejecutando o seg,n el rol )ue ste desempe1e* Esto permite asegurar al
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
administrador de un sistema )ue el cdigo )ue se est ejecutando no pueda
poner en peligro la integridad de sus arc/i(os% la del registro de Hindo=s% etc*
I2314.<149C7-7595 6.2 6857=. 9237=0.: El C?> incorpora los mecanismos
necesarios para poder acceder desde cdigo escrito para la plata&orma *4E5 a
cdigo escrito pre(iamente a la aparicin de la misma +% por tanto% no preparado
para ser ejecutando dentro de ella* Estos mecanismos permiten tanto el acceso a
o$jetos CL6 como el acceso a &unciones sueltas de C??s pree-istentes Acomo
la AP# Hin!B
Como se puede deducir de las caracter.sticas comentadas% el C?> lo )ue /ace es
gestionar la ejecucin de las aplicaciones dise1adas para la plata&orma *4E5* Por esta
razn% al cdigo de estas aplicaciones se le suele llamar 6857=. =1;37.295.% + al cdigo
no escrito para ser ejecutado directamente en la plata&orma *4E5 se le suele llamar
6857=. 2. =1;37.295.*
Microsoft !ntermediate Language (M"!L
5odos los compiladores )ue generan cdigo para la plata&orma *4E5 no generan cdigo
m)uina para CPKs -RT ni para ning,n otro tipo de CPK concreta% sino )ue generan
cdigo escrito en el lenguaje intermedio conocido como 6icroso&t #ntermediate
?enguage A6S#?B El C?> da a las aplicaciones las sensacin de )ue se estn ejecutando
so$re una m)uina (irtual% + precisamente 6S#? es el cdigo m)uina de esa m)uina
(irtual* Es decir% 6S#? es el ,nico cdigo )ue es capaz de interpretar el C?>% + por
tanto cuando se dice )ue un compilador genera cdigo para la plata&orma *4E5 lo )ue
se est diciendo es )ue genera 6S#?*
6S#? /a sido creado por 6icroso&t tras consultar a numerosos especialistas en la
escritura de compiladores + lenguajes tanto del mundo acadmico como empresarial* Es
un lenguaje de un ni(el de a$straccin muc/o ms alto )ue el de la ma+or.a de los
cdigos m)uina de las CPKs e-istentes% e inclu+e instrucciones )ue permiten tra$ajar
directamente con o$jetos Acrearlos% destruirlos% inicializarlos% llamar a mtodos
(irtuales% etc*B% ta$las + e-cepciones Alanzarlas% capturarlas + tratarlasB
Va se coment )ue el compilador de C# compila directamente el cdigo &uente a 6S#?%
)ue 6icroso&t /a desarrollado nue(as (ersiones de sus lenguajes ;isual 0asic A;isual
0asic*4E5B + C'' AC'' con e-tensiones gestionadasB cu+os compiladores generan
6S#?% + )ue /a desarrollado un intrprete de JScript AJScript*4E5B )ue genera cdigo
6S#?* Pues $ien% tam$in /a+ numerosos terceros )ue /an anunciado estar realizando
(ersiones para la plata&orma *4E5 de otros lenguajes como AP?% CA6?% Co$ol% Ei&&el%
Wortran% 8asIell% Ja(a% 6ercur+% 6?% 6ondrian% L$eron% Lz% Pascal% Perl% P+t/on%
>PG% Sc/eme + SmalltalI*
?a principal (entaja del 6S#? es )ue &acilita la ejecucin multiplata&orma + la
integracin entre lenguajes al ser independiente de la CPK + proporcionar un &ormato
com,n para el cdigo m)uina generado por todos los compiladores )ue generen cdigo
para *4E5* Sin em$argo% dado )ue las CPKs no pueden ejecutar directamente 6S#?%
antes de ejecutarlo /a$r )ue con(ertirlo al cdigo nati(o de la CPK so$re la )ue se
(a+a a ejecutar* Ce esto se encarga un componente del C?> conocido como compilador
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
J#5 AJustX#nX5imeB o jitter )ue (a con(irtiendo dinmicamente el cdigo 6S#? a
ejecutar en cdigo nati(o seg,n sea necesario* Este jitter se distri$u+e en tres (ersiones3
>73314 2.4?9-: Es el )ue se suele usar por de&ecto% + slo compila el cdigo
6S#? a cdigo nati(o a medida )ue (a siendo necesario% pues as. se a/orra
tiempo + memoria al e(itarse tener )ue compilar innecesariamente cdigo )ue
nunca se ejecute* Para conseguir esto% el cargador de clases del C?> sustitu+e
inicialmente las llamadas a mtodos de las nue(as clases )ue (a+a cargando por
llamadas a &unciones au-iliares Astu$sB )ue se encarguen de compilar el
(erdadero cdigo del mtodo* Kna (ez compilado% la llamada al stu$ es
sustituida por una llamada directa al cdigo +a compilado% con lo )ue posteriores
llamadas al mismo no necesitarn compilacin*
>73314 16.28?76.: Wunciona de &orma similar al jitter normal solo )ue no realiza
ninguna optimizacin de cdigo al compilar sino )ue traduce cada instruccin
6S#? por su e)ui(alente en el cdigo m)uina so$re la )ue se ejecute* Esta
especialmente pensado para ser usado en dispositi(os empotrados )ue dispongan
de poca potencia de CPK + poca memoria% pues aun)ue genere cdigo ms
ine&iciente es menor el tiempo + memoria )ue necesita para compilar* Es ms%
para a/orrar memoria este jitter puede descargar cdigo +a compilado )ue lle(e
cierto tiempo sin ejecutarse + sustituirlo de nue(o por el stu$ apropiado* Por
estas razones% este es el jitter usado por de&ecto en Hindo=s CE% sistema
operati(o )ue se suele incluir en los dispositi(os empotrados antes mencionados*
Ltra utilidad del jitter econmico es )ue &acilita la adaptacin de la
plata&orma *4E5 a nue(os sistemas por)ue es muc/o ms sencillo de
implementar )ue el normal* Ce este modo% gracias a l es posi$le desarrollar
rpidamente una (ersin del C?> )ue pueda ejecutar aplicaciones gestionadas
aun)ue sea de una &orma poco e&iciente% + una (ez desarrollada es posi$le
centrarse en desarrollar el jitter normal para optimizar la ejecucin de las
mismas*
<41>73314: Se distri$u+e como una aplicacin en l.nea de comandos llamada
ngen.exe mediante la )ue es posi$le compilar completamente cual)uier
ejecuta$le o li$rer.a Acual)uier ensam$lado en general% aun)ue este concepto se
(er ms adelanteB )ue contenga cdigo gestionado + con(ertirlo a cdigo
nati(o% de modo )ue posteriores ejecuciones del mismo se /arn usando esta
(ersin +a compilada + no se perder tiempo en /acer la compilacin dinmica*
?a actuacin de un jitter durante la ejecucin de una aplicacin gestionada puede dar la
sensacin de /acer )ue sta se ejecute ms lentamente de$ido a )ue /a de in(ertirse
tiempo en las compilaciones dinmicas* Esto es cierto% pero /a+ )ue tener en cuenta )ue
es una solucin muc/o ms e&iciente )ue la usada en otras plata&ormas como Ja(a% +a
)ue en *4E5 cada cdigo no es interpretado cada (ez )ue se ejecuta sino )ue slo es
compilado la primera (ez )ue se llama al mtodo al )ue pertenece* Es ms% el /ec/o de
)ue la compilacin se realice dinmicamente permite )ue el jitter tenga acceso a muc/a
ms in&ormacin so$re la m)uina en )ue se ejecutar la aplicacin del )ue tendr.a
cual)uier compilador tradicional% con lo )ue puede optimizar el cdigo para ella
generado Apor ejemplo% usando las instrucciones especiales del Pentium ### si la
m)uina las admite% usando registros e-tra% inclu+endo cdigo inline% etc*B Adems%
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
como el recolector de $asura de *4E5 mantiene siempre compactada la memoria
dinmica las reser(as de memoria se /arn ms rpido% so$re todo en aplicaciones )ue
no agoten la memoria +% por tanto% no necesiten de una recoleccin de $asura* Por estas
razones% los ingenieros de 6icroso&t piensan )ue &uturas (ersiones de sus jitters podrn
incluso conseguir )ue el cdigo gestionado se ejecute ms rpido )ue el no gestionado*
Metadatos
En la plata&orma *4E5 se distinguen dos tipos de ?850-.; de cdigo compilado3
1>16039C-1; Ae-tensin .1I1B + -7C414L9; 51 12-961 572M?76. Ae-tensin .5--
generalmenteB Am$os son &ic/eros )ue contienen de&iniciones de tipos de datos% + la
di&erencia entre ellos es )ue slo los primeros disponen de un mtodo especial )ue sir(e
de punto de entrada a partir del )ue es posi$le ejecutar el cdigo )ue contienen /aciendo
una llamada desde la l.nea de comandos del sistema operati(o* A am$os tipos de
mdulos se les suele llamar 1>16039C-1; <.439C-1; APEB% +a )ue su cdigo puede
ejecutarse en cual)uiera de los di&erentes sistemas operati(os de la &amilia Hindo=s
para los )ue e-iste alguna (ersin del C?>*
El contenido de un mdulo no slo 6S#?% sino )ue tam$in consta de otras dos reas
mu+ importantes3 la ca$ecera de C?> + los metadatos3
?a 69C16149 51 CLR es un pe)ue1o $lo)ue de in&ormacin )ue indica )ue se trata
de un mdulo gestionado e indica es la (ersin del C?> )ue necesita% cul es su
&irma digital% cul es su punto de entrada Asi es un ejecuta$leB% etc*
?os ?139593.; son un conjunto de datos organizados en &orma de ta$las )ue
almacenan in&ormacin so$re los tipos de&inidos en el mdulo% los miem$ros de
stos + so$re cules son los tipos e-ternos al mdulo a los )ue se les re&erencia en el
mdulo* ?os metadatos de cada modulo los genera automticamente el compilador
al crearlo% + entre sus ta$las se inclu+en
1
3

T9C-9 D1;647<6782
6oduleCe& Ce&ine las caracter.sticas del mdulo* Consta de un ,nico elemento
)ue almacena un identi&icador de (ersin de mdulo AGK#C creado
por el compiladorB + el nom$re de &ic/ero )ue se dio al mdulo al
compilarlo Aas. este nom$re siempre estar disponi$le% aun)ue se
renom$re el &ic/eroB
5+peCe& Ce&ine las caracter.sticas de los tipos de&inidos en el mdulo* Ce cada
tipo se almacena su nom$re% su tipo padre% sus modi&icadores de
acceso + re&erencias a los elementos de las ta$las de miem$ros
correspondientes a sus miem$ros*
6et/odCe& Ce&ine las caracter.sticas de los mtodos de&inidos en el mdulo* Ce
cada mtodo se guarda su nom$re% signatura Apor cada parmetro se
inclu+e una re&erencia al elemento apropiado en la ta$la ParamCe&B%
modi&icadores + posicin del mdulo donde comienza el cdigo 6S#?
de su cuerpo*
1
4o se preocupe si no entiende a,n algunos de los conceptos nue(os introducido en las descripciones de
las ta$las de metadatos% pues ms adelante se irn e-plicando detalladamente*
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
ParamCe& Ce&ine las caracter.sticas de los parmetros de&inidos en el mdulo* Ce
cada parmetro se guarda su nom$re + modi&icadores*
WieldCe& Ce&ine las caracter.sticas de los campos de&inidos en el mdulo* Ce
cada uno se almacena in&ormacin so$re cul es su nom$re% tipo +
modi&icadores*
Propert+Ce& Ce&ine las caracter.sticas de las propiedades de&inidas en el mdulo*
Ce cada una se indica su nom$re% tipo% modi&icadores + re&erencias a
los elementos de la ta$la 6et/odCe& correspondientes a sus mtodos
setJget*
E(entCe& Ce&ine las caracter.sticas de los e(entos de&inidos en el mdulo* Ce
cada uno se indica su nom$re% tipo% modi&icadores* + re&erencias a los
elementos de la ta$la 6et/odCe& correspondientes a sus mtodos
addJremo(e*
Assem$l+>e& #ndica cules son los ensam$lados e-ternos a los )ue se re&erencia en
el mdulo* Ce cada uno se indica cul es su nom$re de &ic/ero Asin
e-tensinB% (ersin% idioma + marca de cla(e p,$lica*
6odule>e& #ndica cules son los otros mdulos del mismo ensam$lado a los )ue
re&erencia el mdulo* Ce cada uno se indica cul es su nom$re de
&ic/ero*
5+pe>e& #ndica cules son los tipos e-ternos a los )ue se re&erencia en el
mdulo* Ce cada uno se indica cul es su nom$re +% seg,n donde
estn de&inidos% una re&erencia a la posicin adecuada en la ta$la
Assem$l+>e& o en la ta$la 6odule>e&*
6em$er>e& #ndican cules son los miem$ros de&inidos e-ternamente a los )ue se
re&erencia en el mdulo* Estos miem$ros pueden ser campos% mtodos%
propiedades o e(entosU + de cada uno de ellos se almacena
in&ormacin so$re su nom$re + signatura% as. como una re&erencia a la
posicin de la ta$la 5+pe>e& donde se almacena in&ormacin relati(a
al tipo del )ue es miem$ro*
T9C-9 1 : Principales ta$las de metadatos
4tese )ue el signi&icado de los metadatos es similar al de otras tecnolog.as pre(ias a la
plata&orma *4E5 como lo son los &ic/eros #C?* Sin em$argo% los metadatos tienen dos
(entajas importantes so$re stas3 contiene ms in&ormacin + siempre se almacenan
incrustados en el mdulo al )ue descri$en% /aciendo imposi$le la separacin entre
am$os* Adems% como se (er ms adelante% es posi$le tanto consultar los metadatos de
cual)uier mdulo a tra(s de las clases del espacio de nom$res S:;31?.R1@-1637.2 de la
0C? como a1adirles in&ormacin adicional mediante 9347C03.; Ase (er ms adelanteB

Ensamblados
Kn 12;9?C-95. es una agrupacin lgica de uno o ms mdulos o &ic/eros de recursos
A&ic/eros *G#W% *856?% etc*B )ue se englo$an $ajo un nom$re com,n* Kn programa
puede acceder a in&ormacin o cdigo almacenados en un ensam$lado sin tener por)u
sa$e cul es el &ic/ero en concreto donde se encuentran% por lo )ue los ensam$lados nos
permiten a$straernos de la u$icacin &.sica del cdigo )ue ejecutemos o de los recursos
)ue usemos* Por ejemplo% podemos incluir todos los tipos de una aplicacin en un
mismo ensam$lado pero colocando los ms &recuentemente usados en un cierto mdulo
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
+ los menos usados en otro% de modo )ue slo se descarguen de #nternet los ,ltimos si
es )ue se (an a usar*
5odo ensam$lado contiene un ?927@71;3.% )ue son metadatos con in&ormacin so$re las
caracter.sticas del ensam$lado* Este mani&iesto puede almacenarse cual)uiera de los
mdulos )ue &ormen el ensam$lado o en uno espec.&icamente creado para ello% caso ste
,ltimo necesario cuando es un 12;9?C-95. ;93N-731 Aslo contiene recursosB
?as principales ta$las incluidas en los mani&iestos son las siguientes3
T9C-9 D1;647<6782
Assem$l+Ce& Ce&ine las caracter.sticas del ensam$lado* Consta de un ,nico
elemento )ue almacena el nom$re del ensam$lado sin
e-tensin% (ersin% idioma% cla(e p,$lica + tipo de algoritmo de
dispersin usado para /allar los (alores de dispersin de la
ta$la WileCe&*
WileCe& Ce&ine cules son los arc/i(os )ue &orman el ensam$lado* Ce
cada uno se da su nom$re + (alor de dispersin* 4tese )ue
slo el mdulo )ue contiene el mani&iesto sa$r )u &ic/eros
)ue &orman el ensam$lado% pero el resto de &ic/eros del mismo
no sa$rn si pertenecen o no a un ensam$lado Ano contienen
metadatos )ue les indi)ue si pertenecen a un ensam$ladoB
6ani&est>esourceCe& Ce&ine las caracter.sticas de los recursos incluidos en el
mdulo* Ce cada uno se indica su nom$re + modi&icadores de
acceso* Si es un recurso incrustado se indica dnde empieza
dentro del PE )ue lo contiene% + si es un &ic/ero independiente
se indica cul es el elemento de la ta$la WileCe&
correspondiente a dic/o &ic/ero*
E-ported5+pesCe& #ndica cules son los tipos de&inidos en el ensam$lado +
accesi$les desde &uera del mismo* Para a/orrar espacio slo
recogen los )ue no pertenezcan al mdulo donde se inclu+e el
mani&iesto% + de cada uno se indica su nom$re% la posicin en
la ta$la WileCe& del &ic/ero donde se /a implementado + la
posicin en la ta$la 5+peCe& correspondiente a su de&inicin*
Assem$l+ProccesorCe& #ndica en )u procesadores se puede ejecutar el ensam$lado% lo
)ue puede ser ,til sa$erlo si el ensam$lado contiene mdulos
con cdigo nati(o Apodr.a /acerse usando C'' con
e-tensiones gestionadasB Suele estar (ac.a% lo )ue indica )ue se
puede ejecutar en cual)uier procesadorU pero si estu(iese llena%
cada elemento indicar.a un tipo de procesador admitido seg,n
el &ormato de identi&icadores de procesador del &ic/ero
Hin45*/ incluido con ;isual Studio*4E5 Apor ejemplo% QRT Y
Pentium% 22 Y Ar)uitectura #AT"% etc*B
Assem$l+LSCe& #ndica $ajo )u sistemas operati(os se puede ejecutar el
ensam$lado% lo )ue puede ser ,til si contiene mdulos con
tipos o mtodos disponi$les slo en ciertos sistemas* Suele
estar (ac.a% lo )ue indica )ue se puede ejecutar en cual)uier
procesadorU pero si estu(iese llena% indicar.a el identi&icador de
cada uno de los sistemas admitidos siguiendo el &ormato del
Hin45*/ de ;isual Studio*4E5 Apor ejemplo% 2 Y &amilia
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
Hindo=s :S% 1 Y &amilia Hindo=s 45% etc*B + el n,mero de la
(ersin del mismo a partir de la )ue se admite*
T9C-9 # : Principales ta$las de un mani&iesto
Para asegurar )ue no se /a+a alterado la in&ormacin de ning,n ensam$lado se usa el
criptosistema de cla(e p,$lica >SA* ?o )ue se /ace es calcular el cdigo de dispersin
S8AX1 del mdulo )ue contenga el mani&iesto e incluir tanto este (alor ci&rado con
>SA A@74?9 57=739-B como la cla(e p,$lica necesaria para desci&rarlo en alg,n lugar del
mdulo )ue se indicar en la ca$ecera de C?>* Cada (ez )ue se (a+a a cargar en
memoria el ensam$lado se calcular su (alor de dispersin de nue(o + se compro$ar
)ue es igual al resultado de desci&rar el original usando su cla(e p,$lica* Si no &uese as.
se detectar.a )ue se /a adulterado su contenido*
Para asegurar tam$in )ue los contenidos del resto de &ic/eros )ue &ormen un
ensam$lado no /a+an sido alterados lo )ue se /ace es calcular el cdigo de dispersin
de stos antes de ci&rar el ensam$lado + guardarlo en el elemento correspondiente a cada
&ic/ero en la ta$la WileCe& del mani&iesto* El algoritmo de ci&rado usado por de&ecto es
S8AX1% aun)ue en este caso tam$in se da la posi$ilidad de usar 6CQ* En am$os casos%
cada (ez )ue se accede al &ic/ero para acceder a un tipo o recurso se calcular de nue(o
su (alor de dispersin + se compro$ar )ue coincida con el almacenado en WileCe&*
Cado )ue las cla(es p,$licas son (alores )ue ocupan muc/os $+tes A2"R $itsB% lo )ue
se /ace para e(itar )ue los metadatos sean e-cesi(amente grandes es no incluir en las
re&erencias a ensam$lados e-ternos de la ta$la Assem$l+>e& las cla(es p,$licas de
dic/os ensam$lados% sino slo los T" ,ltimos $its resultantes de aplicar un algoritmo de
dispersin a dic/as cla(es* A este (alor recortado se le llama ?9469 51 6-9A1 <OC-769*
8a+ dos tipos de ensam$lados3 12;9?C-95.; <47A95.; + 12;9?C-95.; 6.?<94375.;*
?os pri(ados se almacenan en el mismo directorio )ue la aplicacin )ue los usa + slo
puede usarlos sta% mientras )ue los compartidos se almacenan en un 696JN 51
12;9?C-95. =-.C9- AGACB + pueden usarlos cual)uiera )ue /a+a sido compilada
re&erencindolos*
?os compartidos /an de ci&rase con >SA +a )ue lo )ue los identi&ica es en el GAC es
su nom$re Asin e-tensinB ms su cla(e p,$lica% lo )ue permite )ue en el GAC puedan
instalarse (arios ensam$lados con el mismo nom$re + di&erentes cla(es p,$licas* Es
decir% es como si la cla(e p,$lica &ormase parte del nom$re del ensam$lado% razn por
la )ue a los ensam$lados as. ci&rados se les llama 12;9?C-95.; 51 2.?C41 @01431* Esta
pol.tica permite resol(er los con&lictos deri(ados de )ue se intente instalar en un mismo
e)uipo (arios ensam$lados compartidos con el mismo nom$re pero procedentes de
distintas empresas% pues stas tendrn distintas cla(es p,$licas*
5am$in para e(itar pro$lemas% en el GAC se pueden mantener m,ltiples (ersiones de
un mismo ensam$lado* As.% si una aplicacin &ue compilada usando una cierta (ersin
de un determinado ensam$lado compartido% cuando se ejecute slo podr /acer uso de
esa (ersin del ensam$lado + no de alguna otra ms moderna )ue se /u$iese instalado
en el GAC* Ce esta &orma se soluciona el pro$lema del 72@7142. 51 -9; DLL comentado
al principio del tema*
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
En realidad es posi$le modi&icar tanto las pol.ticas de $,s)ueda de ensam$lados Apor
ejemplo% para $uscar ensam$lados pri(ados &uera del directorio de la aplicacinB como
la pol.tica de aceptacin de ensam$lados compartidos Apor ejemplo% para )ue se /aga
automticamente uso de las nue(as (ersiones )ue se instalen de C??s compartidasB
inclu+endo en el directorio de instalacin de la aplicacin un &ic/ero de con&iguracin
en &ormato S6? con las nue(as reglas para las mismas* Este &ic/ero /a de llamarse
igual )ue el ejecuta$le de la aplicacin pero /a de tener e-tensin .6@=*
Librer#a de clase base ($CL
?a ?i$rer.a de Clase 0ase A0C?B es una li$rer.a incluida en el .NET Framework
&ormada por cientos de tipos de datos )ue permiten acceder a los ser(icios o&recidos por
el C?> + a las &uncionalidades ms &recuentemente usadas a la /ora de escri$ir
programas* Adems% a partir de estas clases pre&a$ricadas el programador puede crear
nue(as clases )ue mediante /erencia e-tiendan su &uncionalidad + se integren a la
per&eccin con el resto de clases de la 0C?* Por ejemplo% implementando ciertos
inter&aces podemos crear nue(os tipos de colecciones )ue sern tratadas e-actamente
igual )ue cual)uiera de las colecciones incluidas en la 0C?*
Esta li$rer.a est escrita en 6S#?% por lo )ue puede usarse desde cual)uier lenguaje
cu+o compilador genere 6S#?* A tra(s de las clases suministradas en ella es posi$le
desarrollar cual)uier tipo de aplicacin% desde las tradicionales aplicaciones de
(entanas% consola o ser(icio de Hindo=s 45 /asta los no(edosos ser(icios He$ +
pginas ASP*4E5* Es tal la ri)ueza de ser(icios )ue o&rece )ue puede crearse lenguajes
)ue carezcan de li$rer.a de clases propia + slo usen la 0C? Xcomo C#*
Cado la amplitud de la 0C?% /a sido necesario organizar las clases en ella incluida en
1;<967.; 51 2.?C41; )ue agrupen clases con &uncionalidades similares* Por ejemplo%
los espacios de nom$res ms usados son3
E;<967. 51 2.?C41; U37-7595 51 -.; 37<.; 51 593.; /01 6.237121
S+stem 5ipos mu+ &recuentemente usados% como los los tipos
$sicos% ta$las% e-cepciones% &ec/as% n,meros aleatorios%
recolector de $asura% entradaJsalida en consola% etc*
S+stem*Collections Colecciones de datos de uso com,n como pilas% colas%
listas% diccionarios% etc*
S+stem*Cata 6anipulacin de $ases de datos* Worman la denominada
ar)uitectura ADO.NET*
S+stem*#L 6anipulacin de &ic/eros + otros &lujos de datos*
S+stem*4et >ealizacin de comunicaciones en red*
S+stem*>e&lection Acceso a los metadatos )ue acompa1an a los mdulos de
cdigo*
S+stem*>untime*>emoting Acceso a o$jetos remotos*
S+stem*Securit+ Acceso a la pol.tica de seguridad en )ue se $asa el C?>*
S+stem*5/reading 6anipulacin de /ilos*
S+stem*He$*K#*He$Controls Creacin de inter&aces de usuario $asadas en (entanas
para aplicaciones He$*
S+stem*Hin&orms Creacin de inter&aces de usuario $asadas en (entanas
para aplicaciones estndar*
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
S+stem*S6? Acceso a datos en &ormato S6?*
T9C-9 3 : Espacios de nom$res de la 0C? ms usados
Common T%pe "%stem (CT"
El C.??.2 T:<1 S:;31? AC5SB o Sistema de 5ipo Com,n es el conjunto de reglas
)ue /an de seguir las de&iniciones de tipos de datos para )ue el C?> las acepte* Es
decir% aun)ue cada lenguaje gestionado disponga de sus propia sinta-is para de&inir
tipos de datos% en el 6S#? resultante de la compilacin de sus cdigos &uente se /a de
cumplir las reglas del C5S* Algunos ejemplos de estas reglas son3
Cada tipo de dato puede constar de cero o ms miem$ros* Cada uno de estos
miem$ros puede ser un campo% un mtodo una propiedad o un e(ento*
4o puede /a$er /erencia m,ltiple% + todo tipo de dato /a de /eredar directa o
indirectamente de System.Object*
?os modi&icadores de acceso admitidos son3
M.57@7695.4 C857=. 51;51 1- /01 1; 9661;7C-1 1- ?71?C4.
pubIic
Cual)uier cdigo
private
Cdigo del mismo tipo de dato
famiIy
Cdigo del mismo tipo de dato o de /ijos de ste*
assembIy
Cdigo del mismo ensam$lado
famiIy and
assembIy
Cdigo del mismo tipo o de /ijos de ste u$icado en
el mismo ensam$lado
famiIy or
assembIy
Cdigo del mismo tipo o de /ijos de ste% o cdigo
u$icado en el mismo ensam$lado
T9C-9 4 : 6odi&icadores de acceso a miem$ros admitidos por el C5S
Common Language "pecification (CL"
El C.??.2 L92=09=1 S<167@76937.2 AC?SB o Especi&icacin del ?enguaje Com,n es
un conjunto de reglas )ue /an de seguir las de&iniciones de tipos )ue se /agan usando
un determinado lenguaje gestionado si se desea )ue sean accesi$les desde cual)uier otro
lenguaje gestionado* L$(iamente% slo es necesario seguir estas reglas en las
de&iniciones de tipos + miem$ros )ue sean accesi$les e-ternamente% + no la en las de
los pri(ados* Adems% si no importa la interopera$ilidad entre lenguajes tampoco es
necesario seguirlas* A continuacin se listan algunas de reglas signi&icati(as del C?S3
?os tipos de datos $sicos admitidos son booI% char% byte% short% int% Iong% fIoat%
doubIe% string + object 4tese pues )ue no todos los lenguajes tienen por)u
admitir los tipos $sicos enteros sin signo o el tipo decimaI como lo /ace C#*
El lenguaje de programacin C# 5ema 13 #ntroduccin a 6icroso&t*4E5
?as ta$las /an de tener una o ms dimensiones% + el n,mero de dimensiones de
cada ta$la /a de ser &ijo* Adems% /an de inde-arse empezando a contar desde 2*
Se pueden de&inir tipos a$stractos + tipos sellados* ?os tipos sellados no pueden
tener miem$ros a$stractos*
?as e-cepciones /an de deri(ar de System.Exception% los delegados de
System.DeIegate% las enumeraciones de System.Enum% + los tipos por (alor )ue
no sean enumeraciones de System.VaIueType*
?os mtodos de acceso a propiedades en )ue se traduzcan las de&iniciones
getJset de stas /an de llamarse de la &orma get_X + set_X respecti(amente%
donde S es el nom$re de la propiedadU los de acceso a indizadores /an de
traducirse en mtodos get_Item + setItemU + en el caso de los e(entos% sus
de&iniciones addJremo(e /an de traducirse en mtodos de add_X + remove_X*
En las de&iniciones de atri$utos slo pueden usarse enumeraciones o datos de los
siguientes tipos3 System.Type% string% char% booI% byte% short% int% Iong% fIoat%
doubIe + object*
En un mismo m$ito no se pueden de&inir (arios identi&icadores cu+os nom$res
slo di&ieran en la capitalizacin usada* Ce este modo se e(itan pro$lemas al
acceder a ellos usando lenguajes no sensi$les a ma+,sculas*
?as enumeraciones no pueden implementar inter&aces% + todos sus campos /an
de ser estticos + del mismo tipo* El tipo de los campos de una enumeracin slo
puede ser uno de estos cuatro tipos $sicos3 byte% short% int o Iong*
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
Tema 2: Introduccin a C#
&rigen % necesidad de un nuevo lengua'e
C$ Ale.do en ingls NC S/arpO + en espa1ol NC Almo/adillaOB es el nue(o lenguaje de
propsito general dise1ado por 6icroso&t para su plata&orma *4E5* Sus principales
creadores son Scott Hiltamut/ + Anders 8ejls$erg% ste ,ltimo tam$in conocido por
/a$er sido el dise1ador del lenguaje 5ur$o Pascal + la /erramienta >AC Celp/i*
Aun)ue es posi$le escri$ir cdigo para la plata&orma *4E5 en muc/os otros lenguajes%
C# es el ,nico )ue /a sido dise1ado espec.&icamente para ser utilizado en ella% por lo
)ue programarla usando C# es muc/o ms sencillo e intuiti(o )ue /acerlo con
cual)uiera de los otros lenguajes +a )ue C# carece de elementos /eredados innecesarios
en *4E5* Por esta razn% se suele decir )ue C# es el -12=09>1 2937A. 51 .NET
?a sinta-is + estructuracin de C# es mu+ similar a la C''% +a )ue la intencin de
6icroso&t con C# es &acilitar la migracin de cdigos escritos en estos lenguajes a C# +
&acilitar su aprendizaje a los desarrolladores /a$ituados a ellos* Sin em$argo% su
sencillez + el alto ni(el de producti(idad son e)uipara$les a los de ;isual 0asic*
Kn lenguaje )ue /u$iese sido ideal utilizar para estos menesteres es Ja(a% pero de$ido a
pro$lemas con la empresa creadora del mismo XSunX% 6icroso&t /a tenido )ue
desarrollar un nue(o lenguaje )ue a1adiese a las +a pro$adas (irtudes de Ja(a las
modi&icaciones )ue 6icroso&t ten.a pensado a1adirle para mejorarlo a,n ms + /acerlo
un lenguaje orientado al desarrollo de componentes*
En resumen% C# es un lenguaje de programacin )ue toma las mejores caracter.sticas de
lenguajes pree-istentes como ;isual 0asic% Ja(a o C'' + las com$ina en uno solo* El
/ec/o de ser relati(amente reciente no implica )ue sea inmaduro% pues 6icroso&t /a
escrito la ma+or parte de la 0C? usndolo% por lo )ue su compilador es el ms depurado
+ optimizado de los incluidos en el .NET Framework SDK
Caracter#sticas de C(
Con la idea de )ue los programadores ms e-perimentados puedan o$tener una (isin
general del lenguaje% a continuacin se recoge de manera resumida las principales
caracter.sticas de C# Alguna de las caracter.sticas a)u. se1aladas no son e-actamente
propias del lenguaje sino de la plata&orma *4E5 en general* Sin em$argo% tam$in se
comentan a)u. tam$in en tanto )ue tienen repercusin directa en el lenguaje% aun)ue se
indicar e-pl.citamente cules son este tipo de caracter.sticas cada (ez )ue se to)uen3
S1267--1K: C# elimina muc/os elementos )ue otros lenguajes inclu+en + )ue son
innecesarios en *4E5* Por ejemplo3
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
o El cdigo escrito en C# es 903.6.231275.% lo )ue signi&ica )ue no
necesita de &ic/eros adicionales al propio &uente tales como &ic/eros de
ca$ecera o &ic/eros #C?
o El tama1o de los tipos de datos $sicos es &ijo e independiente del
compilador% sistema operati(o o m)uina para )uienes se compile Ano
como en C''B% lo )ue &acilita la porta$ilidad del cdigo*
o 4o se inclu+en elementos poco ,tiles de lenguajes como C'' tales como
macros% /erencia m,ltiple o la necesidad de un operador di&erente del
punto A.B acceder a miem$ros de espacios de nom$res A::B
M.51427595: C# incorpora en el propio lenguaje elementos )ue a lo largo de
los a1os /a ido demostrndose son mu+ ,tiles para el desarrollo de aplicaciones
+ )ue en otros lenguajes como Ja(a o C'' /a+ )ue simular% como un tipo $sico
decimaI )ue permita realizar operaciones de alta precisin con reales de 1R $its
Amu+ ,til en el mundo &inancieroB% la inclusin de una instruccin foreach )ue
permita recorrer colecciones con &acilidad + es amplia$le a tipos de&inidos por el
usuario% la inclusin de un tipo $sico string para representar cadenas o la
distincin de un tipo booI espec.&ico para representar (alores lgicos*
O4712396782 9 .C>13.;: Como todo lenguaje de programacin de propsito
general actual% C# es un lenguaje orientado a o$jetos% aun)ue eso es ms $ien
una caracter.stica del C5S )ue de C#* Kna di&erencia de este en&o)ue orientado a
o$jetos respecto al de otros lenguajes como C'' es )ue el de C# es ms puro en
tanto )ue no admiten ni &unciones ni (aria$les glo$ales sino )ue todo el cdigo +
datos /an de de&inirse dentro de de&iniciones de tipos de datos% lo )ue reduce
pro$lemas por con&lictos de nom$res + &acilita la legi$ilidad del cdigo*
C# soporta todas las caracter.sticas propias del paradigma de programacin
orientada a o$jetos3 1269<;0-96782% J1412679 + <.-7?.4@7;?.*
En lo re&erente a la encapsulacin es importante se1alar )ue aparte de los t.picos
modi&icadores pubIic% private + protected% C# a1ade un cuarto modi&icador
llamado internaI% )ue puede com$inarse con protected e indica )ue al elemento a
cu+a de&inicin precede slo puede accederse desde su mismo ensam$lado*
>especto a la /erencia Xa di&erencia de C'' + al igual )ue Ja(aX C# slo admite
/erencia simple de clases +a )ue la m,ltiple pro(oca ms )ue$raderos de ca$eza
)ue &acilidades + en la ma+or.a de los casos su utilidad puede ser simulada con
&acilidad mediante /erencia m,ltiple de inter&aces* Ce todos modos% esto (uel(e
a ser ms $ien una caracter.stica propia del C5S )ue de C#*
Por otro lado + a di&erencia de Ja(a% en C# se /a optado por /acer )ue todos los
mtodos sean por de&ecto sellados + )ue los rede&ini$les /a+an de marcarse con
el modi&icador virtuaI Acomo en C''B% lo )ue permite e(itar errores deri(ados de
rede&iniciones accidentales* Adems% un e&ecto secundario de esto es )ue las
llamadas a los mtodos sern ms e&icientes por de&ecto al no tenerse )ue $uscar
en la ta$la de &unciones (irtuales la implementacin de los mismos a la )ue se /a
de llamar* Ltro e&ecto secundario es )ue permite )ue las llamadas a los mtodos
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
(irtuales se puedan /acer ms e&icientemente al contri$uir a )ue el tama1o de
dic/a ta$la se reduzca*
O4712396782 9 6.?<.21231;: ?a propia sinta-is de C# inclu+e elementos
propios del dise1o de componentes )ue otros lenguajes tienen )ue simular
mediante construcciones ms o menos complejas* Es decir% la sinta-is de C#
permite de&inir cmodamente <4.<715951; Asimilares a campos de acceso
controladoB% 1A123.; Aasociacin controlada de &unciones de respuesta a
noti&icacionesB o 9347C03.; Ain&ormacin so$re un tipo o sus miem$rosB
G1;3782 903.?M3769 51 ?1?.479: Como +a se coment% todo lenguaje de *4E5
tiene a su disposicin el recolector de $asura del C?>* Esto tiene el e&ecto en el
lenguaje de )ue no es necesario incluir instrucciones de destruccin de o$jetos*
Sin em$argo% dado )ue la destruccin de los o$jetos a tra(s del recolector de
$asura es indeterminista + slo se realiza cuando ste se acti(e Z+a sea por &alta
de memoria% &inalizacin de la aplicacin o solicitud e-pl.cita en el &uenteX% C#
tam$in proporciona un mecanismo de li$eracin de recursos determinista a
tra(s de la instruccin using*
S1=047595 51 37<.;: C# inclu+e mecanismos )ue permiten asegurar )ue los
accesos a tipos de datos siempre se realicen correctamente% lo )ue permite e(ita
)ue se produzcan errores di&.ciles de detectar por acceso a memoria no
perteneciente a ning,n o$jeto + es especialmente necesario en un entorno
gestionado por un recolector de $asura* Para ello se toman medidas del tipo3
o Slo se admiten 6.2A14;7.21; 12341 37<.; 6.?<937C-1;* Esto es% entre un
tipo + antecesores su+os% entre tipos para los )ue e-pl.citamente se /a+a
de&inido un operador de con(ersin% + entre un tipo + un tipo /ijo su+o
del )ue un o$jeto del primero almacenase una re&erencia del segundo
A5.D269;372=B L$(iamente% lo ,ltimo slo puede compro$arlo en tiempo
de ejecucin el C?> + no el compilador% por lo )ue en realidad el C?> +
el compilador cola$oran para asegurar la correccin de las con(ersiones*
o 4o se pueden usar A9479C-1; 2. 727679-7K959;* El compilador da a los
campos un (alor por de&ecto consistente en ponerlos a cero + controla
mediante anlisis del &lujo de control del &uente )ue no se lea ninguna
(aria$le local sin )ue se le /a+a asignado pre(iamente alg,n (alor*
o Se comprue$a )ue todo 9661;. 9 -.; 1-1?123.; 51 029 39C-9 se realice
con .ndices )ue se encuentren dentro del rango de la misma*
o Se puede controlar la <4.5066782 51 51;C.459?7123.; en operaciones
aritmticas% in&ormndose de ello con una e-cepcin cuando ocurra* Sin
em$argo% para conseguirse un ma+or rendimiento en la aritmtica estas
compro$aciones no se /acen por de&ecto al operar con (aria$les sino slo
con constantes Ase pueden detectar en tiempo de compilacinB
o A di&erencia de Ja(a% C# inclu+e 51-1=95.;% )ue son similares a los
punteros a &unciones de C'' pero siguen un en&o)ue orientado a o$jetos%
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
pueden almacenar re&erencias a (arios mtodos simultneamente% + se
comprue$a )ue los mtodos a los )ue apunten tengan parmetros + (alor
de retorno del tipo indicado al de&inirlos*
o Pueden de&inirse mtodos )ue admitan un n,mero inde&inido de
parmetros de un cierto tipo% + a di&erencia lenguajes como CJC''% en
C# siempre se comprue$a )ue los (alores )ue se les pasen en cada
llamada sean de los tipos apropiados*
I2;340667.21; ;1=049;: Para e(itar errores mu+ comunes% en C# se /an
impuesto una serie de restricciones en el uso de las instrucciones de control ms
comunes* Por ejemplo% la guarda de toda condicin /a de ser una e-presin
condicional + no aritmtica% con lo )ue se e(itan errores por con&usin del
operador de igualdad A==B con el de asignacin A=BU + todo caso de un ;D736J /a
de terminar en un break o goto )ue indi)ue cul es la siguiente accin a realizar%
lo )ue e(ita la ejecucin accidental de casos + &acilita su reordenacin*
S7;31?9 51 37<.; 027@7695.: A di&erencia de C''% en C# todos los tipos de datos
)ue se de&inan siempre deri(arn% aun)ue sea de manera impl.cita% de una clase
$ase com,n llamada System.Object% por lo )ue dispondrn de todos los
miem$ros de&inidos en sta clase Aes decir% sern No$jetosOB
A di&erencia de Ja(a% en C# esto tam$in es aplica$le a los tipos de datos $sicos
Adems% para conseguir )ue ello no tenga una repercusin negati(a en su ni(el
de rendimiento% se /a incluido un mecanismo transparente de boxing + unboxing
con el )ue se consigue )ue slo sean tratados como o$jetos cuando la situacin
lo re)uiera% + mientras tanto puede aplicrseles optimizaciones espec.&icas*
El /ec/o de )ue todos los tipos del lenguaje deri(en de una clase com,n &acilita
enormemente el dise1o de colecciones genricas )ue puedan almacenar o$jetos
de cual)uier tipo*
EI312;7C7-7595 51 37<.; CM;76.;: C# permite de&inir% a tra(s de 1;34063049;%
tipos de datos para los )ue se apli)uen las mismas optimizaciones )ue para los
tipos de datos $sicos* Es decir% )ue se puedan almacenar directamente en pila
Aluego su creacin% destruccin + acceso sern ms rpidosB + se asignen por
(alor + no por re&erencia* Para conseguir )ue lo ,ltimo no tenga e&ectos
negati(os al pasar estructuras como parmetros de mtodos% se da la posi$ilidad
de pasar re&erencias a pila a tra(s del modi&icador de parmetro ref*
EI312;7C7-7595 51 .<1495.41;: Para &acilitar la legi$ilidad del cdigo +
conseguir )ue los nue(os tipos de datos $sicos )ue se de&inan a tra(s de las
estructuras estn al mismo ni(el )ue los $sicos prede&inidos en el lenguaje% al
igual )ue C'' + a di&erencia de Ja(a% C# permite rede&inir el signi&icado de la
ma+or.a de los operadores Xincluidos los de con(ersin% tanto para con(ersiones
impl.citas como e-pl.citasX cuando se apli)uen a di&erentes tipos de o$jetos*
?as rede&iniciones de operadores se /acen de manera inteligente% de modo )ue a
partir de una ,nica de&inicin de los operadores ++ + -- el compilador puede
deducir automticamente como ejecutarlos de manera pre&ijas + posti&jaU +
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
de&iniendo operadores simples Acomo +B% el compilador deduce cmo aplicar su
(ersin de asignacin compuesta A'YB Adems% para asegurar la consistencia% el
compilador (igila )ue los operadores con opuesto siempre se rede&inan por
parejas Apor ejemplo% si se rede&ine ==% tam$in /a+ )ue rede&inir !=B
5am$in se da la posi$ilidad% a tra(s del concepto de 7257K95.4% de rede&inir el
signi&icado del operador [] para los tipos de dato de&inidos por el usuario% con lo
)ue se consigue )ue se pueda acceder al mismo como si &uese una ta$la* Esto es
mu+ ,til para tra$ajar con tipos )ue act,en como colecciones de o$jetos*
EI312;7C7-7595 51 ?.57@7695.41;: C# o&rece% a tra(s del concepto de
9347C03.;% la posi$ilidad de a1adir a los metadatos del mdulo resultante de la
compilacin de cual)uier &uente in&ormacin adicional a la generada por el
compilador )ue luego podr ser consultada en tiempo ejecucin a tra(s de la
li$rer.a de re&le-in de *4E5 * Esto% )ue ms $ien es una caracter.stica propia de
la plata&orma *4E5 + no de C#% puede usarse como un mecanismo para de&inir
nue(os modi&icadores*
V14;7.29C-1: C# inclu+e una <.-L3769 51 A14;7.295. )ue permite crear nue(as
(ersiones de tipos sin temor a )ue la introduccin de nue(os miem$ros
pro(o)uen errores di&.ciles de detectar en tipos /ijos pre(iamente desarrollados
+ +a e-tendidos con miem$ros de igual nom$re a los recin introducidos*
Si una clase introduce un nue(o mtodo cu+as rede&iniciones de$an seguir la
regla de llamar a la (ersin de su padre en alg,n punto de su cdigo%
di&.cilmente seguir.an esta regla miem$ros de su misma signatura de&inidos en
clases /ijas pre(iamente a la de&inicin del mismo en la clase padreU o si
introduce un nue(o campo con el mismo nom$re )ue alg,n mtodo de una clase
/ija% la clase /ija dejar de &uncionar* Para e(itar )ue esto ocurra% en C# se
toman dos medidas3
o Se o$liga a )ue toda rede&inicin de$a incluir el modi&icador override%
con lo )ue la (ersin de la clase /ija nunca ser.a considerada como una
rede&inicin de la (ersin de miem$ro en la clase padre +a )ue no
incluir.a override* Para e(itar )ue por accidente un programador inclu+a
este modi&icador% slo se permite incluirlo en miem$ros )ue tengan la
misma signatura )ue miem$ros marcados como rede&ini$les mediante el
modi&icador virtuaI* As. adems se e(ita el error tan &recuente en Ja(a de
creerse /a$er rede&inido un miem$ro% pues si el miem$ro con override no
e-iste en la clase padre se producir un error de compilacin*
o Si no se considera rede&inicin% entonces se considera )ue lo )ue se
desea es ocultar el mtodo de la clase padre% de modo )ue para la clase
/ija sea como si nunca /u$iese e-istido* El compilador a(isar de esta
decisin a tra(s de un mensaje de a(iso )ue puede suprimirse
inclu+endo el modi&icador new en la de&inicin del miem$ro en la clase
/ija para as. indicarle e-pl.citamente la intencin de ocultacin*
E@7671231: En principio% en C# todo el cdigo inclu+e numerosas restricciones
para asegurar su seguridad + no permite el uso de punteros* Sin em$argo% + a
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
di&erencia de Ja(a% en C# es posi$le saltarse dic/as restricciones manipulando
o$jetos a tra(s de punteros* Para ello $asta marcar regiones de cdigo como
inseguras Amodi&icador unsafeB + podrn usarse en ellas punteros de &orma
similar a cmo se /ace en C''% lo )ue puede resultar (ital para situaciones
donde se necesite una e&iciencia + (elocidad procesamiento mu+ grandes*
C.?<937C-1: Para &acilitar la migracin de programadores% C# no slo mantiene
una sinta-is mu+ similar a C% C'' o Ja(a )ue permite incluir directamente en
cdigo escrito en C# &ragmentos de cdigo escrito en estos lenguajes% sino )ue el
C?> tam$in o&rece% a tra(s de los llamados P-93@.4? I2A.6937.2 S14A761;
API2A.E1B% la posi$ilidad de acceder a cdigo nati(o escrito como &unciones
sueltas no orientadas a o$jetos tales como las C??s de la AP# Hin!* 4tese
)ue la capacidad de usar punteros en cdigo inseguro permite )ue se pueda
acceder con &acilidad a este tipo de &unciones% +a )ue stas muc/as (eces
esperan reci$ir o de(uel(en punteros*
5am$in es posi$le acceder desde cdigo escrito en C# a o$jetos CL6* Para
&acilitar esto% el .NET Framework SDK inclu+e una /erramientas llamadas
tlbimp + regasm mediante las )ue es posi$le generar automticamente clases
pro-+ )ue permitan% respecti(amente% usar o$jetos CL6 desde *4E5 como si de
o$jetos *4E5 se tratase + registrar o$jetos *4E5 para su uso desde CL6*
Winalmente% tam$in se da la posi$ilidad de usar controles Acti(eS desde cdigo
*4E5 + (ice(ersa* Para lo primero se utiliza la utilidad aximp% mientras )ue para
lo segundo se usa la +a mencionada regasm*
Escritura de aplicaciones
ApIicacin bsica HoIa Mundo!
0sicamente una aplicacin en C# puede (erse como un conjunto de uno o ms
&ic/eros de cdigo &uente con las instrucciones necesarias para )ue la aplicacin
&uncione como se desea + )ue son pasados al compilador para )ue genere un ejecuta$le*
Cada uno de estos &ic/eros no es ms )ue un &ic/ero de te-to plano escrito usando
caracteres Knicode + siguiendo la sinta-is propia de C#*

Como primer contacto con el lenguaje% nada mejor )ue el t.pico programa de iniciacin
N78ola 6undo9O )ue lo ,nico )ue /ace al ejecutarse es mostrar por pantalla el mensaje
Hola Mundo! Su cdigo es3

1: class HolaMundo
2: {
3: static void Main()
4: {
5: System.Console.WriteLine(Hola Mundo!);
6: }
7: }

?os n,meros de l.nea no &orman parte del cdigo sino )ue slo se inclu+en para &acilitar su posterior
e-plicacin*
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
5odo el cdigo escrito en C# se /a de escri$ir dentro de una de&inicin de clase% + lo
)ue en la l.nea 1: se dice es )ue se (a a de&inir una clase A6-9;;B de nom$re HolaMundo1
cu+a de&inicin estar comprendida entre la lla(e de apertura de la l.nea #: + su
correspondiente lla(e de cierre en la l.nea l.nea !:
Centro de la de&inicin de la clase Al.nea 3:B se de&ine un mtodo de nom$re Main cu+o
cdigo es el indicado entre la lla(e de apertura de la l.nea 4: + su respecti(a lla(e de
cierre Al.nea *:B Kn mtodo no es ms )ue un conjunto de instrucciones a las )ue se les
asocia un nom$re% de modo )ue para posteriormente ejecutarlas $aste re&erenciarlas por
su nom$re en (ez de tener )ue reescri$irlas*
?a part.cula )ue antecede al nom$re del mtodo indica cul es el tipo de (alor )ue se
de(uel(e tras la ejecucin del mtodo% + en este caso es A.75 )ue signi&ica )ue no se
de(uel(e nada* Por su parte% los parntesis )ue se colocado tras el nom$re del mtodo
indican cules son los parmetros ste toma% + como en este caso estn (ac.os ello
signi&ica )ue el mtodo no toma parmetros* ?os parmetros de un mtodo permiten
(ariar el resultado de su ejecucin seg,n los (alores )ue se les d en cada llamada*
?a pala$ra ;39376 )ue antecede a la declaracin del tipo de (alor de(uelto es un
?.57@7695.4 del signi&icado de la declaracin de mtodo )ue indica )ue el mtodo est
asociado a la clase dentro de la )ue se de&ine + no a los o$jetos )ue se creen a partir de
ella* Main() es lo )ue es denomina el <023. 51 1234959 de la aplicacin% )ue no es ms
)ue el mtodo por el )ue comenzar su ejecucin* 4ecesita del modi&icador static para
e(itar )ue para llamarlo /a+a )ue crear alg,n o$jeto de la clase donde se /a+a de&inido*
Winalmente% la l.nea 5: contiene la instruccin con el cdigo a ejecutar% )ue lo )ue se
/ace es solicitar la ejecucin del mtodo B4731L721() de la clase C.2;.-1 de&inida en el
espacio de nom$res System pasndole como parmetro la cadena de te-to con el
contenido Hola Mundo! 4tese )ue las cadenas de te-tos son secuencias de caracteres
delimitadas por comillas do$les aun)ue dic/as comillas no &orman parte de la cadena*
Por su parte% un espacio de nom$res puede considerarse )ue es algo similar para las
clases a lo )ue un directorio es para los &ic/erosU es decir% es una &orma de agruparlas*
El mtodo WriteLine() se usar mu+ a menudo en los pr-imos temas% por lo )ue es
con(eniente se1alar a/ora )ue una &orma de llamarlo )ue se utilizar en repetidas
ocasiones consiste en pasarle un n,mero inde&inido de otros parmetros de cual)uier
tipo e incluir en el primero su$cadenas de la &orma {i}* Con ello se consigue )ue se
muestre por la (entana de consola la cadena )ue se le pasa como primer parmetro pero
sustitu+ndole las su$cadenas {i} por el (alor con(ertido en cadena de te-to del
parmetro )ue ocupe la posicin i' en la llamada a WriteLine()* Por ejemplo% la
siguiente instruccin mostrar.a Tengo 5 aos por pantalla si x (aliese Q3
System.Console.WriteLine(Tengo {! aos"# $%&
Para indicar cmo con(ertir cada o$jeto en un cadena de te-to $asta rede&inir su mtodo
ToString()% aun)ue esto es algo )ue no se (er /asta el Tema 5: Clases*

Antes de seguir es importante resaltar )ue C# es sensi$le a las ma+,sculas% los )ue
signi&ica )ue no da igual la capitalizacin con la )ue se escri$an los identi&icadores* Es
decir% no es lo mismo escri$ir Console )ue COnsole o CONSOLE% + si se /ace de alguna
de las dos ,ltimas &ormas el compilador producir un error de$ido a )ue en el espacio de
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
nom$res System no e-iste ninguna clase con dic/os nom$res* En este sentido% ca$e
se1alar )ue un error com,n entre programadores acostum$rados a Ja(a es llamar al
punto de entrada main en (ez de Main% lo )ue pro(oca un error al compilar ejecuta$les en
tanto )ue el compilador no detectar ninguna de&inicin de punto de entrada*
Puntos de entrada
Va se /a dic/o )ue el <023. 51 1234959 de una aplicacin es un mtodo de nom$re
Main )ue contendr el cdigo por donde se /a de iniciar la ejecucin de la misma* 8asta
a/ora slo se /a (isto una (ersin de Main() )ue no toma parmetros + tiene como tipo
de retorno void% pero en realidad todas sus posi$les (ersiones son3
static void Main()
static int Main()
static int Main(string[] args)
static void Main(string[] args)
Como se (e% /a+ (ersiones de Main() )ue de(uel(en un (alor de tipo int* Kn 723 no es
ms )ue un tipo de datos capaz de almacenar (alor enteros comprendidos entre Z
*1"[
1
"R!*T"R + *1"[
1
"R!*T"[% + el n,mero de(uelto por Main() ser.a interpretado como
cdigo de retorno de la aplicacin* <ste (alor suele usarse para indicar si la aplicacin a
terminado con -ito Ageneralmente (alor 2B o no A(alor seg,n la causa de la terminacin
anormalB% + en el Tema 8: Mtodos se e-plicar como de(ol(er (alores*
5am$in /a+ (ersiones de Main() )ue toman un parmetro donde se almacenar la lista
de argumentos con los )ue se llam a la aplicacin% por lo )ue slo es ,til usar estas
(ersiones del punto de entrada si la aplicacin (a a utilizar dic/os argumentos para algo*
El tipo de este parmetro es string[]% lo )ue signi&ica )ue es una ta$la de cadenas de
te-to Aen el Tema 5: Campos se e-plicar detenidamente )u son las ta$las + las
cadenasB% + su nom$re X)ue es el )ue /a$r de usarse dentro del cdigo de Main() para
/acerle re&erenciaX es args en el ejemplo% aun)ue podr.a drsele cual)uier otro
CompiIacin en Inea de comandos
Kna (ez escrito el cdigo anterior con alg,n editor de te-tos Zcomo el Bloc de Notas
de Hindo=s' + almacenado en &ormato de te-to plano en un &ic/ero HolaMundo.cs
(
%
para compilarlo $asta a$rir una (entana de consola A6SXCLS en Hindo=sB% colocarse
en el directorio donde se encuentre + pasrselo como parmetro al compilador as.3
csc HolaMundo.cs
csc.exe es el compilador de C# incluido en el *4E5 Wrame=orI SCD para Hindo=s
de 6icroso&t% + es posi$le llamarlo desde cual)uier directorio en tanto )ue al instalarlo
se a1ade una re&erencia al mismo en el path* Si utiliza otros compiladores de C# puede
)ue (arie la &orma en )ue se realice la compilacin% por lo )ue lo )ue a)u. se e-plica en
principio slo podr.a ser (lido para el compilador de 6icroso&t para Hindo=s*
!
El nom$re )ue se d al &ic/ero puede ser cual)uiera% aun)ue se recomienda darle la e-tensin .cs +a
)ue es la utilizada por con(enio
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
5ras la compilacin se o$tendr.a un ejecuta$le llamado HolaMundo.e$e cu+a ejecucin
producir.a la siguiente salida por la (entana de consola3
Hola Mundo!
Si la aplicacin )ue se (a+a a compilar no utilizase la (entana de consola para mostrar
su salida sino una inter&az gr&ica de (entanas% entonces /a$r.a )ue compilarla pasando
al compilador la opcin /t con el (alor winexe antes del nom$re del &ic/ero a
compilar* Si no se /iciese as. se a$r.r.a la (entana de consola cada (ez )ue ejecutase la
aplicacin de (entanas% lo )ue suele ser indesea$le en este tipo de aplicaciones* As.%
para compilar )entanas.cs como ejecuta$le de (entanas ser.a con(eniente escri$ir3
csc *t+,ine$e )entanas.cs
4tese )ue aun)ue el nom$re winexe d la sensacin de )ue este (alor para la opcin
/t slo permite generar ejecuta$les de (entanas% en realidad lo )ue permite es generar
ejecuta$les sin (entana de consola asociada* Por tanto% tam$in puede usarse para
generar ejecuta$les )ue no tengan ninguna inter&az asociada% ni de consola ni gr&ica*

Si en lugar de un ejecuta$le X+a sea de consola o de (entanasX se desea o$tener una
li$rer.a% entonces al compilar /a+ )ue pasar al compilador la opcin /t con el (alor
library* Por ejemplo% siguiendo con el ejemplo inicial /a$r.a )ue escri$ir3
csc *t+li-rary HolaMundo.cs
En este caso se generar.a un &ic/ero HolaMundo.dll cu+os tipos de datos podr.an
utilizarse desde otros &uentes pasando al compilador una re&erencia a los mismos
mediante la opcin /r* Por ejemplo% para compilar como ejecuta$le un &uente ..cs )ue
use la clase HolaMundo de la li$rer.a HolaMundo.dll se escri$ir.a3
csc *r+HolaMundo.dll ..cs
En general /r permite re&erenciar a tipos de&inidos en cual)uier ensam$lado% por lo )ue
el (alor )ue se le indi)ue tam$in puede ser el nom$re de un ejecuta$le* Adems% en
cada compilacin es posi$le re&erenciar m,ltiples ensam$lados +a sea inclui+endo la
opcin /r una (ez por cada uno o inclui+endo m,ltiples re&erencias en una ,nica
opcin /r usando comas o puntos + comas como separadores* Por ejemplo% las
siguientes tres llamadas al compilador son e)ui(alentes3
csc *r+HolaMundo.dll&/tro.dll&/troM0s.e$e ..cs
csc *r+HolaMundo.dll#/tro.dll#/troM0s.e$e ..cs
csc *t+HolaMundo.dll *r+/tro.dll *r+/troM0s.e$e ..cs
8a+ )ue se1alar )ue aun)ue no se indi)ue nada% en toda compilacin siempre se
re&erencia por de&ecto a la li$rer.a mscorlib.dll de la 0C?% )ue inclu+e los tipos de
uso ms &recuente* Si se usan tipos de la 0C? no incluidos en ella /a$r )ue incluir al
compilar re&erencias a las li$rer.as donde estn de&inidos Aen la documentacin del SCD
so$re cada tipo de la 0C? puede encontrar in&ormacin so$re donde se de&iniB
5anto las li$rer.as como los ejecuta$les son ensam$lados* Para generar un mdulo de
cdigo )ue no &orme parte de ning,n ensam$lado sino )ue contenga de&iniciones de
tipos )ue puedan a1adirse a ensam$lados )ue se compilen posteriormente% el (alor )ue
/a de darse al compilar a la opcin /t es module* Por ejemplo3
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
csc *t+module HolaMundo.cs
Con la instruccin anterior se generar.a un mdulo llamado HolaMundo.netmodule
)ue podr.a ser a1adido a compilaciones de ensam$lados inclu+ndolo como (alor de la
opcin /addmodule* Por ejemplo% para a1adir el mdulo anterior a la compilacin del
&uente li$rer.a Li-.cs como li$rer.a se escri$ir.a3
csc *t+li-rary *addmodule+HolaMundo.netmodule Li-.cs
Aun)ue /asta a/ora todas las compilaciones de ejemplo se /an realizado utilizando un
,nico &ic/ero de cdigo &uente% en realidad nada impide )ue se puedan utilizar ms* Por
ejemplo% para compilar los &ic/eros ..cs + 1.cs en una li$rer.a ..dll se ejecutar.a3
csc *t+li-rary ..cs 1.cs
4tese )ue el nom$re )ue por de&ecto se d al ejecuta$le generado siempre es igual al
del primer &uente especi&icado pero con la e-tensin propia del tipo de compilacin
realizada A.exe para ejecuta$les% .dll para li$rer.as + .netmodule para mdulosB Sin
em$argo% puede especi&icrse como (alor en la opcin /out del compilador cual)uier
otro tal + como muestra el siguiente ejemplo )ue compila el &ic/ero ..cs como una
li$rer.a de nom$re Li-.e$e3
csc *t+li-rary *out+Li-.e$e ..cs
;ase )ue aun)ue se /a+a dado un nom$re terminado en .exe al &ic/ero resultante%
ste sigue siendo una li$rer.a + no un ejecuta$le e intentar ejecutarlo producir.a un
mensaje de error* L$(iamente no tiene muc/o sentido darle esa e-tensin% + slo se le
/a dado en este ejemplo para demostrar )ue% aun)ue recomenda$le% la e-tensin del
&ic/ero no tiene por)u corresponderse realmente con el tipo de &ic/ero del )ue se trate*
A la /ora de especi&icar &ic/eros a compilar tam$in es pueden utilizar los caracteres de
comod.n t.picos del sistema operati(o* Por ejemplo% para compilar todos los &ic/eros
con e-tensin .cs del directorio actual en una li$rer.a llamada )arios.dll se /ar.a3
csc *t+li-rary *out+2arios.dll 3.cs
Con lo )ue /a+ )ue tener cuidado% + en especial al compilar (arios &uentes% es con )ue
no se compilen a la (ez ms de un tipo de dato con punto de entrada% pues entonces el
compilador no sa$r.a cul usar como inicio de la aplicacin* Para orientarlo% puede
especi&icarse como (alor de la opcin /main el nom$re del tipo )ue contenga el Main()
/a usar como punto de entrada* As.% para compilar los &ic/eros ..cs + 1.cs en un
ejecuta$le cu+o punto de entrada sea el de&inido en el tipo Principal% /a$r.a )ue escri$ir3
csc *main+4rinci5al ..cs 1.cs
L$(iamente% para )ue esto &uncione ..cs o 1.cs tiene )ue contener alguna de&inicin
de alg,n tipo llamado Principal con un ,nico mtodo (lido como punto de entrada*
Ao$(iamente si contiene (arias se (ol(er.a a tener el pro$lema de no sa$er cul usarB
CompiIacin con VisuaI Studio.NET
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
Para compilar una aplicacin en ;isual Studio*4E5 primero /a+ )ue incluirla dentro de
alg,n pro+ecto* Para ello $asta pulsar el $otn New Project en la pgina de inicio )ue
se muestra nada ms arrancar dic/a /erramienta% tras lo )ue se o$tendr una pantalla
con el aspecto mostrado en la #lustracin 1*
En el recuadro de la (entana mostrada eti)uetado como Project Types se /a de
seleccionar el tipo de pro+ecto a crear* L$(iamente% si se (a a tra$ajar en C# la opcin
)ue /a$r )ue escoger en la misma ser siempre )isual C6 4ro7ects*
En el recuadro T1?<-931; se /a de seleccionar la plantilla correspondiente al su$tipo
de pro+ecto dentro del tipo indicado en Project Types )ue se (a a realizar* Para
realizar un ejecuta$le de consola% como es nuestro caso% /a+ )ue seleccionar el icono
eti)uetado como Console .55lication* Si se )uisiese realizar una li$rer.a /a$r.a )ue
seleccionar Class Li-rary% + si se )uisies realizar un ejecuta$le de (entanas /a$r.a
)ue seleccionar Windo,s .55lication* 4tese )ue no se o&rece ninguna plantilla para
realizar mdulos% lo )ue se de$e a )ue desde ;isual Studio*4E5 no pueden crearse*
Por ,ltimo% en el recuadro de te-to N9?1 se /a de escri$ir el nom$re a dar al pro+ecto +
en L.6937.2 el del directorio $ase asociado al mismo* 4tese )ue $ajo de L.6937.2
aparecer un mensaje in&ormando so$re cual ser el directorio donde &inalmente se
almacenarn los arc/i(os del pro+ecto% )ue ser el resultante de concatenar la ruta
especi&icada para el directorio $ase + el nom$re del pro+ecto*
I-0;3496782 1: ;entana de creacin de nue(o pro+ecto en ;isual Studio*4E5
Kna (ez con&iguradas todas estas opciones% al pulsar $otn OF ;isual Studio crear
toda la in&raestructura adecuada para empezar a tra$ajar cmodamente en el pro+ecto*
Como puede apreciarse en la #lustracin % esta in&raestructura consistir en la
generacin de un &uente )ue ser(ir de plantilla para la realizacin de pro+ectos del tipo
elegido Aen nuestro caso% aplicaciones de consola en C#B3
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
I-0;3496782 #: Plantilla para aplicaciones de consola generada por ;isual Studio*4E5
A partir de esta plantilla% escri$ir el cdigo de la aplicacin de ejemplo es tan sencillo
con simplemente teclear System.Console.WriteLine(Hola Mundo!) dentro de la de&inicin
del mtodo Main() creada por ;isual Studio*4E5* Claro est% otra posi$ilidad es $orrar
toda la plantilla + sustituirla por el cdigo para HolaMundo mostrado anteriormente*
Sea /aga como se /aga% para compilar + ejecutar tras ello la aplicacin slo /a+ )ue
pulsar CTRL!" o seleccionar #ebug $tart %ithout #ebugging en el men,
principal de ;isual Studio*4E5* Para slo compilar el pro+ecto% entonces /a+ )ue
seleccionar Build Rebuild &ll* Ce todas &ormas% en am$os casos el ejecuta$le
generado se almacenar en el su$directorio 1in89e-ug del directorio del pro+ecto*
En el e-tremo derec/o de la (entana principal de ;isual Studio*4E5 puede encontrar el
denominado $olution 'xplorer Asi no lo encuentra% seleccione (iew $olution
EI<-.414B% )ue es una /erramienta )ue permite consultar cules son los arc/i(os )ue
&orman el pro+ecto* Si selecciona en l el icono correspondiente al pro+ecto en )ue
estamos tra$ajando + pulsa (iew Property Pages o$tendr una /oja de
propiedades del pro+ecto con el aspecto mostrado en la #lustracin !3
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
I-0;3496782 3: 8oja de propiedades del pro+ecto en ;isual Studio*4E5
Esta (entana permite con&igurar de manera (isual la ma+or.a de opciones con las )ue se
llamar al compilador en l.nea de comandos* Por ejemplo% para cam$iar el nom$re del
&ic/ero de salida Aopcin /outB se indica su nue(o nom$re en el cuadro de te-to Common
Properties )eneral &ssembly NameU para cam$iar el tipo de pro+ecto a
generar Aopcin /tB se utiliza Common Properties )eneral *utput Type
Acomo (er si intenta cam$iarlo% no es posi$le generar mdulos desde ;isual
Studio*4E5BU + el tipo )ue contiene el punto de entrada a utilizar Aopcin /mainB se
indica en Common Properties )eneral $tartup *bject
Winalemente% para a1adir al pro+ecto re&erencias a ensam$lados e-ternos Aopcin /rB
$asta seleccionar Project &dd Re+erence en el men, principal de ;S*4E5*
El lenguaje de programacin C# 5ema 3 #ntroduccin a C#
El lenguaje de programacin C# 5ema !3 El Preprocesador
TEMA 3: EL PREPROCESADOR
Concepto de preprocesador
El <41<4.61;95. es un paso pre(io
"
a la compilacin mediante el )ue es posi$le
controlar la &orma en )ue se realizar sta* El <41<4.61;95.4 es el mdulo au-iliar )ue
utiliza el compilador para realizar estas tareas% + lo )ue &inalmente el compilador
compila es el resultado de aplicar el preprocesador al &ic/ero de te-to &uente% resultado
)ue tam$in es un &ic/ero de te-to* 4tese pues% )ue mientras )ue el compilador /ace
una traduccin de te-to a $inario% lo )ue el preprocesador /ace es una traduccin de
te-to a te-to*
A)uellos )ue tengan e-periencia en el uso del preprocesador en lenguajes como C'' +
conozcan los pro$lemas )ue implica el uso del mismo pueden respirar tran)uilos% +a )ue
en C# se /an eliminado la ma+or.a de caracter.sticas de ste )ue pro(oca$an errores
di&.ciles de detectar Amacros% directi(as de inclusin% etc*B + prcticamente slo se usa
para permitir realizar compilaciones condicionales de cdigo*
)irectivas de preprocesado
Concepto de directiva. Sintaxis
El preprocesador no interpreta de ninguna manera el cdigo &uente del &ic/ero% sino )ue
slo interpreta de dic/o &ic/ero lo )ue se denominan 5741637A9; 51 <41<4.61;95.* Estas
directi(as son l.neas de te-to del &ic/ero &uente )ue se caracterizan por)ue en ellas el
primer carcter no $lanco )ue aparece es una almo/adilla Acarcter #B Por ejemplo3
#define TEST
#error Ha habido un error fatal
4o se preocupe a/ora si no entiendo el signi&icado de estas directi(as% +a )ue se
e-plicarn ms adelante* ?o ,nico de$e sa$er es )ue el nom$re )ue se indica tras el
s.m$olo # es el nom$re de la directi(a% + el te-to )ue se inclu+e tras l Ano todas las
directi(as tienen por)u incluirloB es el (alor )ue se le da* Por tanto% la sinta-is de una
directi(a es3
#<nombreDirectiva> <valorDirectiva>
Es posi$le incluir comentarios en la misma l.nea en )ue se declara una directi(a% aun)ue
estos slo pueden ser comentarios de una l.nea )ue empiecen con // Por ejemplo% el
siguiente comentario es (lido3
#define TEST // Ha habido algn error durante el preprocesado
"
En realidad% en C# se realiza a la (ez )ue el anlisis l-ico del cdigo &uenteU pero para simpli&icar la
e-plicacin consideraremos )ue se realiza antes )ue ste% en una etapa pre(ia independiente*
El lenguaje de programacin C# 5ema !3 El Preprocesador
Pero este otro no% pues aun)ue ocupa una l.nea tiene la sinta-is de los comentarios )ue
pueden ocupar (arias l.neas3
#define TEST /* Ha habido algn error durante el preprocesado */
Definicin de identificadores de preprocesado
Como +a se /a comentado% la principal utilidad del preprocesador en C# es la de
permitir determinar cules regiones de cdigo de un &ic/ero &uente se /an de compilar*
Para ello% lo )ue se /ace es encerrar las secciones de cdigo opcionales dentro de
directi(as de compilacin condicional% de modo )ue slo se compilarn si determinados
identi&icadores de preprocesado estn de&inidos* Para de&inir un identi&icador de este
tipo la directi(a )ue se usa sigue esta sinta-is3
#define <nombredentificador>
Esta directi(a de&ine un identi&icador de preprocesado :nom-re;denti<icador=*
Aun)ue ms adelante estudiaremos detalladamente cules son los nom$res (lidos
como identi&icadores en C#% por a/ora podemos considerar )ue son (lidos a)uellos
&ormados por uno o ms caracteres al&anumricos tales )ue no sean ni true ni faIse + no
empiecen con un numero* Por ejemplo% para de&inir un identi&icador de preprocesado de
nom$re 4>?@1. se /ar.a3
#define PRUEBA
Por con(enio se da a estos identi&icadores nom$res en los )ue todas las letras se
escri$en en ma+,sculas% como en el ejemplo anterior* Aun)ue es slo un con(enio +
nada o$liga a usarlo% sta ser la nomenclatura )ue usaremos en el presente documento%
)ue es la usada por 6icroso&t en sus cdigos de ejemplo* Con(iene &amiliarizarse con
ella por)ue por un lado /a+ muc/o cdigo escrito )ue la usa + por otro usarla &acilita la
lectura de nuestro cdigo a los dems al ser la notacin )ue esperarn encontrar*
Es importante se1alar )ue cual)uier de&inicin de identi&icador /a de preceder a
cual)uier aparicin de cdigo en el &ic/ero &uente* Por ejemplo% el siguiente cdigo no
es (lido% pues antes del #define se /a incluido cdigo &uente Ael class .B3
class A
#define PRUEBA
{}
Sin em$argo% aun)ue no pueda /a$er cdigo antes de un 6de<ine% s. )ue es posi$le
incluir antes de l otras directi(as de preprocesado con total li$ertad*
E-iste una &orma alternati(a de de&inir un identi&icador de preprocesado + )ue adems
permite )ue dic/a de&inicin slo sea (lida en una compilacin en concreto* Esta &orma
consiste en pasarle al compilador en su llamada la opcin *d+:nom-re;denti<icador=
A&orma a$re(iada de *de<ine+:nom-re;denti<icador=B% caso en )ue durante la
compilacin se considerar )ue al principio de todos los &ic/eros &uente a compilar se
encuentra de&inido el identi&icador indicado* ?as siguientes tres &ormas de llamar al
El lenguaje de programacin C# 5ema !3 El Preprocesador
compilador son e)ui(alentes + de&inen identi&icadores de preprocesado de nom$res
4>?@1. + T>.A. durante la compilacin de un &ic/ero &uente de nom$re e7em5lo.cs3
csc *d+4>?@1. *d+T>.A. e7em5lo.cs
csc *d+4>?@1.#T>.A. e7em5lo.cs
csc *d+4>?@1.&T>.A. e7em5lo.cs
4tese en el ejemplo )ue si )ueremos de&inir ms de un identi&icador usando esta
tcnica tenemos dos alternati(as3 incluir (arias opciones /d en la llamada al compilador
o de&inir (arios de estos identi&icadores en una misma opcin /d separndolos mediante
caracteres de coma A,B o punto + coma A;B
Si se tra$aja con ;isual Studio*4E5 en lugar de directamente con el compilador en
l.nea de comandos% entonces puede conseguir mismo e&ecto a tra(s de (iew
Property Pages Con+iguration *ptions Build Conditional
Compilation Constants% donde nue(amente usado el punto + coma A;B o la coma A,B
como separadores% puede de&inir (arias constantes* Para )ue todo &uncione $ien% antes
de seleccionar (iew /a de seleccionar en el SoIution ExpIorer Ase a$re con (iew
$olution 'xplorerB el pro+ecto al )ue aplicar la de&inicin de las constantes*
Winalmente% respecto al uso de #define slo )ueda comentar )ue es posi$le de&inir (arias
(eces una misma directi(a sin )ue ello pro(o)ue ning,n tipo de error en el compilador%
lo )ue permite )ue podamos pasar tantos (alores a la opcin /d del compilador como
)ueramos sin temor a )ue entren en con&licto con identi&icadores de preprocesado +a
incluidos en los &uentes a compilar*
EIiminacin de identificadores de preprocesado
Cel mismo modo )ue es posi$le de&inir identi&icadores de preprocesado% tam$in es
posi$le eliminar de&iniciones de este tipo de identi&icadores pre(iamente realizadas*
Para ello la directi(a )ue se usa tiene la siguiente sinta-is3
#undef <nombredentificador>
En caso de )ue se intente eliminar con esta directi(a un identi&icador )ue no /a+a sido
de&inido o cu+a de&inicin +a /a+a sido eliminada no se producir error alguna% sino )ue
simplemente la directi(a de eliminacin ser ignorada* El siguiente ejemplo muestra un
ejemplo de esto en el )ue el segundo #undef es ignorado3
#define VERSON1
#undef VERSON1
#undef VERSON1
Al igual )ue ocurr.a con las directi(as #define% no se puede incluir cdigo &uente antes
de las directi(as #undef% sino )ue% todo lo ms% lo ,nico )ue podr.an incluirse antes )ue
ellas ser.an directi(as de preprocesado*
CompiIacin condicionaI
El lenguaje de programacin C# 5ema !3 El Preprocesador
Como se /a repetido (arias (eces a lo largo del tema% la principal utilidad del
preprocesador en C# es la de permitir la compilacin de cdigo condicional% lo )ue
consiste en slo permitir )ue se compile determinadas regiones de cdigo &uente si las
(aria$les de preprocesado de&inidas cumplen alguna condicin determinada* Para
conseguir esto se utiliza el siguiente juego de directi(as3
#if <condicin1>
<cdigo1>
(elif <condicin2>
<cdigo2>
...
(else
<cdigoElse>
#endif
El signi&icado de una estructura como esta es )ue si se cumple :condiciBnC= entonces
se pasa al compilador el :cBdigoC=% si no ocurre esto pero se cumple :condiciBnD=
entonces lo )ue se pasar.a al compilador ser.a :cBdigoD=% + as. continuamente /asta
)ue se llegue a una rama #eIif cu+a condicin se cumpla* Si no se cumple ninguna pero
/a+ una rama #eIse se pasar al compilador el <cdigoElse>% pero si dic/a rama no
e-istiese entonces no se le pasar.a cdigo alguno + se continuar.a preprocesando el
cdigo siguiente al #endif en el &uente original*
Aun)ue las ramas #eIse + #endif son opcionales% /a+ )ue tener cuidado + no mezclarlas
+a )ue la rama #eIse slo puede aparecer como ,ltima rama del $lo)ue #if***#endif*
Es posi$le anidar (arias estructuras #if...#endif% como muestra el siguiente cdigo3

#define PRUEBA
using System;
class A
{
public static void Main()
{
#if PRUEBA
Console.Write (Esto es una prueba);
#if TRAZA
Console.Write( con traza);
#elif !TRAZA
Console.Write( sin traza);
#endif
#endif
}
}
Como se (e en el ejemplo% las condiciones especi&icadas son nom$res de identi&icadores
de preprocesado% considerndose )ue cada condicin slo se cumple si el identi&icador
)ue se indica en ella est de&inido* L lo )ue es lo mismo3 un identi&icador de
preprocesado (ale cierto Atrue en C#B si est de&inido + &also A+alse en C#B si no*

El s.m$olo ! incluido en junto al (alor de la directi(a #eIif es el s.m$olo de NnoO lgico%
+ el #eIif en el )ue se usa lo )ue nos permite es indicar )ue en caso de )ue no se
El lenguaje de programacin C# 5ema !3 El Preprocesador
encuentre de&inido el identi&icador de preprocesado T>.A. se /an de pasar al compilador
las instrucciones a continuacin indicadas Ao sea% el Console.Write(sin traEa"%&B
El cdigo &uente )ue el preprocesador pasar al compilador en caso de )ue compilemos
sin especi&icar ninguna opcin /d en la llamada al compilador ser3

using System;
class A
{
public static void Main()
{
Console.Write(Esto es una prueba);
Console.Write( sin traza);
}
}
4tese como en el cdigo )ue se pasa al compilador +a no aparece ninguna directi(a de
preprocesado% pues lo )ue el preprocesador le pasa es el cdigo resultante de aplicar al
original las directi(as de preprocesado )ue contu(iese*
Asimismo% si compilsemos el cdigo &uente original llamando al compilador con
*d+T>.A.% lo )ue el preprocesador pasar.a al compilador ser.a3
using System;
class A
{
public static void Main()
{
Console.Write (Esto es una prueba);
Console.Write( sin traza);
}
}
8asta a/ora solo /emos (isto )ue la condicin de un #if o #eIif puede ser un
identi&icador de preprocesado% + )ue este (aldr true o <alse seg,n est o no de&inido*
Pues $ien% estos no son el ,nico tipo de condiciones (lidas en C#% sino )ue tam$in es
posi$le incluir condiciones )ue contengan e-presiones lgicas &ormadas por
identi&icadores de preprocesado% operadores lgicos A! para NnotO% && para NandO + ||
para NorOB% operadores relacionales de igualdad A==B + desigualdad A!=B% parntesis A( + )B
+ los identi&icadores especiales true + faIse* Por ejemplo3
#if TRAZA // Se cumple si TRAZA esta definido.
#if TRAZA==true // dem al ejemplo anterior aunque con una sintaxis menos cmoda
#if !TRAZA // Slo se cumple si TRAZA no est definido.
#if TRAZA==false // dema al ejemplo anterior aunque con una sintaxis menos cmoda
#if TRAZA == PRUEBA // Solo se cumple si tanto TRAZA como PRUEBA estn
// definidos o si no ninguno lo est.
#if TRAZA != PRUEBA // Solo se cumple si TRAZA esta definido y PRUEBA no o
// viceversa
#if TRAZA && PRUEBA // Solo se cumple si estn definidos TRAZA y PRUEBA.
#if TRAZA || PRUEBA // Solo se cumple si estn definidos TRAZA o PRUEBA.
#if false // Nunca se cumple (por lo que es absurdo ponerlo)
#if true // Siempre se cumple (por lo que es absurdo ponerlo)
El lenguaje de programacin C# 5ema !3 El Preprocesador
Es &cil (er )ue la causa de la restriccin antes comentada de )ue no es (lido dar un
como nom$re true o faIse a un identi&icador de preprocesado se de$e al signi&icado
especial )ue estos tienen en las condiciones de los #if + #eIif
Generacin de avisos y errores
El preprocesador de C# tam$in o&rece directi(as )ue permiten generar a(isos + errores
durante el proceso de preprocesado en caso de )ue ser interpretadas por el
preprocesador* Estas directi(as tienen la siguiente sinta-is3
#warning <mensajeAviso>
#error <mensajeError>
?a directi(a #warning lo )ue /ace al ser procesada es pro(ocar )ue el compilador
produzca un mensaje de a(iso )ue siga el &ormato estndar usado por ste para ello +
cu+o te-to descripti(o tenga el contenido indicado en :mensa7e.2iso=U + #error /ace lo
mismo pero pro(ocando un mensaje de error en (ez de uno de a(iso*
Ksando directi(as de compilacin condicional se puede controlar cuando se /an de
producir estos mensajes% cuando se /an de procesar estas directi(as* Ce /ec/o la
principal utilidad de estas directi(as es permitir controlar errores de asignacin de
(alores a los di&erentes identi&icadores de preprocesado de un cdigo% + un ejemplo de
ello es el siguiente3
#warning Cdigo aun no revisado
#define PRUEBA
#if PRUEBA && FNAL
#error Un cdigo no puede ser simultneamente de prueba y versin final
#endif
class A
{}
En este cdigo siempre se producir el mensaje de a(iso% pero el #if indica )ue slo se
producir el mensaje de error si se /an de&inido simultneamente los identi&icadores de
preprocesado PRUEBA + FNAL
Como puede deducirse del ejemplo% el preprocesador de C# considera )ue los mensajes
asociados a directi(as #warning o #error son todo el te-to )ue se encuentra tras el
nom$re de dic/as directi(as + /asta el &inal de la l.nea donde stas aparecen* Por tanto%
todo comentario )ue se inclu+a en una l.nea de este tipo ser considerado como parte
del mensaje a mostrar% + no como comentario como tal* Por ejemplo% ante la directi(a3
#error La compilacin ha fallado // Error
?o )ue se mostrar en pantalla es un mensaje de la siguiente &orma3

Fichero.cs(3,5): error CS1029: La compilacin ha fallado // Error
El lenguaje de programacin C# 5ema !3 El Preprocesador
Cambios en Ia numeracin de Ineas
Por de&ecto el compilador enumera las l.neas de cada &ic/ero &uente seg,n el orden
normal en )ue estas aparecen en el mismo% + este orden es el )ue sigue a la /ora de
in&ormar de errores o de a(isos durante la compilacin* Sin em$argo% /a+ situaciones en
las )ue interesa cam$iar esta numeracin% + para ello se o&rece una directi(a con la
siguiente sinta-is3
#Iine <nmero> *<nombreFichero>+
Esta directi(a indica al preprocesador )ue /a de considerar )ue la siguiente l.nea del
&ic/ero &uente en )ue aparece es la l.nea cu+o n,mero se le indica% independientemente
del (alor )ue tu(iese seg,n la numeracin usada en ese momento* El (alor indicado en
<nombreFichero> es opcional% + en caso de aparecer indica el nom$re )ue se /a de
considerar )ue tiene el &ic/ero a la /ora de dar mensajes de error* Kn ejemplo3
#line 127 csmace.cs
Este uso de #Iine indica )ue el compilador /a de considerar )ue la l.nea siguiente es la
l.nea 1[ del &ic/ero csmace.cs* A partir de ella se seguir usando el sistema de
numeracin normal Ala siguiente a esa ser la 1R de csmace.cs% la pr-ima la CDF%
etc*B sal(o )ue ms adelante se (uel(a a cam$iar la numeracin con otra directi(a #Iine*
Aun)ue en principio puede parecer )ue esta directi(a es de escasa utilidad% lo cierto es
)ue suele (enir $astante $ien para la escritura de compiladores + otras /erramientas )ue
generen cdigo en C# a partir de cdigo escrito en otros lenguajes*
Marcacin de regiones de cdigo
Es posi$le marcar regiones de cdigo + asociarles un nom$re usando el juego de
directi(as #region + #endregion* Estas directi(as se usan as.3
#region <nombreRegin>
<cdigo>
#endregion
?a utilidad )ue se d a estas marcaciones depende de cada /erramienta% pero en el
momento de escri$ir estas l.neas la ,nica /erramienta disponi$le )ue /ac.a uso de ellas
era ;isual Studio*4E5% donde se usa para marcar cdigo de modo )ue desde la (entana
de cdigo podamos e-pandirlo + contraerlo con una ,nica pulsacin de ratn* En
concreto% en la (entana de cdigo de ;isual Studio aparecer un s.m$olo [-] junto a las
regiones de cdigo as. marcadas de manera )ue pulsando so$re l todo el cdigo
contenido en la regin se comprimir + ser sustituido por el nom$re dado en
:nom-re>egiBn=* 5ras ello% el \X] se con(ertir en un \'] + si (ol(emos a pulsarlo el
cdigo contra.do se e-pandir + recuperar su aspecto original* A continuacin se
muestra un ejemplo de cada caso3
El lenguaje de programacin C# 5ema !3 El Preprocesador
I-0;3496782 4: Cdigo de regin e-pandido
I-0;3496782 5: Cdigo de regin contra.do
8a+ )ue tener cuidado al anidar regiones con directi(as de compilacin condicional% +a
)ue todo $lo)ue #if...#endif )ue comience dentro de una regin /a de terminar tam$in
dentro de ella* Por tanto% el siguiente uso de la directi(a #region no es (alido +a )ue
>egiBn@rrBnea termina estando el $lo)ue #if...#endif a$ierto3

#region ReginErrnea
#if A
#endregion
#endif
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
TEMA 4: ASPECTOS LXICOS
Comentarios
Kn 6.?123947. es te-to )ue incluido en el cdigo &uente de un programa con la idea de
&acilitar su legi$ilidad a los programadores + cu+o contenido es% por de&ecto%
completamente ignorado por el compilador* Suelen usarse para incluir in&ormacin
so$re el autor del cdigo% para aclarar el signi&icado o el por)u de determinadas
secciones de cdigo% para descri$ir el &uncionamiento de los mtodos de las clases% etc*
En C# /a+ dos &ormas de escri$ir comentarios* ?a primera consiste en encerrar todo el
te-to )ue se desee comentar entre caracteres /* + */ siguiendo la siguiente sinta-is3
/*<texto>*/
Estos comentarios pueden a$arcar tantas l.neas como sea necesario* Po ejemplo3

/* Esto es un comentario
que ejemplifica cmo se escribe comentarios que ocupen varias lneas */

A/ora $ien% /a+ )ue tener cuidado con el /ec/o de )ue no es posi$le anidar comentarios
de este tipo* Es decir% no (ale escri$ir comentarios como el siguiente3
/* Comentario contenedor /* Comentario contenido */ */
Esto se de$e a )ue como el compilador ignora todo el te-to contenido en un comentario
+ slo $usca la secuencia */ )ue marca su &inal% ignorar el segundo /* + cuando llegue al
primer */ considerar )ue /a aca$ado el comentario a$ierto con el primer /* Ano el
a$ierto con el segundoB + pasar a $uscar cdigo* Como el */ slo lo admite si /a
detectado antes alg,n comentario a$ierto + a,n no cerrado Ano mientras $usca cdigoB%
cuando llegue al segundo */ considerar )ue /a /a$ido un error +a )ue encontrar el ,/
donde espera$a encontrar cdigo
Cado )ue muc/as (eces los comentarios )ue se escri$en son mu+ cortos + no suelen
ocupar ms de una l.nea% C# o&rece una sinta-is alternati(a ms compacta para la
escritura este tipo de comentarios en las )ue se considera como indicador del comienzo
del comentario la pareja de caracteres // + como indicador de su &inal el &in de l.nea* Por
tanto% la sinta-is )ue siguen estos comentarios es3
// <texto>
V un ejemplo de su uso es3

// Este comentario ejemplifica como escribir comentarios abreviados de una sola lnea
Estos comentarios de una sola l.nea s. )ue pueden anidarse sin ning,n pro$lema* Por
ejemplo% el siguiente comentario es per&ectamente (lido3

// Comentario contenedor // Comentario contenido
El lenguaje de programacin C# 5ema "3 Aspectos l-icos

!dentificadores
Al igual )ue en cual)uier lenguaje de programacin% en C# un 751237@7695.4 no es ms
)ue% como su propio nom$re indica% un nom$re con el )ue identi&icaremos alg,n
elemento de nuestro cdigo% +a sea una clase% una (aria$le% un mtodo% etc*
5.picamente el nom$re de un identi&icador ser una secuencia de cual)uier n,mero de
caracteres al&anumricos Zincluidas (ocales acentuadas + e1esX tales )ue el primero de
ellos no sea un n,mero* Por ejemplo% identi&icadores (lidos ser.an3 Arriba% caa% C3P0%
% etcU pero no lo ser.an 3com% 127% etc*
Sin em$argo% + aun)ue por moti(os de legi$ilidad del cdigo no se recomienda% C#
tam$in permite incluir dentro de un identi&icador caracteres especiales imprimi$les
tales como s.m$olos de diresis% su$ra+ados% etc* siempre + cuando estos no tengan un
signi&icado especial dentro del lenguaje* Por ejemplo% tam$in ser.an identi&icadores
(lidos% _barco_% ck + ABU pero no C# A# indica inicio de directi(a de preprocesadoB o a!
b A! indica operacin lgica NnotOB

Winalmente% C# da la posi$ilidad de poder escri$ir identi&icadores )ue inclu+an
caracteres Knicode )ue no se puedan imprimir usando el teclado de la m)uina del
programador o )ue no sean directamente (lidos de$ido a )ue tengan un signi&icado
especial en el lenguaje* Para ello% lo )ue permite es escri$ir estos caracteres usando
;16012679; 51 1;69<1% )ue no son ms )ue secuencias de caracteres con las sinta-is3
\u<dgito><dgito><dgito><dgito>
\U<dgito><dgito><dgito><dgito><dgito><dgito><dgito><dgito>
Estos d.gitos indican es el cdigo Knicode del carcter )ue se desea incluir como parte
del identi&icador% + cada uno de ellos /a de ser un d.gito /e-adecimal (lido* A'F% a'<
.'GB 8a+ )ue se1alar )ue el carcter u /a de escri$ise en min,scula cuando se
indi)uen caracteres Knicode con " d.gitos + en ma+,scula cuando se indi)uen con
caracteres de oc/o* Ejemplos de identi&icadores (lidos son C\u0064 Ae)ui(ale a C#%
pues T" es el cdigo de # en KnicodeB a\U00000033b Ae)ui(ale a a!bB
,alabras reservadas
Aun)ue antes se /an dado una serie de restricciones so$re cules son los nom$res
(lidos )ue se pueden dar en C# a los identi&icadores% &alta toda(.a por dar una3 los
siguientes nom$res no son (lidos como identi&icadores +a )ue tienen un signi&icado
especial en el lenguaje3
abstract, as, base, bool, break, byte, case, catch, char, checked, class, const,
continue, decimal, default, delegate, do, double, else, enum, event, explicit, extern,
false, finally, fixed, float, for, foreach, goto, if, implicit, in, int, interface, internal, lock,
is, long, namespace, new, null, object, operator, out, override, params, private,
protected, public, readonly, ref, return, sbyte, sealed, short, sizeof, stackalloc, static,
string, struct, switch, this, throw, true, try, typeof, uint, ulong, unchecked, unsafe, ushort,
using, virtual, void, while
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
Aparte de estas pala$ras reser(adas% si en &uturas implementaciones del lenguaje se
decidiese incluir nue(as pala$ras reser(adas% 6icroso&t dice )ue dic/as pala$ras /a$r.an
de incluir al menos dos s.m$olos de su$ra+ado consecuti(os A__B Por tanto% para e(itar
posi$les con&lictos &uturos no se recomienda dar a nuestros identi&icadores nom$res )ue
contengan dic/a secuencia de s.m$olos*
Aun)ue directamente no podemos dar estos nom$res a nuestros identi&icadores% C#
proporciona un mecanismo para /acerlo indirectamente + de una &orma muc/o ms
legi$le )ue usando secuencias de escape* Este mecanismo consiste en usar el carcter -
para pre&ijar el nom$re coincidente con el de una pala$ra reser(ada )ue )ueramos dar a
nuestra (aria$le* Por ejemplo% el siguiente cdigo es (lido3
class @class
{
static void @static(bool @bool)
{
if (@bool)
Console.WriteLine("cierto");
else
Console.WriteLine("falso");
}
}
?o )ue se /a /ec/o en el cdigo anterior /a sido usar @ para declarar una clase de
nom$re class con un mtodo de nom$re static )ue toma un parmetro de nom$re bool%
a,n cuando todos estos nom$res son pala$ras reser(adas en C#*
8a+ )ue precisar )ue aun)ue el nom$re )ue nosotros escri$amos sea por ejemplo
@class% el nom$re con el )ue el compilador (a a tratar internamente al identi&icador es
solamente class* Ce /ec/o% si desde cdigo escrito en otro lenguaje adaptado a *4E5
distinto a C# /acemos re&erencia a ste identi&icador + en ese lenguaje su nom$re no es
una pala$ra reser(ada% el nom$re con el )ue de$eremos re&erenciarlo es class% + no
Hclass Asi tam$in &uese en ese lenguaje pala$ra reser(ada /a$r.a )ue re&erenciarlo
con el mecanismo )ue el lenguaje inclu+ese para ello% )ue )uizs tam$in podr.a
consistir en usar - como en C#B
En realidad% el uso de @ no se tiene por)u limitar a preceder pala$ras reser(adas en
C#% sino )ue podemos preceder cual)uier nom$re con l* Sin em$argo% /acer esto no se
recomienda% pues es considerado como un mal /$ito de programacin + puede
pro(ocar errores mu+ sutiles como el )ue muestra el siguiente ejemplo3
class A
{
int a; // (1)
int @a; // (2)
public static void Main()
{}
}

Si intentamos compilar este cdigo se producir un error )ue nos in&ormar de )ue el
campo de nom$re a /a sido declarado m,ltiples (eces en la clase A* Esto se de$e a )ue
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
como - no &orma parte en realidad del nom$re del identi&icador al )ue precede% las
declaraciones marcadas con comentarios como A1B + AB son e)ui(alentes*
8a+ )ue se1alar por ,ltimo una cosa respecto al carcter @3 slo puede preceder al
nom$re de un identi&icador% pero no puede estar contenido dentro del mismo* Es decir%
identi&icadores como i5322@fie.us.es no son (lidos*
Literales
Kn -73149- es la representacin e-pl.cita de los (alores )ue pueden tomar los tipos
$sicos del lenguaje* A continuacin se e-plica cul es la sinta-is con )ue se escri$en
los literales en C# desglosndolos seg,n el tipo de (alores )ue representan3
L73149-1; 12314.;: Kn n,mero entero se puede representar en C# tanto en
&ormato decimal como /e-adecimal* En el primer caso $asta escri$ir los d.gitos
decimales A0-9B del n,mero unos tras otros% mientras )ue en el segundo /a+ )ue
preceder los d.gitos /e-adecimales A0-9% a-f% A-FB con el pre&ijo 0x* En am$os
casos es posi$le preceder el n,mero de los operadores . para indicar si es
positi(o o negati(o% aun)ue si no se pone nada se considerar )ue es positi(o*
Ejemplos de literales enteros son 0% 5% +15% -23% 0x1A% -0x1a% etc
En realidad% la sinta-is completa para la escritura de literales enteros tam$in
puede incluir un su&ijo )ue indi)ue el tipo de dato entero al )ue /a de pertenecer
el literal* Esto no lo (eremos /asta el Tema 7: Variales ! tipos de datos*

L73149-1; 419-1;: ?os n,meros reales se escri$en de &orma similar a los enteros%
aun)ue slo se pueden escri$ir en &orma decimal + para separar la parte entera
de la real usan el tradicional punto decimal Acarcter .B 5am$in es posi$le
representar los reales en &ormato cient.&ico% usndose para indicar el e-ponente
los caracteres e E* Ejemplos de literales reales son 0.0% 5.1% -5.1% +15.21%
3.02e10% 2.02e-2% 98.8E+1% etc*
Al igual )ue ocurr.a con los literales enteros% los literales reales tam$in pueden
incluir su&ijos )ue indi)uen el tipo de dato real al )ue pertenecen% aun)ue
nue(amente no los (eremos /asta el Tema 7: Variales ! tipos de datos
L73149-1; -8=76.;: ?os ,nicos literales lgicos (lidos son true + faIse% )ue
respecti(amente representan los (alores lgicos cierto + &also*
L73149-1; 51 694M6314: Prcticamente cual)uier carcter se puede representar
encerrndolo entre comillas simples* Por ejemplo% 'a' Aletra aB% ' ' Acarcter de
espacioB% '?' As.m$olo de interrogacinB% etc* ?as ,nicas e-cepciones a esto son
los caracteres )ue se muestran en la T9C-9 4.1% )ue /an de representarse con
secuencias de escape )ue indi)uen su (alor como cdigo Knicode o mediante un
&ormato especial tal + como se indica a continuacin3
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
C94M6314 C857=. 51 1;69<1
U276.51
C857=. 51
1;69<1 1;<1679-
Comilla simple
\u0027 \'
Comilla do$le
\u0022 \"
Carcter nulo
\u0000 \0
Alarma
\u0007 \a
>etroceso
\u0008 \b
Salto de pgina
\u000C \f
4ue(a l.nea
\u000A \n
>etorno de carro
\u000D \r
5a$ulacin /orizontal
\u0009 \t
5a$ulacin (ertical
\u000B \v
0arra in(ertida
\u005C \\
T9C-9 4.1: Cdigos de escape especiales
En realidad% de la ta$la anterior /a+ )ue matizar )ue el carcter de comilla do$le
tam$in puede aparecer dentro de un literal de cadena directamente% sin
necesidad de usar secuencias de escape* Por tanto% otros ejemplos de literales de
carcter (lidos sern '\"'% '"'% '\f'% '\u0000'% '\\'% '\''% etc*
Aparte de para representar los caracteres de la ta$la anterior% tam$in es posi$le
usar los cdigos de escape Knicode para representar cual)uier cdigo Knicode%
lo )ue suele usarse para representar literales de caracteres no incluidos en los
teclados estndares*
Junto al &ormato de representacin de cdigos de escape Knicode +a (isto% C#
inclu+e un &ormato a$re(iado para representar estos cdigos en los literales de
carcter si necesidad de escri$ir siempre cuatro d.gitos a,n cuando el cdigo a
representar tenga muc/os ceros en su parte iz)uierda* Este &ormato consiste en
preceder el cdigo de \x en (ez de \u* Ce este modo% los literales de carcter
'\U00000008'% '\u0008'% '\x0008'% '\x008'% '\x08' + '\x8' son todos e)ui(alentes* 8a+ )ue
tener en cuenta )ue este &ormato a$re(iado slo es (lido en los literales de
carcter% + no a la /ora de dar nom$res a los identi&icadores*
L73149-1; 51 695129: Kna 695129 no es ms )ue una secuencia de caracteres
encerrados entre comillas do$les* Por ejemplo "Hola, mundo"% "camin"% etc* El
te-to contenido dentro estos literales puede estar &ormado por cual)uier n,mero
de literales de carcter concatenados + sin las comillas simples% aun)ue si
inclu+e comillas do$les stas /an de escri$irse usando secuencias de escape
por)ue si no el compilador las interpretar.a como el &inal de la cadena*
Aparte del &ormato de escritura de literales de cadenas antes comentado% )ue es
el com,nmente usado en la ma+or.a de lenguajes de programacin% C# tam$in
admite un nue(o &ormato para la escritura estos literales tipo de literales
consistente en precederlas de un s.m$olo -% caso en )ue todo el contenido de la
cadena ser.a interpretado tal cual% sin considerar la e-istencia de secuencias de
escape* A este tipo de literales se les conoce como -73149-1; 51 695129 <-92.; +
pueden incluso ocupar m,ltiples l.neas* ?a siguiente ta$la recoge algunos
ejemplos de cmo se interpretan3
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
L73149- 51 695129 I2314<41395. 6.?....
"Hola\tMundo"
8ola 6undo
@Hola\tMundo"
8ola^t6undo
@"Hola
Mundo"
8ola
6undo
@Hola Mundo"
N8ola 6undoO
T9C-9 4.#: Ejemplos de literales de cadena planos
El ,ltimo ejemplo de la ta$la se /a apro(ec/ado para mostrar )ue si dentro de un literal
de cadena plano se desea incluir caracteres de comilla do$le sin )ue sean con&undidos
con el &inal de la cadena $asta duplicarlos*
L73149- 20-.: El literal nulo es un (alor especial )ue se representa en C# con la
pala$ra reser(ada nuII + se usa como (alor de las (aria$les de o$jeto no
inicializadas para as. indicar )ue contienen re&erencias nulas*
&peradores
Kn .<1495.4 en C# es un s.m$olo &ormado por uno o ms caracteres )ue permite
realizar una determinada operacin entre uno o ms datos + produce un resultado*
A continuacin se descri$en cules son los operadores incluidos en el lenguaje
clasi&icados seg,n el tipo de operaciones )ue permiten realizar% aun)ue /a+ )ue tener en
cuenta )ue C# permite la rede&inicin del signi&icado de la ma+or.a de los operadores
seg,n el tipo de dato so$re el )ue se apli)uen% por lo )ue lo )ue a)u. se cuenta se
corresponde con los usos ms comunes de los mismos3
O<14967.21; 9473?N3769; 3 ?os operadores aritmticos incluidos en C# son los
t.picos de suma A+B% resta A-B% producto A*B% di(isin A/B + mdulo A%B 5am$in se
inclu+en operadores de Nmenos unarioO A-B + Nms unarioO A+B
>elacionados con las operaciones aritmticas se encuentran un par de operadores
llamados checked + unchecked )ue permiten controlar si se desea detectar los
des$ordamientos )ue puedan producirse si al realizar este tipo de operaciones el
resultado es superior a la capacidad del tipo de datos de sus operandos* Estos
operadores se usan as.3
checked (<expresinAritmtica>)
unchecked(<expresinAritmtica>)
Am$os operadores calculan el resultado de <expresinAritmtica> + lo de(uel(en
si durante el clculo no se produce ning,n des$ordamiento* Sin em$argo% en
caso de )ue /a+a des$ordamiento cada uno act,a de una &orma distinta3 checked
pro(oca un error de compilacin si <expresinAritmtica> es una e-presin
constante + una e-cepcin System.OverfIowException si no lo es% mientras )ue
unchecked de(uel(e el resultado de la e-presin aritmtica truncado para modo
)ue )uepa en el tama1o esperado*
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
Por de&ecto% en ausencia de los operadores checked + unchecked lo )ue se /ace
es e(aluar las operaciones aritmticas entre datos constantes como si se les
aplicase checked + las operaciones entre datos no constantes como si se les
/u$iese aplicado unchecked*
O<14967.21; -8=769;: Se inclu+en operadores )ue permiten realizar las
operaciones lgicas t.picas3 NandO A&& y &B% NorO A|| + |B% NnotO A!B + N-orO A^B
?os operadores && + || se di&erencia de & + | en )ue los primeros realizan
e(aluacin perezosa + los segundos no* ?a e(aluacin perezosa consiste en )ue
si el resultado de e(aluar el primer operando permite deducir el resultado de la
operacin% entonces no se e(al,a el segundo + se de(uel(e dic/o resultado
directamente% mientras )ue la e(aluacin no perezosa consiste en e(aluar
siempre am$os operandos* Es decir% si el primer operando de una operacin //
es &also se de(uel(e +alse directamente% sin e(aluar el segundoU + si el primer
operando de una 00 es cierto se de(uel(e true directamente% sin e(aluar el otro*

O<14967.21; 41-967.29-1;: Se /an incluido los tradicionales operadores de
igualdad A==B% desigualdad A!=B% Nma+or )ueO A>B% Nmenor )ueO A<B% Nma+or o
igual )ueO A>=B + Nmenor o igual )ueO A<=B
O<14967.21; 51 ?927<0-96782 51 C73; 3 Se /an incluido operadores )ue
permiten realizar a ni(el de $its operaciones NandO A&B% NorO A|B% NnotO A~B% N-orO
A^B% desplazamiento a iz)uierda A<<B + desplazamiento a derec/a A>>B El
operador << desplaza a iz)uierda rellenando con ceros% mientras )ue el tipo de
relleno realizado por >> depende del tipo de dato so$re el )ue se aplica3 si es un
dato con signo mantiene el signo% + en caso contrario rellena con ceros*
O<14967.21; 51 9;7=296782: Para realizar asignaciones se usa en C# el operador
=% operador )ue adems de realizar la asignacin )ue se le solicita de(uel(e el
(alor asignado* Por ejemplo% la e-presin a = b asigna a la (aria$le a el (alor de
la (aria$le b + de(uel(e dic/o (alor% mientras )ue la e-presin c = a = b asigna a
c + a el (alor de b Ael operador = es asociati(o por la derec/aB
5am$in se /an incluido operadores de asignacin compuestos )ue permiten
a/orrar tecleo a la /ora de realizar asignaciones tan comunes como3
temperatura = temperatura + 15; // Sin usar asignacin compuesta
temperatura += 15; // Usando asignacin compuesta
?as dos l.neas anteriores son e)ui(alentes% pues el operador compuesto += lo )ue
/ace es asignar a su primer operando el (alor )ue ten.a ms el (alor de su
segundo operando* Como se (e% permite compactar $astante el cdigo*
Aparte del operador de asignacin compuesto +=% tam$in se o&recen operadores
de asignacin compuestos para la ma+or.a de los operadores $inarios +a (istos*
Estos son3 +=% -=% *=% /=% %=% &=% |=% ^=% <<= + >>=* 4tese )ue no /a+ (ersiones
compuestas para los operadores $inarios // + 00*
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
Ltros dos operadores de asignacin incluidos son los de incrementoA++B +
decremento A--B Estos operadores permiten% respecti(amente% aumentar +
disminuir en una unidad el (alor de la (aria$le so$re el )ue se aplican* As.% estas
l.neas de cdigo son e)ui(alentes3
temperatura = temperatura + 1; // Sin usar asignacin compuesta ni incremento
temperatura += 1; // Usando asignacin compuesta
temperatura++; // Usando incremento
Si el operador ++ se coloca tras el nom$re de la (aria$le Acomo en el ejemploB
de(uel(e el (alor de la (aria$le antes de incrementarla% mientras )ue si se coloca
antes% de(uel(e el (alor de sta tras incrementarlaU + lo mismo ocurre con el
operador --* Por ejemplo3
c = b++; // Se asigna a c el valor de b y luego se incrementa b c = ++b;
c = ++b; // Se incrementa el valor de b y luego se asigna a c
?a (entaja de usar los operadores ++ + -- es )ue en muc/as m)uinas son ms
e&icientes )ue el resto de &ormas de realizar sumas o restas de una unidad% pues
el compilador traducirlos en una ,nica instruccin en cdigo m)uina
Q
*
O<14967.21; 6.2 695129;: Para realizar operaciones de concatenacin de
cadenas se puede usar el mismo operador )ue para realizar sumas% +a )ue en C#
se /a rede&inido su signi&icado para )ue cuando se apli)ue entre operandos )ue
sean cadenas o )ue sean una cadena + un carcter lo )ue /aga sea concatenarlos*
Por ejemplo% "Hola"+" mundo" de(uel(e "Hola mundo"% + "Hola mund" + 'o' tam$in*
O<14967.21; 51 9661;. 9 39C-9;: Kna 39C-9 es un conjunto de ordenado de
o$jetos de tama1o &ijo* Para acceder a cual)uier elemento de este conjunto se
aplica el operador post&ijo [] so$re la ta$la para indicar entre corc/etes la
posicin )ue ocupa el o$jeto al )ue se desea acceder dentro del conjunto* Es
decir% este operador se usa as.3
[<posicinElemento>]
Kn ejemplo de su uso en el )ue se asigna al elemento )ue ocupa la posicin ! en
una ta$la de nom$re tablaPrueba el (alor del elemento )ue ocupa la posicin 1R
de dic/a ta$la es el siguiente3
tablaPrueba[3] = tablaPrueba[18];
?as ta$las se estudian detenidamente en el Tema 7: Variales ! tipos de datos
O<1495.4 6.25767.29-: Es el ,nico operador incluido en C# )ue toma !
operandos% + se usa as.3
<condicin> ? <expresin1> : <expresin2>
Q
Generalmente% en estas m)uinas ++ se con(ierte en una instruccin NC + -- en una instruccin DEC
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
El signi&icado del operando es el siguiente3 se e(al,a <condicin> Si es cierta se
de(uel(e el resultado de e(aluar <expresin1>, + si es &alsa se de(uel(e el
resultado de e(aluar <condicin2>* Kn ejemplo de su uso es3
b = (a>0)? a : 0; // Suponemos a y b de tipos enteros
En este ejemplo% si el (alor de la (aria$le a es superior a 0 se asignar a b el
(alor de a% mientras )ue en caso contrario el (alor )ue se le asignar ser 0*
8a+ )ue tener en cuenta )ue este operador es asociati(o por la derec/a% por lo
)ue una e-presin como a?b:c?d:e es e)ui(alente a a?b:(c?d:e)
4o /a+ )ue con&undir este operador con la instruccin condicional if )ue se
tratar en el Tema 8:"nstr#$$iones% pues aun)ue su utilidad es similar al de sta%
? de(uel(e un (alor e if no*

O<14967.21; 51 51-1=95.;: Kn 51-1=95. es un o$jeto )ue puede almacenar en
re&erencias a uno o ms mtodos + a tra(s del cual es posi$le llamar a estos
mtodos* Para a1adir o$jetos a un delegado se usan los operadores + + +=%
mientras )ue para )uitrselos se usan los operadores - + -=* Estos conceptos se
estudiarn detalladamente en el Tema %&: E'entos ! dele(ados
O<14967.21; 51 9661;. 9 .C>13.;: Para acceder a los miem$ros de un o$jeto se
usa el operador .% cu+a sinta-is es3
<objeto>.<miembro>
Si a es un o$jeto% ejemplos de cmo llamar a di&erentes miem$ros su+os son3

a.b = 2; // Asignamos a su propiedad a el valor 2
a.f(); // Llamamos a su mtodo f()
a.g(2); // Llamamos a su mtodo g() pasndole como parmetro el valor entero 2
a.c += new adelegado(h) // Asociamos a su evento c el cdigo del mtodo h() de
//tipo adelegado
4o se preocupe si no conoce los conceptos de mtodos% propiedades% e(entos +
delegados en los )ue se $asa este ejemplo% pues se e-plican detalladamente en
temas posteriores*

O<14967.21; 6.2 <02314.;: Kn puntero es una (aria$le )ue almacena una
re&erencia a una direccin de memoria* Para o$tener la direccin de memoria de
un o$jeto se usa el operador &% para acceder al contenido de la direccin de
memoria almacenada en un puntero se usa el operador *% para acceder a un
miem$ro de un o$jeto cu+a direccin se almacena en un puntero se usa ->% + para
re&erenciar una direccin de memoria de &orma relati(a a un puntero se le aplica
el operador [] de la &orma puntero[desplazamiento]* 5odos estos conceptos se
e-plicarn ms a &ondo en el Tema %8: C)di(o inse(#ro*
O<14967.21; 51 .C3126782 51 72@.4?96782 ;.C41 37<.;: Ce todos los
operadores )ue nos permiten o$tener in&ormacin so$re tipos de datos el ms
importante es typeof% cu+a &orma de uso es3
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
typeof(<nombreTipo>)
Este operador de(uel(e un o$jeto de tipo System.Type con in&ormacin so$re el
tipo de nom$re <nombreTipo> )ue podremos consultar a tra(s de los miem$ros
o&recidos por dic/o o$jeto* Esta in&ormacin inclu+e detalles tales como cules
son sus miem$ros% cul es su tipo padre o a )u espacio de nom$res pertenece*
Si lo )ue )ueremos es determinar si una determinada e-presin es de un tipo u
otro% entonces el operador a usar es is% cu+a sinta-is es la siguiente3
<expresin> is <nombreTipo>
El signi&icado de este operador es el siguiente3 se e(al,a <expresin>. Si el
resultado de sta es del tipo cu+o nom$re se indica en <nombreTipo> se de(uel(e
trueU + si no% se de(uel(e faIse* Como se (er en el Tema 5: Clases% este
operador suele usarse en mtodos polimr&icos*
Winalmente% C# incorpora un tercer operador )ue permite o$tener in&ormacin
so$re un tipo de dato3 sizeof Este operador permite o$tener el n,mero de $+tes
)ue ocuparn en memoria los o$jetos de un tipo% + se usa as.3
sizeof(<nombreTipo>)
sizeof slo puede usarse dentro de cdigo inseguro% )ue por a/ora $asta
considerar )ue son zonas de cdigo donde es posi$le usar punteros* 4o ser
/asta el Tema %8: C)di(o inse(#ro cuando lo trataremos en pro&undidad*
Adems% si1eo+ slo se puede aplicar so$re nom$res de tipos de datos cu+os
o$jetos se puedan almacenar directamente en pila* Es decir% )ue sean estructuras
Ase (ern en el Tema %&B o tipos enumerados Ase (ern en el Tema %*B
O<14967.21; 51 64196782 51 .C>13.; 3 El operador ms t.picamente usado para
crear o$jetos es new% )ue se usa as.3
new <nombreTipo>(<parametros>)
Este operador crea un o$jeto de <nombreTipo> pasndole a su mtodo constructor
los parmetros indicados en <parmetros> + de(uel(e una re&erencia al mismo*
En &uncin del tipo + n,mero de estos parmetros se llamar a uno u otro de los
constructores del o$jeto* As.% suponiendo )ue a1 + a2 sean (aria$les de tipo
Avin% ejemplos de uso del operador new son3
Avin a1 = new Avin(); // Se llama al constructor sin parmetros de Avin
Avin a2 = new Avin(Caza); // Se llama al constructor de Avin que toma
// como parmetro una cadena
En caso de )ue el tipo del )ue se /a+a solicitado la creacin del o$jeto sea una
clase% ste se crear en memoria dinmica% + lo )ue new de(ol(er ser una
re&erencia a la direccin de pila donde se almacena una re&erencia a la direccin
del o$jeto en memoria dinmica* Sin em$argo% si el o$jeto a crear pertenece a
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
una estructura o a un tipo enumerado% entonces ste se crear directamente en la
pila + la re&erencia de(uelta por el new se re&erir directamente al o$jeto creado*
Por estas razones% a las clases se les conoce como 37<.; 41@1412679 +a )ue de sus
o$jetos en pila slo se almacena una re&erencia a la direccin de memoria
dinmica donde (erdaderamente se encuentranU mientras )ue a las estructuras +
tipos enumerados se les conoce como 37<.; A9-.4 +a sus o$jetos se almacenan
directamente en pila*
C# proporciona otro operador )ue tam$in nos permite crear o$jetos* <ste es
stackaIIoc% + se usa as.3
stackaIIoc <nombreTipo>[<nElementos>]
Este operador lo )ue /ace es crear en pila una ta$la de tantos elementos de tipo
<nombreTipo> como indi)ue <nElementos> + de(ol(er la direccin de memoria en
)ue sta /a sido creada* Por ejemplo3
stackaIIoc slo puede usarse para inicializar punteros a o$jetos de tipos (alor
declarados como (aria$les locales* Por ejemplo3
int * p = stackalloc[100]; // p apunta a una tabla de 100 enteros.
O<14967.21; 51 6.2A14;782: Para con(ertir unos o$jetos en otros se utiliza el
operador de con(ersin% )ue no consiste ms )ue en preceder la e-presin a
con(ertir del nom$re entre parntesis del tipo al )ue se desea con(ertir el
resultado de e(aluarla* Por ejemplo% si l es una (aria$le de tipo Iong + se desea
almacenar su (alor dentro de una (aria$le de tipo int llamada i% /a$r.a )ue
con(ertir pre(iamente su (alor a tipo int as.3
i = (int) l; // Asignamos a i el resultado de convertir el valor de l a tipo int
?os tipos int + Iong estn prede&inidos en C# + permite almacenar (alores
enteros con signo* ?a capacidad de int es de ! $its% mientras )ue la de Iong es
de T" $its* Por tanto% a no ser )ue /agamos uso del operador de con(ersin% el
compilador no nos dejar /acer la asignacin% +a )ue al ser ma+or la capacidad
de los Iong% no todo (alor )ue se pueda almacenar en un Iong tiene por)u
poderse almacenar en un int* Es decir% no es (lido3
i = l; //ERROR: El valor de l no tiene porqu caber en i
Esta restriccin en la asignacin la impone el compilador de$ido a )ue sin ella
podr.an producirse errores mu+ di&.ciles de detectar ante truncamientos no
esperados de$ido al )ue el (alor de la (aria$le &uente es superior a la capacidad
de la (aria$le destino*
E-iste otro operador )ue permite realizar operaciones de con(ersin de &orma
mu+ similar al +a (isto* <ste es el operador as% )ue se usa as.3
<expresin> as <tipoDestino>
El lenguaje de programacin C# 5ema "3 Aspectos l-icos
?o )ue /ace es de(ol(er el resultado de con(ertir el resultado de e(aluar
<expresin> al tipo indicado en <tipoDestino> Por ejemplo% para almacenar en una
(aria$le p el resultado de con(ertir un o$jeto t a tipo tipo Persona se /ar.a3
p = t as Persona;
?as ,nicas di&erencias entre usar uno u otro operador de con(ersin son3
as slo es aplica$le a tipos re&erencia + slo a a)uellos casos en )ue
e-istan con(ersiones prede&inidas en el lenguaje* Como se (er ms
adelante% esto slo inclu+e con(ersiones entre un tipo + tipos padres
su+os + entre un tipo + tipos /ijos su+os*
Kna consecuencia de esto es )ue el programador puede de&inir cmo
/acer con(ersiones de tipos por l de&inidos + otros mediante el operador
()% pero no mediante as*
Esto se de$e a )ue as ,nicamente indica )ue se desea )ue una re&erencia
a un o$jeto en memoria dinmica se trate como si el o$jeto &uese de otro
tipo% pero no implica con(ersin ninguna* Sin em$argo% () s. )ue implica
con(ersin si el <tipoDestino> no es compati$le con el tipo del o$jeto
re&erenciado* L$(iamente% el operador se aplirar muc/o ms rpido en
los casos donde no sea necesario con(ertir*
En caso de )ue se solicite /acer una con(ersin in(lida as de(uel(e nuII
mientras )ue () produce una e-cepcin System.InvaIidCastException*
El lenguaje de programacin C# 5ema Q3 Clases
TEMA 5: CIases
)efinicin de clases
Conceptos de cIase y objeto
C# es un lenguaje orientado a o$jetos puro
T
% lo )ue signi&ica )ue todo con lo )ue (amos
a tra$ajar en este lenguaje son o$jetos* Kn .C>13. es un agregado de datos + de mtodos
)ue permiten manipular dic/os datos% + un programa en C# no es ms )ue un conjunto
de o$jetos )ue interaccionan unos con otros a tra(s de sus mtodos*

Kna 6-9;1 es la de&inicin de las caracter.sticas concretas de un determinado tipo de
o$jetos* Es decir% de cules son los datos + los mtodos de los )ue (an a disponer todos
los o$jetos de ese tipo* Por esta razn% se suele decir )ue el 37<. 51 593. de un o$jeto es
la clase )ue de&ine las caracter.sticas del mismo
[
*
Sintaxis de definicin de cIases
?a sinta-is $sica para de&inir una clase es la )ue a continuacin se muestra3
cIass <nombreClase>
{
<miembros>
}
Ce este modo se de&inir.a una clase de nom$re :nom-reClase= cu+os miem$ros son los
de&inidos en :miem-ros= ?os ?71?C4.; de una clase son los datos + mtodos de los
)ue (an a disponer todos los o$jetos de la misma* Kn ejemplo de cmo declarar una
clase de nom$re . )ue no tenga ning,n miem$ro es la siguiente3
class A
{}
Kna clase as. declarada no dispondr de ning,n miem$ro a e-cepcin de los
impl.citamente de&inidos de manera com,n para todos los o$jetos )ue creemos en C#*
Estos miem$ros los (eremos dentro de poco en este mismo tema $ajo el ep.gra&e +a
$lase prime(ina: S!stem.,-e$t*
Aun)ue en C# /a+ muc/os tipos de miem$ros distintos% por a/ora (amos a considerar
)ue estos ,nicamente pueden ser campos o mtodos + (amos a /a$lar un poco acerca de
ellos + de cmo se de&inen3
T
Esta a&irmacin no es del todo cierta% pues como (eremos ms adelante /a+ elementos del lenguaje )ue
no estn asociados a ning,n o$jeto en concreto* Sin em$argo% para simpli&icar podemos considerarlo por
a/ora como tal*
[
En realidad /a+ otras &ormas de de&inir las caracter.sticas de un tipo de o$jetos% como son las estructuras
+ las enumeraciones* Por tanto% el tipo de dato de un o$jeto no tiene por)u ser una clase% aun)ue a
e&ectos de simpli&icacin por a/ora consideraremos )ue siempre lo es*
El lenguaje de programacin C# 5ema Q3 Clases
C9?<.;: Kn 69?<. es un dato com,n a todos los o$jetos de una determinada
clase* Para de&inir cules son los campos de los )ue una clase dispone se usa la
siguiente sinta-is dentro de la zona se1alada como <miembros> en la de&inicin
de la misma3
<tipoCampo> <nombreCampo>;
El nom$re )ue demos al campo puede ser cual)uier identi&icador )ue )ueramos
siempre + cuando siga las reglas descritas en el Tema *: .spe$tos +/i$os para la
escritura de identi&icadores + no coincida con el nom$re de ning,n otro miem$ro
pre(iamente de&inido en la de&inicin de clase*
?os campos de un o$jeto son a su (ez o$jetos% + en <tipoCampo> /emos de
indicar cul es el tipo de dato del o$jeto )ue (amos a crear* <ste tipo puede
corresponderse con cual)uiera )ue los prede&inidos en la 0C? o con cual)uier
otro )ue nosotros /allamos de&inido siguiendo la sinta-is arri$a mostrada* A
continuacin se muestra un ejemplo de de&inicin de una clase de nom$re
Persona )ue dispone de tres campos3
class Persona
{
string Nombre; // Campo de cada objeto Persona que almacena su nombre
int Edad; // Campo de cada objeto Persona que almacena su edad
string NF; // Campo de cada objeto Persona que almacena su NF
}
Seg,n esta de&inicin% todos los o$jetos de clase Persona incorporarn campos
)ue almacenarn cul es el nom$re de la persona )ue cada o$jeto representa%
cul es su edad + cul es su 4#W* El tipo int incluido en la de&inicin del campo
Edad es un tipo prede&inido en la 0C? cu+os o$jetos son capaces de almacenar
n,meros enteros con signo comprendidos entre X*1"[*"R!*T"R + *1"[*"R!*T"[
A! $itsB% mientras )ue string es un tipo prede&inido )ue permite almacenar
cadenas de te-to )ue sigan el &ormato de los literales de cadena (isto en el Tema
*: .spe$tos +/i$os
Para acceder a un campo de un determinado o$jeto se usa la sinta-is3
<objeto>.<campo>
Por ejemplo% para acceder al campo Edad de un o$jeto Persona llamado p +
cam$iar su (alor por 20 se /ar.a3
p.Edad = 20;
En realidad lo marcado como <objeto> no tiene por)u ser necesariamente el
nom$re de alg,n o$jeto% sino )ue puede ser cual)uier e-presin )ue produzca
como resultado una re&erencia no nula a un o$jeto Asi produjese nuII se lanzar.a
una e-cepcin del tipo prede&inido System.NuIIPointerExceptionB
MN3.5.;: Kn ?N3.5. es un conjunto de instrucciones a las )ue se les asocia un
nom$re de modo )ue si se desea ejecutarlas $asta re&erenciarlas a tra(s de
El lenguaje de programacin C# 5ema Q3 Clases
dic/o nom$re en (ez de tener )ue escri$irlas* Centro de estas instrucciones es
posi$le acceder con total li$ertad a la in&ormacin almacenada en los campos
pertenecientes a la clase dentro de la )ue el mtodo se /a de&inido% por lo )ue
como al principio del tema se indic% los mtodos permiten manipular los datos
almacenados en los o$jetos*
?a sinta-is )ue se usa en C# para de&inir los mtodos es la siguiente3
<tipoDevuelto> <nombreMtodo> (<parametros>)
{
<instrucciones>
}
5odo mtodo puede de(ol(er un o$jeto como resultado de la ejecucin de las
instrucciones )ue lo &orman% + el tipo de dato al )ue pertenece este o$jeto es lo
)ue se indica en <tipoDevuelto>* Si no de(uel(e nada se indica void% + si de(uel(e
algo es o$ligatorio &inalizar la ejecucin de sus instrucciones con alguna
instruccin return <objeto>; )ue indi)ue )u o$jeto /a de de(ol(erse*
Lpcionalmente todo mtodo puede reci$ir en cada llamada una lista de o$jetos a
los )ue podr acceder durante la ejecucin de sus instrucciones* En <parametros>
se indica es cules son los tipos de dato de estos o$jetos + cul es el nom$re con
el )ue /arn re&erencia las instrucciones del mtodo a cada uno de ellos* Aun)ue
los o$jetos )ue puede reci$ir el mtodo pueden ser di&erentes cada (ez )ue se
solicite su ejecucin% siempre /an de ser de los mismos tipos + /an de seguir el
orden esta$lecido en <parametros>*
Kn ejemplo de cmo declarar un mtodo de nom$re Cumpleaos es la siguiente
modi&icacin de la de&inicin de la clase 4ersona usada antes como ejemplo3
class Persona
{
string Nombre; // Campo de cada objeto Persona que almacena su nombre
int Edad; // Campo de cada objeto Persona que almacena su edad
string NF; // Campo de cada objeto Persona que almacena su NF
void Cumpleaos() // ncrementa en uno de la edad del objeto Persona
{
Edad++;
}
}
?a sinta-is usada para llamar a los mtodos de un o$jeto es la misma )ue la
usada para llamar a sus campos% slo )ue a/ora tras el nom$re del mtodo al )ue
se desea llamar /a+ )ue indicar entre parntesis cules son los (alores )ue se
desea dar a los parmetros del mtodo al /acer la llamada* L sea% se escri$e3
<objeto>.<mtodo>(<parmetros>)
Como es lgico% si el mtodo no tomase parmetros se dejar.an (ac.os los
parmetros en la llamada al mismo* Por ejemplo% para llamar al mtodo
Cumpleaos() de un o$jeto Persona llamado p se /ar.a3
El lenguaje de programacin C# 5ema Q3 Clases
p.Cumpleaos(); // El mtodo no toma parmetros, luego no le pasamos ninguno
Es importante se1alar )ue en una misma clase pueden de&inirse (arios mtodos
con el mismo nom$re siempre + cuando tomen di&erente n,mero o tipo de
parmetros* A esto se le conoce como ;.C41694=94 51 ?N3.5.;% + es posi$le +a
)ue cuando se les llame el compilador sa$r a cual llamar a partir de
<parmetros> pasados en la llamada*
Sin em$argo% lo )ue no es permite es de&inir (arios mtodos )ue slo se
di&erencien en su (alor de retorno% +a )ue como ste no se tiene por)u indicar al
llamarlos no podr.a di&erenciarse a )ue mtodo en concreto se /ace re&erencia en
cada llamada* Por ejemplo% a partir de la llamada3
p.Cumpleaos();
Si adems de la (ersin de Cumpleaos() )ue no retorna nada /u$iese otra )ue
retornase un int% _cmo sa$r.a entonces el compilador a cul llamar`
Antes de continuar es preciso se1alar )ue en C# todo% incluido los literales% son o$jetos
del tipo de cada literal + por tanto pueden contar con miem$ros a los )ue se acceder.a
tal + como se /a e-plicado* Para entender esto no /a+ nada mejor )ue un ejemplo3
string s = 12.ToString();
Este cdigo almacena el literal de cadena 12 en la (aria$le s% pues 12 es un o$jeto de
tipo int Atipo )ue representa enterosB + cuenta cuenta con el mtodo com,n a todos los
ints llamado ToString() )ue lo )ue /ace es de(ol(er una cadena cu+os caracteres son los
d.gitos )ue &orman el entero representado por el int so$re el )ue se aplicaU + como la
(aria$le s es de tipo string Atipo )ue representa cadenasB es per&ectamente posi$le
almacenar dic/a cadena en ella% )ue es lo )ue se /ace en el cdigo anterior*
Creacin de ob'etos
Operador new
A/ora )ue +a sa$emos cmo de&inir las clases de o$jetos )ue podremos usar en nuestras
aplicaciones /a llegado el momento de e-plicar cmo crear o$jetos de una determinada
clase* Algo de ello +a se introdujo en el Tema *: .spe$tos +/i$os cuando se coment la
utilidad del operador 21D% )ue precisamente es crear o$jetos + cu+a sinta-is es3
new <nombreTipo>(<parametros>)
Este operador crea un nue(o o$jeto del tipo cu+o nom$re se le indica + llama durante su
proceso de creacin al constructor del mismo apropiado seg,n los (alores )ue se le
pasen en <parametros>% de(ol(iendo una re&erencia al o$jeto recin creado* 8a+ )ue
resaltar el /ec/o de )ue new no de(uel(e el propio o$jeto creado% sino una re&erencia a
la direccin de memoria dinmica donde en realidad se /a creado*
El antes comentado 6.2;34063.4 de un o$jeto no es ms )ue un mtodo de&inido en la
de&inicin de su tipo )ue tiene el mismo nom$re )ue la clase a la )ue pertenece el o$jeto
El lenguaje de programacin C# 5ema Q3 Clases
+ no tiene (alor de retorno* Como new siempre de(uel(e una re&erencia a la direccin
de memoria donde se cree el o$jeto + los constructores slo pueden usarse como
operandos de new% no tiene sentido )ue un constructor de(uel(a o$jetos% por lo )ue no
tiene sentido incluir en su de&inicin un campo <tipoDevuelto> + el compilador considera
errneo /acerlo Aaun)ue se indi)ue voidB
El constructor reci$e ese nom$re de$ido a )ue su cdigo suele usarse precisamente para
construir el o$jeto% para inicializar sus miem$ros* Por ejemplo% a nuestra clase de
ejemplo Persona le podr.amos a1adir un constructor dejndola as.3
class Persona
{
string Nombre; // Campo de cada objeto Persona que almacena su nombre
int Edad; // Campo de cada objeto Persona que almacena su edad
string NF; // Campo de cada objeto Persona que almacena su NF
void Cumpleaos() // ncrementa en uno la edad del objeto Persona
{
Edad++;
}
Persona (string nombre, int edad, string nif) // Constructor
{
Nombre = nombre;
Edad = edad;
NF = nif;
}
}
Como se (e en el cdigo% el constructor toma como parmetros los (alores con los )ue
deseemos inicializar el o$jeto a crear* Gracias a l% podemos crear un o$jeto Persona de
nom$re Jos% de a1os de edad + 4#W 1!""!1XA as.3
new Persona(Jos, 22, 12344321-A)
4tese )ue la &orma en )ue se pasan parmetros al constructor consiste en indicar los
(alores )ue se /a de dar a cada uno de los parmetros indicados en la de&inicin del
mismo separndolos por comas* L$(iamente% si un parmetro se de&ini como de tipo
string /a$r )ue pasarle una cadena% si se de&ini de tipo int /a$r )ue pasarle un entero
+% en general% /a todo parmetro /a$r )ue pasarle un (alor de su mismo tipo Ao de
alguno con(erti$le al mismoB% producindose un error al compilar si no se /ace as.*
En realidad un o$jeto puede tener m,ltiples constructores% aun)ue para di&erenciar a
unos de otros es o$ligatorio )ue se di&erencien en el n,mero u orden de los parmetros
)ue aceptan% +a )ue el nom$re de todos ellos /a de coincidir con el nom$re de la clase
de la )ue son miem$ros* Ce ese modo% cuando creemos el o$jeto el compilador podr
inteligentemente determinar cul de los constructores /a de ejecutarse en &uncin de los
(alores )ue le pasemos al new*
Kna (ez creado un o$jeto lo ms normal es almacenar la direccin de(uelta por new en
una (aria$le del tipo apropiado para el o$jeto creado* El siguiente ejemplo X)ue como es
lgico ir dentro de la de&inicin de alg,n mtodoX muestra cmo crear una (aria$le de
El lenguaje de programacin C# 5ema Q3 Clases
tipo Persona llamada p + cmo almacenar en ella la direccin del o$jeto )ue de(ol(er.a
la anterior aplicacin del operador new3
Persona p; // Creamos variable p
p = new Persona(Jose, 22, 12344321-A); // Almacenamos en p el objeto creado con new
A partir de este momento la (aria$le p contendr una re&erencia a un o$jeto de clase
Persona )ue representar a una persona llamada Jos de a1os + 4#W 1!""!1XA* L
lo )ue prcticamente es lo mismo + suele ser la &orma com,nmente usada para decirlo3
la (aria$le p representa a una persona llamada Jos de a1os + 4#W 1!""!1XA*
Como lo ms normal suele ser crear (aria$les donde almacenar re&erencias a o$jetos
)ue creemos% las instrucciones anteriores pueden compactarse en una sola as.3

Persona p = new Persona(Jos, 22, 12344321-A);
Ce /ec/o% una sinta-is ms general para la de&inicin de (aria$les es la siguiente3
<tipoDato> <nombreVariable> - <valorInicial>;
?a parte = <valornicial> de esta sinta-is es en realidad opcional% + si no se inclu+e la
(aria$le declarada pasar a almacenar una re&erencia nula Acontendr el literal nuIIB
Constructor por defecto
4o es o$ligatorio de&inir un constructor para cada clase% + en caso de )ue no de&inamos
ninguno el compilador crear uno por nosotros sin parmetros ni instrucciones* Es decir%
como si se /u$iese de&inido de esta &orma3
<nombreTipo>()
{
}
Gracias a este constructor introducido automticamente por el compilador% si Coche es
una clase en cu+a de&inicin no se /a incluido ning,n constructor% siempre ser posi$le
crear uno nue(o usando el operador new as.3
Coche c = new Coche(); // Crea coche c llamando al constructor por defecto de Coche
8a+ )ue tener en cuenta una cosa3 el constructor por de&ecto es slo incluido por el
compilador si no /emos de&inido ning,n otro constructor* Por tanto% si tenemos una
clase en la )ue /a+amos de&inido alg,n constructor con parmetros pero ninguno sin
parmetros no ser (lido crear o$jetos de la misma llamando al constructor sin
parmetros% pues el compilador no lo /a$r de&inido automticamente* Por ejemplo% con
la ,ltima (ersin de la clase de ejemplo Persona es in(lido /acer3
Persona p = new Persona(); // ERROR: El nico constructor de persona toma 3 parmetros
El lenguaje de programacin C# 5ema Q3 Clases
Referencia aI objeto actuaI con this
Centro del cdigo de cual)uier mtodo de un o$jeto siempre es posi$le /acer re&erencia
al propio o$jeto usando la pala$ra reser(ada this* Esto puede (enir $ien a la /ora de
escri$ir constructores de o$jetos de$ido a )ue permite )ue los nom$res )ue demos a los
parmetros del constructor puedan coincidir nom$res de los campos del o$jeto sin )ue
/a+a ning,n pro$lema* Por ejemplo% el constructor de la clase Persona escrito
anteriormente se puede reescri$ir as. usando this3
Persona (string Nombre, int Edad, string NF)
{
this.Nombre = Nombre;
this.Edad = Edad;
this.NF = NF;
}
Es decir% dentro de un mtodo con parmetros cu+os nom$res coincidan con campos% se
da pre&erencia a los parmetros + para /acer re&erencia a los campos /a+ )ue pre&ijarlos
con el this tal + como se muestra en el ejemplo*
El ejemplo anterior puede )ue no resulte mu+ interesante de$ido a )ue para e(itar tener
)ue usar this podr.a /a$erse escrito el constructor tal + como se mostr en la primera
(ersin del mismo3 dando nom$res )ue empiecen en min,scula a los parmetros +
nom$res )ue empiecen con ma+,sculas a los campos* Ce /ec/o% ese es el con(enio )ue
6icroso&t recomienda usar* Sin em$argo% como ms adelante se (er s. )ue puede ser
,til this cuando los campos a inicializar a sean pri(ados% +a )ue el con(enio de
escritura de identi&icadores para campos pri(ados recomendado por 6icroso&t coincide
con el usado para dar identi&icadores a parmetros Ao$(iamente otra solucin ser.a dar
cual)uier otro nom$re a los parmetros del constructor o los campos a&ectados% aun)ue
as. el cdigo perder.a algo legi$ilidadB
Kn uso ms &recuente de this en C# es el de permitir realizar llamadas a un mtodo de
un o$jeto desde cdigo u$icado en mtodos del mismo o$jeto* Es decir% en C# siempre
es necesario )ue cuando llamemos a alg,n mtodo de un o$jeto precedamos al operador
. de alguna e-presin )ue indi)ue cul es el o$jeto a cu+o mtodo se desea llamar% + si
ste mtodo pertenece al mismo o$jeto )ue /ace la llamada la ,nica &orma de conseguir
indicarlo en C# es usando this*
Winalmente% una tercera utilidad de this es permitir escri$ir mtodos )ue puedan
de(ol(er como o$jeto el propio o$jeto so$re el )ue el mtodo es aplicado* Para ello
$astar.a usar una instruccin return this; al indicar el o$jeto a de(ol(er
.erencia % m/todos virtuales
Concepto de herencia
El mecanismo de J1412679 es uno de los pilares &undamentales en los )ue se $asa la
programacin orientada a o$jetos* Es un mecanismo )ue permite de&inir nue(as clases a
partir de otras +a de&inidas de modo )ue si en la de&inicin de una clase indicamos )ue
El lenguaje de programacin C# 5ema Q3 Clases
sta deri(a de otra% entonces la primera Xa la )ue se le suele llamar 6-9;1 J7>9X ser
tratada por el compilador automticamente como si su de&inicin inclu+ese la de&inicin
de la segunda Za la )ue se le suele llamar 6-9;1 <9541 o 6-9;1 C9;1* ?as clases )ue
deri(an de otras se de&inen usando la siguiente sinta-is3
cIass <nombreHija>:<nombrePadre>
{
<miembrosHija>
}
A los miem$ros de&inidos en <miembrosHijas> se le a1adirn los )ue /u$isemos
de&inido en la clase padre* Por ejemplo% a partir de la clase Persona puede crearse una
clase Trabajador as.3
class Trabajador:Persona
{
public int Sueldo;
public Trabajador(string nombre, int edad, string nif, int sueldo)
: base(nombre, edad, nif)
{
Sueldo = sueldo;
}
}
?os o$jetos de esta clase Trabajador contarn con los mismos miem$ros )ue los o$jetos
Persona + adems incorporarn un nue(o campo llamado Sueldo )ue almacenar el
dinero )ue cada tra$ajador gane* 4tese adems )ue a la /ora de escri$ir el constructor
de esta clase /a sido necesario escri$irlo con una sinta-is especial consistente en
preceder la lla(e de apertura del cuerpo del mtodo de una estructura de la &orma3
: base(<parametrosBase>)
A esta estructura se le llama 727679-7K95.4 C9;1 + se utiliza para indicar cmo deseamos
inicializar los campos /eredados de la clase padre* 4o es ms )ue una llamada al
constructor de la misma con los parmetros adecuados% + si no se inclu+e el compilador
considerar.a por de&ecto )ue (ale :base()% lo )ue ser.a incorrecto en este ejemplo de$ido
a )ue Persona carece de constructor sin parmetros*
Kn ejemplo )ue pone de mani&iesto cmo &unciona la /erencia es el siguiente3
using System;
class Persona
{
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NF; // Campo de cada objeto Persona que almacena su NF
void Cumpleaos() // ncrementa en uno de edad del objeto Persona
{
Edad++;
}
public Persona (string nombre, int edad, string nif) // Constructor de Persona
El lenguaje de programacin C# 5ema Q3 Clases
{
Nombre = nombre;
Edad = edad;
NF = nif;
}
}
class Trabajador: Persona
{
public int Sueldo; // Campo de cada objeto Trabajador que almacena cunto gana
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // nicializamos cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}
public static void Main()
{
Trabajador p = new Trabajador("Josan", 22, "77588260-Z", 100000);

Console.WriteLine ("Nombre="+p.Nombre);
Console.WriteLine ("Edad="+p.Edad);
Console.WriteLine ("NF="+p.NF);
Console.WriteLine ("Sueldo="+p.Sueldo);
}
}
4tese )ue /a sido necesario pre&ijar la de&inicin de los miem$ros de 4ersona del
pala$ra reser(ada pubIic* Esto se de$e a )ue por de&ecto los miem$ros de una tipo slo
son accesi$les desde cdigo incluido dentro de la de&inicin de dic/o tipo% e inclu+endo
pubIic conseguimos )ue sean accesi$les desde cual)uier cdigo% como el mtodo Main()
de&inido en Trabajador* pubIic es lo )ue se denomina un ?.57@7695.4 51 9661;.%
concepto )ue se tratar ms adelante en este mismo tema $ajo el ep.gra&e titulado
Modi0i$adores de a$$eso*
LIamadas por defecto aI constructor base

Si en la de&inicin del constructor de alguna clase )ue deri(e de otra no incluimos
inicializador $ase el compilador considerar )ue ste es :base() Por ello /a+ )ue estar
seguros de )ue si no se inclu+e base en la de&inicin de alg,n constructor% el tipo padre
del tipo al )ue pertenezca disponga de constructor sin parmetros*
Es especialmente signi&icati(o rese1ar el caso de )ue no demos la de&inicin de ning,n
constructor en la clase /ija% +a )ue en estos casos la de&inicin del constructor )ue por
de&ecto introducir el compilador ser en realidad de la &orma3
<nombreClase>(): base()
{}
Es decir% este constructor siempre llama al constructor sin parmetros del padre del tipo
)ue estemos de&iniendo% + si se no dispone de alguno se producir un error al compilar*
El lenguaje de programacin C# 5ema Q3 Clases
Mtodos virtuaIes
Va /emos (isto )ue es posi$le de&inir tipos cu+os mtodos se /ereden de de&iniciones
de otros tipos* ?o )ue a/ora (amos a (er es )ue adems es posi$le cam$iar dic/ar
de&inicin en la clase /ija% para lo )ue /a$r.a )ue /a$er precedido con la pala$ra
reser(ada virtuaI la de&inicin de dic/o mtodo en la clase padre* A este tipo de mtodos
se les llama ?N3.5.; A74309-1;% + la sinta-is )ue se usa para de&inirlos es la siguiente3
virtuaI <tipoDevuelto> <nombreMtodo>(<parmetros>)
{
<cdigo>
}
Si en alguna clase /ija )uisisemos dar una nue(a de&inicin del <cdigo> del mtodo%
simplemente lo (ol(er.amos a de&inir en la misma pero sustitu+endo en su de&inicin la
pala$ra reser(ada virtuaI por override* Es decir% usar.amos esta sinta-is3
override <tipoDevuelto> <nombreMtodo>(<parmetros>)
{
<nuevoCdigo>
}
4tese )ue esta posi$ilidad de cam$iar el cdigo de un mtodo en su clase /ija slo se
da si en la clase padre el mtodo &ue de&inido como 2irtual* En caso contrario% el
compilador considerar un error intentar rede&inirlo*
El lenguaje C# impone la restriccin de )ue toda rede&inicin de mtodo )ue )ueramos
realizar incorpore la part.cula o2erride para &orzar a )ue el programador est seguro de
)ue (erdaderamente lo )ue )uiere /acer es cam$iar el signi&icado de un mtodo
/eredado* As. se e(ita )ue por accidente de&ina un mtodo del )ue +a e-ista una
de&inicin en una clase padre* Adems% C# no permite de&inir un mtodo como
o2erride + 2irtual a la (ez% +a )ue ello tendr.a un signi&icado a$surdo3 estar.amos
dando una rede&inicin de un mtodo )ue (amos a de&inir*
Por otro lado% cuando de&inamos un mtodo como o2erride /a de cumplirse )ue en
alguna clase antecesora Asu clase padre% su clase a$uela% etc*B de la clase en la )ue se /a
realizado la de&inicin del mismo e-ista un mtodo (irtual con el mismo nom$re )ue el
rede&inido* Si no% el compilador in&ormar de error por intento de rede&inicin de
mtodo no e-istente o no (irtual* As. se e(ita )ue por accidente un programador crea
)ue est rede&iniendo un mtodo del )ue no e-ista de&inicin pre(ia o )ue rede&ina un
mtodo )ue el creador de la clase $ase no desee )ue se pueda rede&inir*
Para aclarar mejor el concepto de mtodo (irtual% (amos a mostrar un ejemplo en el )ue
cam$iaremos la de&inicin del mtodo Cumpleaos() en los o$jetos Persona por una
nue(a (ersin en la )ue se muestre un mensaje cada (ez )ue se ejecute% + rede&iniremos
dic/a nue(a (ersin para los o$jetos Trabajador de modo )ue el mensaje mostrado sea
otro* El cdigo de este ejemplo es el )ue se muestra a continuacin3
using System;
class Persona
{
El lenguaje de programacin C# 5ema Q3 Clases
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NF; // Campo de cada objeto Persona que almacena su NF
public virtual void Cumpleaos() // ncrementa en uno de la edad del objeto Persona
{
Console.WriteLine(ncrementada edad de persona);
}
public Persona (string nombre, int edad, string nif) // Constructor de Persona
{
Nombre = nombre;
Edad = edad;
NF = nif;
}
}
class Trabajador: Persona
{
public int Sueldo; // Campo de cada objeto Trabajador que almacena cunto gana
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // nicializamos cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}

public override Cumpleaos()
{
Edad++;
Console.WriteLine(ncrementada edad de persona);
}
public static void Main()
{
Persona p = new Persona("Carlos", 22, "77588261-Z", 100000);
Trabajador t = new Trabajador("Josan", 22, "77588260-Z", 100000);
t.Cumpleaos();
p.Cumpleaos();
}
}
4tese cmo se /a a1adido el modi&icador virtuaI en la de&inicin de Cumpleaos() en la
clase Persona para /a$ilitar la posi$ilidad de )ue dic/o mtodo puede ser rede&inido en
clase /ijas de Persona + cmo se /a a1ado o2erride en la rede&inicin del mismo
dentro de la clase Trabajador para indicar )ue la nue(a de&inicin del mtodo es una
rede&inicin del /eredado de la clase* ?a salida de este programa con&irma )ue la
implementacin de Cumplea3os45 es distinta en cada clase% pues es de la &orma3

;ncrementada edad de tra-a7ador
;ncrementada edad de 5ersona
5am$in es importante se1alar )ue para )ue la rede&inicin sea (lida /a sido necesario
a1adir la part.cula pubIic a la de&inicin del mtodo original% pues si no se inclu+ese se
considerar.a )ue el mtodo slo es accesi$le desde dentro de la clase donde se /a
de&inido% lo )ue no tiene sentido en mtodos (irtuales +a )ue entonces nunca podr.a ser
rede&inido* Ce /ec/o% si se e-clu+ese el modi&icador public el compilador in&ormar.a
El lenguaje de programacin C# 5ema Q3 Clases
de un error ante este a$surdo* Adems% este modi&icador tam$in se /a mantenido en la
rede&inicin de Cumpleaos() por)ue toda rede&inicin de un mtodo (irtual /a de
mantener los mismos modi&icadores de acceso )ue el mtodo original para ser (lida*
CIases abstractas
Kna 6-9;1 9C;349639 es a)uella )ue &orzosamente se /a de deri(ar si se desea )ue se
puedan crear o$jetos de la misma o acceder a sus miem$ros estticos Aesto ,ltimo se
(er ms adelante en este mismo temaB Para de&inir una clase a$stracta se antepone
abstract a su de&inicin% como se muestra en el siguiente ejemplo3
public abstract class A
{
public abstract void F();
}
abstract public class B: A
{
public void G() {}
}
class C: B
{
public override void F()
{}
}
?as clases A + B del ejemplo son a$stractas% + como puede (erse es posi$le com$inar en
cual)uier orden el modi&icador abstract con modi&icadores de acceso*

?a utilidad de las clases a$stractas es )ue pueden contener mtodos para los )ue no se
d directamente una implementacin sino )ue se deje en manos de sus clases /ijas darla*
4o es o$ligatorio )ue las clases a$stractas contengan mtodos de este tipo% pero s. lo es
marcar como a$stracta a toda la )ue tenga alguno* Estos mtodos se de&inen
precediendo su de&inicin del modi&icador abstract + sustitu+endo su cdigo por un
punto + coma A;B% como se muestra en el mtodo F() de la clase A del ejemplo Antese
)ue B tam$in /a de de&inirse como a$stracta por)ue tampoco implementa el mtodo F()
)ue /ereda de AB
L$(iamente% como un mtodo a$stracto no tiene cdigo no es posi$le llamarlo* 8a+ )ue
tener especial cuidado con esto a la /ora de utilizar this para llamar a otros mtodos de
un mismo o$jeto% +a )ue llamar a los a$stractos pro(oca un error al compilar*
;ase )ue todo mtodo de&inido como a$stracto es impl.citamente (irtual% pues si no
ser.a imposi$le rede&inirlo para darle una implementacin en las clases /ijas de la clase
a$stracta donde est de&inido* Por ello es necesario incluir el modi&icador override a la
/ora de darle implementacin + es redundante marcar un mtodo como abstract +
2irtual a la (ez Ade /ec/o% /acerlo pro(oca un error al compilarB
Es posi$le marcar un mtodo como abstract + o2erride a la (ez% lo )ue con(ertir.a al
mtodo en a$stracto para sus clases /ijas + &orzar.a a )ue stas lo tu(iesen )ue
reimplementar si no se )uisiese )ue &uesen clases a$stractas*
El lenguaje de programacin C# 5ema Q3 Clases
La clase primegenia0 "%stem.&b'ect
A/ora )ue sa$emos lo )ue es la /erencia es el momento apropiado para e-plicar )ue
en *4E5 todos los tipos )ue se de&inan /eredan impl.citamente de la clase
System.Object prede&inida en la 0C?% por lo )ue dispondrn de todos los miem$ros de
sta* Por esta razn se dice )ue System.Object es la ra.z de la jerar)u.a de o$jetos de
*4E5*
A continuacin (amos a e-plicar cules son estos mtodos comunes a todos los o$jetos3
pubIic virtuaI booI EquaIs(object o)3 Se usa para comparar el o$jeto so$re el )ue
se aplica con cual)uier otro )ue se le pase como parmetro* Ce(uel(e true si
am$os o$jetos son iguales + +alse en caso contrario*
?a implementacin )ue por de&ecto se /a dado a este mtodo consiste en usar
igualdad por re&erencia para los tipos por re&erencia e igualdad por (alor para los
tipos por (alor* Es decir% si los o$jetos a comparar son de tipos por re&erencia
slo se de(uel(e true si am$os o$jetos apuntan a la misma re&erencia en
memoria dinmica% + si los tipos a comparar son tipos por (alor slo se de(uel(e
true si todos los $its de am$os o$jetos son iguales% aun)ue se almacenen en
posiciones di&erentes de memoria*
Como se (e% el mtodo /a sido de&inido como 2irtual% lo )ue permite )ue los
programadores puedan rede&inirlo para indicar cundo /a de considerarse )ue
son iguales dos o$jetos de tipos de&inidos por ellos* Ce /ec/o% muc/os de los
tipos incluidos en la 0C? cuentan con rede&iniciones de este tipo% como es el
caso de string% )uien a,n siendo un tipo por re&erencia% sus o$jetos se
consideran iguales si apuntan a cadenas )ue sean iguales carcter a carcter
Aaun)ue re&erencien a distintas direcciones de memoria dinmicaB
El siguiente ejemplo muestra cmo /acer una rede&inicin de '6uals45 de
manera )ue aun)ue los o$jetos Persona sean de tipos por re&erencia% se considere
)ue dos Personas son iguales si tienen el mismo 4#W3
public override bool Equals(object o)
{
if (o==null)
return this==null;
else
return (o is Persona) && (this.NF == ((Persona) o).NF);
}
8a+ )ue tener en cuenta )ue es con(eniente )ue toda rede&inicin del mtodo
'6uals45 )ue /agamos cumpla con una serie de propiedades )ue muc/os de los
mtodos incluidos en las distintas clases de la 0C? esperan )ue se cumplan*
Estas propiedades son3
R1@-1I7A7595 3 5odo o$jeto /a de ser igual a s. mismo* Es decir% x.Equals(x)
siempre /a de de(ol(er true*
S7?134L9 3 8a de dar igual el orden en )ue se /aga la comparacin* Es decir%
x.Equals(y) /a de de(ol(er lo mismo )ue y.Equals(x) *
El lenguaje de programacin C# 5ema Q3 Clases
T492;737A7595 3 Si dos o$jetos son iguales + uno de ellos es igual a otro%
entonces el primero tam$in /a de ser igual a ese otro o$jeto* Es decir% si
x.Equals(y) e y.Equals(z) entonces x.Equals(z) *
C.2;7;312679: Siempre )ue el mtodo se apli)ue so$re los mismos o$jetos
/a de de(ol(er el mismo resultado*
T4939?7123. 51 .C>13.; 20-.;: Si uno de los o$jetos comparados es nulo
AnuII)% slo se /a de de(ol(er true si el otro tam$in lo es*
8a+ )ue recalcar )ue el /ec/o de )ue rede&inir Equals() no implica )ue el
operador de igualdad A==B )uede tam$in rede&inido* Ello /a$r.a )ue /acerlo de
independientemente como se indica en el Tema %%: 1ede0ini$i)n de operadores*
pubIic virtuaI int GetHashCode()3 Ce(uel(e un cdigo de dispersin A/as/B )ue
representa de &orma numrica al o$jeto so$re el )ue el mtodo es aplicado*
GetHashCode() suele usarse para tra$ajar con ta$las de dispersin% + se cumple
)ue si dos o$jetos son iguales sus cdigos de dispersin sern iguales% mientras
)ue si son distintos la pro$a$ilidad de )ue sean iguales es .n&ima*
En tanto )ue la $,s)ueda de o$jetos en ta$las de dispersin no se realiza
,nicamente usando la igualdad de o$jetos Amtodo Equals()B sino usando tam$in
la igualdad de cdigos de dispersin% suele ser con(eniente rede&inir
GetHashCode() siempre )ue se rede&ina Equals() Ce /ec/o% si no se /ace el
compilador in&orma de la situacin con un mensaje de a(iso*
pubIic virtuaI string ToString()3 Ce(uel(e una representacin en &orma de cadena
del o$jeto so$re el )ue se el mtodo es aplicado% lo )ue es mu+ ,til para depurar
aplicaciones +a )ue permite mostrar con &acilidad el estado de los o$jetos*
?a implementacin por de&ecto de este mtodo simplemente de(uel(e una
cadena de te-to con el nom$re de la clase a la )ue pertenece el o$jeto so$re el
)ue es aplicado* Sin em$argo% como lo /a$itual suele ser implementar ToString()
en cada nue(a clase )ue es de&ina% a continuacin mostraremos un ejemplo de
cmo rede&inirlo en la clase 4ersona para )ue muestre los (alores de todos los
campos de los o$jetos 4ersona3
public override string ToString()
{
string cadena = ;
cadena += DN = + this.DN + \n;
cadena +=Nombre = + this.Nombre + \n;
cadena +=Edad = + this.Edad + \n;
return cadena;
}
Es de rese1ar el /ec/o de )ue en realidad los )ue /ace el operador de
concatenacin de cadenas A+B para concatenar una cadena con un o$jeto
cual)uiera es con(ertirlo primero en cadena llamando a su mtodo ToString() +
luego realizar la concatenacin de am$as cadenas*
El lenguaje de programacin C# 5ema Q3 Clases
Cel mismo modo% cuando a ConsoIe.WriteLine() + ConsoIe.Write() se les pasa
como parmetro un o$jeto lo )ue /acen es mostrar por la salida estndar el
resultado de con(ertirlo en cadena llamando a su mtodo ToString()U + si se les
pasa como parmetros una cadena seguida de (arios o$jetos lo muestran por la
salida estndar esa cadena pero sustitu+endo en ella toda su$cadena de la &orma
{<nmero>} por el resultado de con(ertir en cadena el parmetro )ue ocupe la
posicin <nmero>' en la lista de (alores de llamada al mtodo*

protected object 7ember%iseClone45: Ce(uel(e una copia ;J9--.D 6.<:
del o$jeto so$re el )ue se aplica* Esta copia es una copia $it a $it del mismo% por
lo )ue el o$jeto resultante de la copia mantendr las mismas re&erencias a otros
)ue tu(iese el o$jeto copiado + toda modi&icacin )ue se /aga a estos o$jetos a
tra(s de la copia a&ectar al o$jeto copiado + (ice(ersa*
Si lo )ue interesa es disponer de una copia ms normal% en la )ue por cada o$jeto
re&erenciado se crease una copia del mismo a la )ue re&erenciase el o$jeto
clonado% entonces el programador /a de escri$ir su propio mtodo clonador pero
puede ser(irse de MemberwiseClone() como $ase con la )ue copiar los campos
)ue no sean de tipos re&erencia*
pubIic System.Type GetType()3 Ce(uel(e un o$jeto de clase System.Type )ue
representa al tipo de dato del o$jeto so$re el )ue el mtodo es aplicado* A tra(s
de los mtodos o&recidos por este o$jeto se puede acceder a metadatos so$re el
mismo como su nom$re% su clase padre% sus miem$ros% etc* ?a e-plicacin de
cmo usar los miem$ros de este o$jeto para o$tener dic/a in&ormacin )ueda
&uera del alcance de este documento +a )ue es mu+ larga + puede ser &cilmente
consultada en la documentacin )ue acompa1a al *4E5 SCD*
protected virtuaI void FinaIize(): Contiene el cdigo )ue se ejecutar siempre )ue
(a+a /a ser destruido alg,n o$jeto del tipo del )ue sea miem$ro* ?a
implementacin dada por de&ecto a !inali1e45 consiste en no /acer nada*
Aun)ue es un mtodo (irtual% en C# no se permite )ue el programador lo
rede&ina e-pl.citamente dado )ue /acerlo es peligroso por razones )ue se
e-plicarn en el Tema 8: Mtodos Aotros lenguajes de *4E5 podr.an permitirloB*
Aparte de los mtodos +a comentados )ue todos los o$jetos /eredan% la clase
System.Object tam$in inclu+e en su de&inicin los siguientes mtodos de tipo3
pubIic static booI EquaIs(object objeto1, object objeto2) ;ersin esttica
del mtodo EquaIs() +a (isto* #ndica si los o$jetos )ue se le pasan como
parmetros son iguales% + para compararlos lo )ue /ace es de(ol(er el
resultado de calcular objeto1.EquaIs(objeto2) compro$ando antes si alguno
de los o$jetos (ale nuII Aslo se de(ol(er.a true slo si el otro tam$in lo esB
L$(iamente si se da una rede&inicin al EquaIs() no esttico% esta tam$in se
aplicar al esttico*
El lenguaje de programacin C# 5ema Q3 Clases
pubIic static booI ReferenceEquaIs(object objeto1, object objeto2) #ndica
si los dos o$jetos )ue se le pasan como parmetro se almacenan en la misma
posicin de memoria dinmica* A tra(s de este mtodo% aun)ue se /a+an
rede&inido Equals() + el operador de igualdad A==B para un cierto tipo por
re&erencia% se podrn seguir realizando comparaciones por re&erencia*entre
o$jetos de ese tipo en tanto )ue rede&inir de Equals() no a&ecta a este mtodo*
Por ejemplo% dada la anterior rede&inicin de Equals() para o$jetos Persona3
Persona p = new Persona(Jos, 22, 83721654-W);
Persona q = new Persona(Antonio, 23, 83721654-W);
Console.WriteLine(p.Equals(q));
Console.WriteLine(Object.Equals(p, q));
Console.WriteLine(Object.ReferenceEquals(p, q));
Console.WriteLine(p == q);
?a salida )ue por pantalla mostrar el cdigo anterior es3
True
True
Galse
Galse
En los primeros casos se de(uel(e true por)ue seg,n la rede&inicin de
Equals() dos personas son iguales si tienen el mismo C4#% como pasa con los
o$jetos p + q* Sin em$argo% en los ,ltimos casos se de(uel(e faIse por)ue
aun)ue am$os o$jetos tienen el mismo C4# cada uno se almacena en la
memoria dinmica en una posicin distinta% )ue es lo )ue comparan
ReferenceEquals() + el operador == Aste ,ltimo slo por de&ectoB
,olimorfismo
Concepto de poIimorfismo
El <.-7?.4@7;?. es otro de los pilares &undamentales de la programacin orientada a
o$jetos* Es la capacidad de almacenar o$jetos de un determinado tipo en (aria$les de
tipos antecesores del primero a costa% claro est% de slo poderse acceder a tra(s de
dic/a (aria$le a los miem$ros comunes a am$os tipos* Sin em$argo% las (ersiones de los
mtodos (irtuales a las )ue se llamar.a a tra(s de esas (aria$les no ser.an las de&inidas
como miem$ros del tipo de dic/as (aria$les% sino las de&inidas en el (erdadero tipo de
los o$jetos )ue almacenan*

A continuacin se muestra un ejemplo de cmo una (aria$le de tipo Persona puede
usarse para almacenar o$jetos de tipo Trabajador* En esos casos el campo Sueldo del
o$jeto re&erenciado por la (aria$le no ser accesi$le% + la (ersin del mtodo
Cumpleaos() a la )ue se podr.a llamar a tra(s de la (aria$le de tipo Persona ser.a la
de&inida en la clase Trabajador% + no la de&inida en Persona3
using System;
class Persona
{
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
El lenguaje de programacin C# 5ema Q3 Clases
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NF; // Campo de cada objeto Persona que almacena su NF
public virtual void Cumpleaos() // ncrementa en uno la edad del objeto Persona
{
Console.WriteLine(ncrementada edad de persona);
}
public Persona (string nombre, int edad, string nif) // Constructor de Persona
{
Nombre = nombre;
Edad = edad;
NF = nif;
}
}
class Trabajador: Persona
{
int Sueldo; // Campo de cada objeto Trabajador que almacena cunto gana
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // nicializamos cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}

public override Cumpleaos()
{
Edad++;
Console.WriteLine("ncrementada edad de trabajador");
}
public static void Main()
{
Persona p = new Trabajador("Josan", 22, "77588260-Z", 100000);
p.Cumpleaos();
// p.Sueldo++; //ERROR: Sueldo no es miembro de Persona
}
}
El mensaje mostrado por pantalla al ejecutar este mtodo con&irma lo antes dic/o
respecto a )ue la (ersin de Cumpleaos() a la )ue se llama% +a )ue es3

;ncrementada edad de tra-a7ador
Mtodos genricos
El polimor&ismo es mu+ ,til +a )ue permite escri$ir mtodos genricos )ue puedan
reci$ir parmetros )ue sean de un determinado tipo o de cual)uiera de sus tipos /ijos*
Es ms% en tanto )ue cmo se (er en el ep.gra&e siguiente% en C# todos los tipos
deri(an impl.citamente del tipo System.Object% podemos escri$ir mtodos )ue admitan
parmetros de cual)uier tipo sin ms )ue de&inirlos como mtodos )ue tomen
parmetros de tipo System.Object* Por ejemplo3
public void MtodoGenrico(object o)
El lenguaje de programacin C# 5ema Q3 Clases
{
// Cdigo del mtodo
}
4tese )ue en (ez de System.Object se /a escrito object% )ue es el nom$re a$re(iado
incluido en C# para /acer re&erencia de manera compacta a un tipo tan &recuentemente
usado como System.Object*
Determinacin de tipo. Operador is
Centro de una rutina polimri&ica )ue% como la del ejemplo anterior% admita parmetros
)ue puedan ser de cual)uier tipo% muc/as (eces es con(eniente poder consultar en el
cdigo de la misma cul es el tipo en concreto del parmetro )ue se /a+a pasado al
mtodo en cada llamada al mismo* Para ello C# o&rece el operador is% cu+a &orma
sinta-is de uso es3
<expresin> is <nombreTipo>
Este operador de(uel(e true en caso de )ue el resultado de e(aluar :e$5resiBn= sea del
tipo cu+o nom$re es <nombreTipo> + faIse en caso contrario
R
* Gracias a ellas podemos
escri$ir mtodos genricos )ue puedan determinar cul es el tipo )ue tienen los
parmetros )ue en cada llamada en concreto se les pasen* L sea% mtodos como3
public void MtodoGenrico(object o)
{
if (o is int) // Si o es de tipo int (entero)...
// ...Cdigo a ejecutar si el objeto o es de tipo int
else if (o is string) // Si no, si o es de tipo string (cadena)...
// ...Cdigo a ejecutar si o es de tipo string
//... dem para otros tipos
}
El $lo)ue if...eIse es una instruccin condicional )ue permite ejecutar un cdigo u otro
en &uncin de si la condicin indicada entre parntesis tras el if es cierta AtrueB o no
AfaIseB Esta instruccin se e-plicar ms detalladamente en el Tema %2: "nstr#$$iones
Acceso a Ia cIase base
8a+ determinadas circunstancias en las )ue cuando rede&inamos un determinado
mtodo nos interese poder acceder al cdigo de la (ersin original* Por ejemplo% por)ue
el cdigo rede&inido )ue (a+amos a escri$ir /aga lo mismo )ue el original + adems
algunas cosas e-tras* En estos casos se podr.a pensar )ue una &orma de conseguir esto
ser.a con(irtiendo el o$jeto actual al tipo del mtodo a rede&inir + entonces llamar as. a
ese mtodo% como por ejemplo en el siguiente cdigo3
using System;
class A
{
public virtual void F()
R
Si la e-presin (ale nuII se de(ol(er faIse% pues este (alor no est asociado a ning,n tipo en concreto*
El lenguaje de programacin C# 5ema Q3 Clases
{
Console.WriteLine(A);
}
}
class B:A
{
public override void F()
{
Console.WriteLine(Antes);
((A) this).F(); // (2)
Console.WriteLine(Despus);
}
public static void Main()
{
B b = new B();
b.F();
}
@
Pues $ien% si ejecutamos el cdigo anterior (eremos )ue la aplicacin nunca termina de
ejecutarse + est constantemente mostrando el mensaje Antes por pantalla* Esto se de$e
a )ue de$ido al polimor&ismo se /a entrado en un $ucle in&inito3 aun)ue usemos el
operador de con(ersin para tratar el o$jeto como si &uese de tipo A% su (erdadero tipo
sigue siendo B% por lo )ue la (ersin de F() a la )ue se llamar en (2) es a la de B de
nuevo% )ue (ol(er a llamarse as. misma una + otra (ez de manera inde&inida*
Para solucionar esto% los dise1adores de C# /an incluido una pala$ra reser(ada llamada
base )ue de(uel(e una re&erencia al o$jeto actual semejante a this pero con la
peculiaridad de )ue los accesos a ella son tratados como si el (erdadero tipo &uese el de
su clase $ase* Ksando base% podr.amos reemplazar el cdigo de la rede&inicin de F() de
ejemplo anterior por3

public override void F()
{
Console.WriteLine(Antes);
base.F();
Console.WriteLine(Despus);
}
Si a/ora ejecutamos el programa (eremos )ue a/ora s. )ue la (ersin de F() en B llama a
la (ersin de F() en A% resultando la siguiente salida por pantalla3
Antes
A
Despus
A la /ora de rede&inir mtodos a$stractos /a+ )ue tener cuidado con una cosa3 desde el
mtodo rede&inidor no es posi$le usar base para /acer re&erencia a mtodos a$stractos
de la clase padre% aun)ue s. para /acer re&erencia a los no a$stractos* Por ejemplo3
abstract class A
{
public abstract void F();
public void G()
El lenguaje de programacin C# 5ema Q3 Clases
{}
}
class B: A
{
public override void F()
{
base.G(); // Correcto
base.F(); // Error, base.F() es abstracto
}
}
Downcasting
Cado )ue una (aria$le de un determinado tipo puede estar en realidad almacenando un
o$jeto )ue sea de alg,n tipo /ijo del tipo de la (aria$le + en ese caso a tra(s de la
(aria$le slo puede accederse a a)uellos miem$ros del (erdadero tipo del o$jeto )ue
sean comunes con miem$ros del tipo de la (aria$le )ue re&erencia al o$jeto% muc/as
(eces nos (a a interesar )ue una (ez )ue dentro de un mtodo genrico /a+amos
determinado cul es el (erdadero tipo de un o$jeto Apor ejemplo% con el operador isB
podamos tratarlo como tal* En estos casos lo )ue /a+ es )ue /acer una con(ersin del
tipo padre al (erdadero tipo del o$jeto% + a esto se le llama 5.D269;372=
Para realizar un do=ncasting una primera posi$ilidad es indicar preceder la e-presin a
con(ertir del tipo en el )ue se la desea con(ertir indicado entre parntesis* Es decir%
siguiendo la siguiente sinta-is3
(<tipoDestino>) <expresinAConvertir>
El resultado de este tipo de e-presin es el o$jeto resultante de con(ertir el resultado de
<expresinAConvertir> a <tipoDestino>* En caso de )ue la con(ersin no se pudiese
realizar se lanzar.a una e-cepcin del tipo prede&inido System.InvaIidCastException
Ltra &orma de realizar el do=ncasting es usando el operador as% )ue se usa as.3
<expresinAConvertir> as <tipoDestino>
?a principal di&erencia de este operador con el anterior es )ue si a/ora la con(ersin no
se pudiese realizar se de(ol(er.a nuII en lugar de lanzarse una e-cepcin* ?a otra
di&erencia es )ue as slo es aplica$le a tipos re&erencia + slo a con(ersiones entre tipos
de una misma jerar)u.a Ade padres a /ijos o (ice(ersaB
?os errores al realizar con(ersiones de este tipo en mtodos genricos se producen
cuando el (alor pasado a la (aria$le genrica no es ni del tipo indicado en <tipoDestino>
ni e-iste ninguna de&inicin de cmo realizar la con(ersin a ese tipo Acmo de&inirla se
(er en el Tema %%: 1ede0ini$i)n de operadoresB*
CIases y mtodos seIIados
El lenguaje de programacin C# 5ema Q3 Clases
Kna 6-9;1 ;1--959 es una clase )ue no puede tener clases /ijas% + para de&inirla $asta
anteponer el modi&icador seaIed a la de&inicin de una clase normal* Por ejemplo3
sealed class ClaseSellada
{
}
Kna utilidad de de&inir una clase como sellada es )ue permite )ue las llamadas a sus
mtodos (irtuales /eredados se realicen tan e&icientemente como si &uesen no (irtuales%
pues al no poder e-istir clases /ijas )ue los rede&inan no puede /a$er polimor&ismo + no
/a+ )ue determinar cul es la (ersin correcta del mtodo a la )ue se /a de llamar*
4tese )ue se /a dic/o mtodos (irtuales /eredados% pues lo )ue no se permite es
de&inir miem$ros (irtuales dentrode este tipo de clases% +a )ue al no poderse /eredarse
de ellas es algo sin sentido en tanto )ue nunca podrin rede&inirse*
A/ora $ien% /a+ )ue tener en cuenta )ue sellar reduce enormemente su capacidad de
reutilizacin% + eso es algo )ue el aumento de e&iciencia o$tenido en las llamadas a sus
mtodos (irtuales no suele compensar* En realidad la principal causa de la inclusin de
estas clases en C# es )ue permiten asegurar )ue ciertas clases cr.ticas nunca podrn
tener clases /ijas* Por ejemplo% para simpli&icar el &uncionamiento del C?> + los
compiladores se /a optado por)ue todos los tipos de datos $sicos e-cepto
System.Object estn sellados% pues as. las operaciones con ellos siempre se realizarn de
la misma &orma al no in&luirles el polimor&ismo*
5ngase en cuenta )ue es a$surdo de&inir simultnemanente una clase como abstract +
seaIed% pues nunca podr.a accederse a la misma al no poderse crear clases /ijas su+as
)ue de&inan sus mtodos a$stractos* Por esta razn% el compilador considera errneo
de&inir una clase con am$os modi&icadores a la (ez*
Aparte de para sellar clases% tam$in se puede usar seaIed como modi&icador en la
rede&inicin de un mtodo para conseguir )ue la nue(a (ersin del mismo )ue se de&ina
deje de ser (irtual + se le puedan aplicar las optimizaciones arri$a comentadas* Kn
ejemplo de esto es el siguiente3
class A
{
public abstract F();
}
class B:A
{
public sealed override F() // F() deja de ser redefinible
{}
}
&cultacin de miembros
8a+ ocasiones en las )ue puede resultar interesante usar la /erencia ,nicamente como
mecanismo de reutilizacin de cdigo pero no necesariamente para reutilizar miem$ros*
Es decir% puede )ue interese /eredar de una clase sin )ue ello impli)ue )ue su clase /ija
/erede sus miem$ros tal cuales sino con ligeras modi&icaciones*
El lenguaje de programacin C# 5ema Q3 Clases
Esto puede mu+ ,til al usar la /erencia para de&inir (ersiones especializadas de clases de
uso genrico* Por ejemplo% los o$jetos de la clase System.CoIIections.ArrayList incluida
en la 0C? pueden almacenar cual)uier n,mero de o$jetos System.Object% )ue al ser la
clase primigenia ello signi&ica )ue pueden almacenar o$jetos de cual)uier tipo* Sin
em$argo% al recuperarlos de este almacn genrico se tiene el pro$lema de )ue los
mtodos )ue para ello se o&recen de(uel(en o$jetos System.Object% lo )ue implicar )ue
muc/as (eces /a+a luego )ue recon(ertirlos a su tipo original mediante do=ncasting
para poder as. usar sus mtodos espec.&icos* En su lugar% si slo se (a a usar un
ArrayList para almacenar o$jetos de un cierto tipo puede resultar ms cmodo usar un
o$jeto de alguna clase deri(ada de ArrayList cu+o mtodo e-tractor de o$jetos oculte al
/eredado de ArrayList + de(uel(a directamente o$jetos de ese tipo*
Para (er ms claramente cmo /acer la ocultacin% (amos a tomar el siguiente ejemplo
donde se deri(a de una clase con un mtodo void F() pero se desea )ue en la clase /ija el
mtodo )ue se tenga sea de la &orma int F()3
class Padre
{
public void F()
{}
}
class Hija:Padre
{
public int F()
{return 1;}
}
Como en C# no se admite )ue en una misma clase /a+an dos mtodos )ue slo se
di&erencien en sus (alores de retorno% puede pensarse )ue el cdigo anterior producir
un error de compilacin* Sin em$argo% esto no es as. sino )ue el compilador lo )ue /ar
ser )uedarse ,nicamente con la (ersin de&inida en la clase /ija + desec/ar la /eredada
de la clase padre* A esto se le conoce como .60-396782 51 ?71?C4. +a )ue /ace
desparacer en la clase /ija el miem$ro /eredado% + cuando al compilar se detecte se
generar el siguiente de a(iso Ase supone )ue clases.cs almacena el cdigo anteirorB3
clases.cs(F#C5%+ ,arning CSCI+ TJe Key,ord ne, is reLuired on
MHi7a.G(%M -ecause it Jides inJerited mem-er M4adre.G(%M

Como generalmente cuando se /ereda interesa )ue la clase /ija comparta los mismos
miem$ros )ue la clase padre A+ si acaso )ue a1ada miem$ros e-traB% el compilador
emite el a(iso anterior para indicar )ue no se est /aciendo lo /a$itual* Si )ueremos
e(itarlo /emos de preceder la de&inicin del mtodo ocultador de la pala$ra reser(ada
new para as. indicar e-pl.ctamente )ue lo )ue )ueremos /acer es ocultar el F() /eredado3
class Padre
{
public void F()
{}
}
class Hija:Padre
{
new public int F()
El lenguaje de programacin C# 5ema Q3 Clases
{return 1;}
}
En realidad la ocultacin de miem$ros no implica los miem$ros ocultados tengan )ue
ser mtodos% sino )ue tam$in pueden ser campos o cual)uiera de los dems tipos de
miem$ro )ue en temas posteriores se (ern* Por ejemplo% puede )ue se desee )ue un
campo X de tipo int est disponi$le en la clase /ija como si &uese de tipo string*
5ampoco implica )ue los miem$ros mtodos ocultados tengan )ue di&erenciarse de los
mtodos ocultadores en su tipo de retorno% sino )ue pueden tener e-ctamente su mismo
tipo de retorno% parmetros + nom$re* 8acer esto puede dar lugar a errores mu+ sutiles
como el incluido en la siguiente (ariante de la clase Trabajador donde en (ez de
rede&inirse Cumpleaos() lo )ue se /ace es ocultarlo al ol(idar incluir el override3

using System;
class Persona
{
public string Nombre; // Campo de cada objeto Persona que almacena su nombre
public int Edad; // Campo de cada objeto Persona que almacena su edad
public string NF; // Campo de cada objeto Persona que almacena su NF
public virtual void Cumpleaos() // ncrementa en uno la edad del objeto Persona
{
Console.WriteLine(ncrementada edad de persona);
}
public Persona (string nombre, int edad, string nif) // Constructor de Persona
{
Nombre = nombre;
Edad = edad;
NF = nif;
}
}
class Trabajador: Persona
{
int Sueldo; // Campo de cada objeto Trabajador que almacena cunto gana
Trabajador(string nombre, int edad, string nif, int sueldo): base(nombre, edad, nif)
{ // nicializamos cada Trabajador en base al constructor de Persona
Sueldo = sueldo;
}

public Cumpleaos()
{
Edad++;
Console.WriteLine("ncrementada edad de trabajador");
}
public static void Main()
{
Persona p = new Trabajador("Josan", 22, "77588260-Z", 100000);
p.Cumpleaos();
// p.Sueldo++; //ERROR: Sueldo no es miembro de Persona
}
El lenguaje de programacin C# 5ema Q3 Clases
}
Al no incluirse override se /a perdido la capacidad de polimori&smo% + ello puede (erse
en )ue la salida )ue a/ora mostrara por pantalla el cdigo3

;ncrementada edad de 5ersona
Errores de este tipo son mu+ sutiles + podr.an ser di&.ciles de detectar* Sin em$argo% en
C# es &cil /acerlo gracias a )ue el compilador emitir el mensaje de a(iso +a (isto por
/a$er /ec/o la ocultacin sin new* Cuando el programador lo (ea podr a1adir new para
suprimirlo si realmente lo )ue )uer.a /acer era ocultar% pero si esa no era su intencin
as. sa$r )ue tiene )ue corregir el cdigo Apor ejemplo% a1adiendo el override ol(idadoB
Como su propio nom$re indica% cuando se rede&ine un mtodo se cam$ia su de&inicin
original + por ello las llamadas al mismo ejecutaran dic/a (ersin aun)ue se /agan a
tra(s de (aria$les de la clase padre )ue almacenen o$jetos de la clase /ija donde se
rede&ini* Sin em$argo% cuando se oculta un mtodo no se cam$ia su de&inicin en la
clase padre sino slo en la clase /ija% por lo )ue las llamadas al mismo realizadas a
tra(s de (aria$les de la clase padre ejecutarn la (ersin de dic/a clase padre + las
realizadas mediante (aria$les de la clase /ija ejecutarn la (ersin de la clase /ija*
En realidad el polimor&ismo + la ocultacin no son conceptos totalmente antagnicos% +
aun)ue no es (lido de&inir mtodos )ue simultnemente cuenten con los modi&icadores
o2erride + new +a )ue un mtodo ocultador es como si &uese la primera (ersin )ue se
/ace del mismo Aluego no puede rede&inirse algo no de&inidoB% s. )ue es posi$le
com$inar new + 2irtual para de&inir mtodos ocultadores rede&ini$les* Por ejemplo3
using System;
class A
{
public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
public override void F() { Console.WriteLine("D.F"); }
}
class Ocultacin
{
public static void Main()
{
A a = new D();
B b = new D();
C c = new D();
D d = new D();
a.F();
El lenguaje de programacin C# 5ema Q3 Clases
b.F();
c.F();
d.F();
}
}
?a salida por pantalla de este programa es3
1.G
1.G
9.G
9.G
Aun)ue el (erdadero tipo de los o$jetos a cu+o mtodo se llama en Main() es D% en las
dos primeras llamadas se llama al F() de B* Esto se de$e a )ue la rede&inicin dada en B
cam$ia la (ersin de F() en A por la su+a propia% pero la ocultacin dada en C /ace )ue
para la rede&inicin )ue posteriormente se da en D se considere )ue la (ersin original
de F() es la dada en C + ello pro(oca )ue no modi&i)ue la (ersiones de dic/o mtodo
dadas en A + B A)ue% por la rede&inicin dada en 0% en am$os casos son la (ersin de BB

Kn truco nemotcnico )ue puede ser ,til para determinar a )u (ersin del mtodo se
llamar en casos complejos como el anterior consiste en considerar )ue el mecanismo
de polimor&ismo &unciona como si $uscase el (erdadero tipo del o$jeto a cu+o mtodo
se llama descendiendo en la jerar)u.a de tipos desde el tipo de la (aria$le so$re la )ue
se aplica el mtodo + de manera )ue si durante dic/o recorrido se llega a alguna (ersin
del mtodo con new se para la $,s)ueda + se )ueda con la (ersin del mismo incluida
en el tipo recorrido justo antes del )ue ten.a el mtodo ocultador*

8a+ )ue tener en cuenta )ue el grado de ocultacin )ue proporcione new depende del
ni(el de accesi$ilidad del mtodo ocultador% de modo )ue si es pri(ado slo ocultar
dentro de la clase donde est de&inido* Por ejemplo% dado3
using System;
class A
{
public virtual void F() // F() es un mtodo redefinible
{
Console.WriteLine(F() de A);
}
}
class B: A
{
new private void F() {} // Oculta la versin de F() de A slo dentro de B
}
class C: B
{
public override void F() // Vlido, pues aqu slo se ve el F() de A
{
base.F();
Console.WriteLine(F() de B);
}
public static void Main()
{
El lenguaje de programacin C# 5ema Q3 Clases
C obj = new C();
obj.F();
}
}
?a salida de este programa por pantalla ser3
G(% de .
G(% de 1
Pese a todo lo comentado% /a+ )ue resaltar )ue la principal utilidad de poder indicar
e-pl.citamente si se desea rede&inir u ocultar cada miem$ro es )ue &acilita enormemente
la resolucin de pro$lemas de A14;7.295. 51 37<.; )ue puedan surgir si al deri(ar una
nue(a clase de otra + a1adirle miem$ros adicionales% posteriormente se la desea
actualizar con una nue(a (ersin de su clase padre pero sta contiene miem$ros )ue
entran en con&lictos con los a1adidos pre(iamente a la clase /ija cuando a,n no e-ist.an
en la clase padre* En lenguajes como Ja(a donde todos los miem$ros son impl.citamente
(irtuales estos da lugar a pro$lemas mu+ gra(es de$idos so$re todo a3
Mue por sus nom$res los nue(os miem$ros de la clase padre entre en con&lictos con
los a1adidos a la clase /ija cuando no e-isit.an* Por ejemplo% si la (ersin inicial de
de la clase padre no contiene ning,n mtodo de nom$re F()% a la clase /ija se le
a1ade void F() + luego en la nue(a (ersin de la clase padre se incorporado int F()% se
producir un error por tenerse en la clase /ija dos mtodos F()
En Ja(a para resol(er este pro$lema una posi$ilidad ser.a pedir al creador de la clase
padre )ue cam$iase el nom$re o parmetros de su mtodo% lo cual no es siempre
posi$le ni con(eniente en tanto )ue ello podr.a trasladar el pro$lema a )ue /u$iesen
deri(ado de dic/a clase antes de (ol(erla a modi&icar* Ltra posi$ilidad ser.a
modi&icar el nom$re o parmetros del mtodo en la clase /ija% lo )ue nue(amente
puede lle(ar a incompati$ilidades si tam$in se /u$iese deri(ado de dic/a clase /ija*
Mue los nue(os miem$ros tengan los mismos nom$res + tipos de parmetros )ue los
incluidos en las clases /ijas + sea o$ligatorio )ue toda rede&inicin )ue se /aga de
ellos siga un cierto es)uema*
Esto es mu+ pro$lemtico en lenguajes como Ja(a donde toda de&inicin de mtodo
con igual nom$re + parmetros )ue alguno de su clase padre es considerado
impl.citamente rede&inicin de ste% +a )ue di&.cilmente en una clase /ija escrita con
anterioridad a la nue(a (ersin de la clase padre se /a$r seguido el es)uema
necesario* Por ello% para resol(erlo /a$r )ue actualizar la clase /ija para )ue lo siga
+ de tal manera )ue los cam$ios )ue se le /agan no a&ecten a sus su$clases% lo )ue
ello puede ser ms o menos di&.cil seg,n las caracter.sticas del es)uema a seguir*
Ltra posi$ilidad ser.a sellar el mtodo en la clase /ija% pero ello recorta la capacidad
de reutilizacin de dic/a clase + slo tiene sentido si no &ue rede&inido en ninguna
su$clase su+a*
En C# todos estos pro$lemas son de &cil solucin +a )ue pueden resol(erse con slo
ocultar los nue(os miem$ros en la clase /ija + seguir tra$ajando como si no e-istiesen*
El lenguaje de programacin C# 5ema Q3 Clases
Miembros de tipo
En realidad% dentro la de&inicin de un tipo de dato no tiene por)u incluirse slo
de&iniciones de miem$ros comunes a todos sus o$jetos% sino tam$in pueden de&inirse
miem$ros ligados al tipo como tal + no a los o$jetos del mismo* Para ello $asta preceder
la de&inicin de ese miem$ro de la pala$ra reser(ada static% como muestra este ejemplo3
class A
{
int x;
static int y;
}
?os o$jetos de clase A slo (an a disponer del campo x% mientras )ue el campo y (a a
pertenecer a la clase A* Por esta razn se dice )ue los miem$ros con modi&icador static
son ?71?C4.; 51 37<. + )ue los no lo tienen son ?71?C4.; 51 .C>13.*
Para acceder a un miem$ro de clase +a no es (lida la sinta-is /asta a/ora (ista de
<objeto>.<miembro>% pues al no estar estos miem$ros ligados a ning,n o$jeto no podr.a
ponerse nada en el campo <objeto>* ?a sinta-is a usar para acceder a estos miem$ros
ser <nombreClase>.<miembro>% como muestra ejemplo donde se asigna el (alor al
miem$ro y de la clase A de&inida ms arri$a3
A.y = 2;
4tese )ue la inclusin de miem$ros de clase rompe con la a&irmacin indicada al
principio del tema en la )ue se dec.a )ue C# es un lenguaje orientado a o$jetos puro en
el )ue todo con lo )ue se tra$aja son o$jetos% +a )ue a los miem$ros de tipo no se les
accede a tra(s de o$jetos sino nom$res de tipos*
Es importante matizar )ue si de&inimos una &uncin como static% entonces el cdigo de
la misma slo podr acceder impl.citamente Asin sinta-is <objeto>.<miembro>B a otros
miem$ros static del tipo de dato al )ue pertenezca* L sea% no se podr acceder a ni a los
miem$ros de o$jeto del tipo en )ue est de&inido ni se podr usar this +a )ue el mtodo
no est asociado a ning,n o$jeto* L sea% este cdigo ser.a in(lido3
int x;
static void ncrementa()
{
x++; //ERROR: x es miembro de objeto e ncrementa() lo es de clase.
}
5am$in /a+ )ue se1alar )ue los mtodos estticos no entran dentro del mecanismo de
rede&iniciones descrito en este mismo tema* Cic/o mecanismo slo es aplica$le a
mtodos de o$jetos% )ue son de )uienes puede declararse (aria$les + por tanto puede
actuar el polimori&smo* Por ello% incluir los modi&icadores virtuaI% override o abstract al
de&inir un mtodo static es considerado errneo por el compiladorU aun)ue ello no
signi&ican )ue los miem$ros static no se /ereden% sino slo tiene sentido rede&inirlos*
Encapsulacin
El lenguaje de programacin C# 5ema Q3 Clases
Va /emos (isto )ue la /erencia + el polimor&ismo eran dos de los pilares &undamentales
en los )ue es apo+a la programacin orientada a o$jetos* Pues $ien% el tercero + ,ltimo
es la 1269<;0-96782% )ue es un mecanismo )ue permite a los dise1adores de tipos de
datos determinar )u miem$ros de los tipos creen pueden ser utilizados por otros
programadores + cules no* ?as principales (entajas )ue ello aporta son3
Se &acilita a los programadores )ue (a+a a usar el tipo de dato Aprogramadores
clientesB el aprendizaje de cmo tra$ajar con l% pues se le pueden ocultar todos los
detalles relati(os a su implementacin interna + slo dejarle (isi$les a)uellos )ue
puedan usar con seguridad* Adems% as. se les e(ita )ue cometan errores por
manipular inadecuadamente miem$ros )ue no de$er.an tocar*
Se &acilita al creador del tipo la posterior modi&icacin del mismo% pues si los
programadores clientes no pueden acceder a los miem$ros no (isi$les% sus
aplicaciones no se (ern a&ectadas si stos cam$ian o se eliminan* Gracias a esto es
posi$le crear inicialmente tipos de datos con un dise1o sencillo aun)ue poco
e&iciente% + si posteriormente es necesariomodi&icarlos para aumentar su e&iciencia%
ello puede /acerse sin a&ectar al cdigo escrito en $ase a la no mejorada de tipo*
?a encapsulacin se consigue a1adiendo ?.57@7695.41; 51 9661;. en las de&iniciones
de miem$ros + tipos de datos* Estos modi&icadores son part.culas )ue se les colocan
delante para indicar desde )u cdigos puede accederse a ellos% entendindose por
acceder el /ec/o de usar su nom$re para cual)uier cosa )ue no sea de&inirlo% como
llamarlo si es una &uncin% leer o escri$ir su (alor si es un campo% crear o$jetos o
/eredar de l si es una clase% etc*
Por de&ecto se considera )ue los miem$ros de un tipo de dato slo son accesi$les desde
cdigo situado dentro de la de&inicin del mismo% aun)ue esto puede cam$iarse
precediendolos de uno los siguientes modi&icadores Aaun)ue algunos de ellos +a se /an
e-plicado a lo largo del tema% a)u. se recogen todos de manera detalladaB al de&inirlos3
public : Puede ser accedido desde cual)uier cdigo*
protected : Cesde una clase slo puede accederse a miem$ros protected de
o$jetos de esa misma clase o de su$clases su+as* As.% en el siguiente cdigo las
instrucciones comentadas con JJ Error no son (lidas por lo escrito junto a ellas3
public class A
{
protected int x;
static void F(A a, B b, C c)
{
a.x = 1; // Ok
b.x = 1; // Ok
c.x = 1; // OK
}
}
public class B: A
{
static void F(A a, B b, C c)
{
//a.x = 1; // Error, ha de accederse a traves de objetos tipo B o C
El lenguaje de programacin C# 5ema Q3 Clases
b.x = 1; // Ok
c.x = 1; // Ok
}
}
public class C: B
{
static void F(A a, B b, C c)
{
//a.x = 1; // Error, ha de accederse a traves de objetos tipo C
//b.x = 1; // Error, ha de accederse a traves de objetos tipo C
c.x = 1; // Ok
}
}
L$(iamente siempre )ue se /erede de una clase se tendr total acceso en la clase
/ija Ze impl.ctiamente sin necesidad de usar la sinta-is <objeto>.<miembro>- a los
miem$ros )ue sta /erede de su clase padre% como muestra el siguiente ejemplo3
using System;
class A
{
protected int x=5;
}
class B:A
{
B()
{
Console.WriteLine(Heredado x={0} de clase A, x);
}
public static void Main()
{
new B();
}
}
Como es de esperar% la salida por pantalla del programa de ejemplo ser3
Heredado $N5 de clase .
pri2ate : Slo puede ser accedido desde el cdigo de la clase a la )ue pertenece*
Es lo considerado por de&ecto*
internal : Slo puede ser accedido desde cdigo perteneciente al ensam$lado
en )ue se /a de&inido*
protected internal : Slo puede ser accedido desde cdigo perteneciente al
ensam$lado en )ue se /a de&inido o desde clases )ue deri(en de la clase donde
se /a de&inido*
Es importante recordar )ue toda rede&inicin de un mtodo (irtual o a$stracto /a de
realizarse manteniendo los mismos modi&icadores )ue tu(iese el mtodo original* Es
decir% no podemos rede&inir un mtodo protegido cam$iando su accesi$ilidad por
p,$lica% pues si el creador de la clase $ase lo de&ini as. por algo ser.a*
El lenguaje de programacin C# 5ema Q3 Clases
>especto a los tipos de datos% por de&ecto se considera )ue son accesi$les slo desde el
mismo ensam$lado en )ue /a sido de&inidos% aun)ue tam$in es posi$le modi&icar esta
consideracin anteponiendo uno de los siguientes modi&icadores a su de&inicin3
public : Es posi$le acceder a la clase desde cual)uier ensam$lado*
internal : Slo es posi$le acceder a la clase desde el ensam$lado donde se
declar* Es lo considerado por de&ecto*
5am$in pueden de&inirse tipos dentro de otros A37<.; 723142.;B En ese caso sern
considerados miem$ros del tipo contenedor dentro de la )ue se /a+an de&inido% por lo
)ue les sern aplica$les todos los modi&icadores (lidos para miem$ros + por de&ecto se
considerar )ue% como con cual)uier miem$ro% son pri(ados* Para acceder a estos tipos
desde cdigo e-terno a su tipo contenedor A+a sea para /eredar de ellos% crear o$jetos
su+os o acceder a sus miem$ros estticosB% adems de necesitarse los permisos de
acceso necesarios seg,n el modi&icador de accesi$ilidad al de&inirlos% /a+ )ue usar la
notacin <nombreTipoContendera>.<nombreTiponterno> como muestra este ejemplo3
class A // No lleva modificador, luego se considera que es internal
{
public class Anterna {} // Si ahora no se pusiese public se considerara private
}
class B:A.Anterna // B deriva de la clase interna Anterna definida dentro de A. Es
{} // vlido porque A.Anterna es pblica
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
TEMA 6: Espacios de nombres
Concepto de espacio de nombres
Cel mismo modo )ue los &ic/eros se organizan en directorios% los tipos de datos se
organizan en 1;<967. 51 2.?C41;*
Por un lado estos espacios permiten tener ms organizados los tipos de datos% lo )ue
&acilita su localizacin* Ce /ec/o% esta es la &orma en )ue se encuentra organizada la
0C?% de modo )ue todas las clases ms com,nmente usadas en cual)uier aplicacin
pertenecen al espacio de nom$res llamado System% las de acceso a $ases de datos en
System.Data% las de realizacin de operaciones de entradaJsalida en System.IO% etc
Por otro lado% los espacios de nom$res tam$in permiten poder usar en un mismo
programa (arias clases con igual nom$re si pertenecen a espacios di&erentes* ?a idea es
)ue cada &a$ricante de&ina sus tipos dentro de un espacio de nom$res propio para )ue
as. no /a+an con&lictos si (arios &a$ricantes de&inen clases con el mismo nom$re + se
)uieren usar a la (ez en un mismo programa* L$(iamente para )ue esto &uncione no /an
de coincidir los nom$res los espacios de cada &a$ricante% + una &orma de conseguirlo es
dndoles el nom$re de la empresa &a$ricante% o su nom$re de dominio en #nternet% etc*
)efinicin de espacios de nombres
Para de&inir un espacio de nom$res se utiliza la siguiente sinta-is3
namespace <nombreEspacio>
{
<tipos>
}
?os tipos )ue se de&inan en <tipos> pasarn a considerase pertenecientes al espacio de
nom$res llamado <nombreEspacio>* Como (eremos ms adelante% aparte de clases esto
tipos pueden ser tam$in inter&aces% estructuras% tipos enumerados + delegados* A
continuacin se muestra un ejemplo en el )ue de&inimos una clase de nom$re
ClaseEjemplo perteneciente a un espacio de nom$res llamado EspacioEjemplo3
namespace EspacioEjemplo
{
class ClaseEjemplo
{}
}
El (erdadero nom$re de una clase% al )ue se denomina 2.?C41 6.?<-139?1231
69-7@7695.% es el nom$re )ue le demos al declararla pre&ijado por la concatenacin de
todos los espacios de nom$res a los )ue pertenece ordenados del ms e-terno al ms
interno + seguido cada uno de ellos por un punto Acarcter .B Por ejemplo% el (erdadero
nom$re de la clase ClaseEjemplo antes de&inida es EspacioEjemplo.ClaseEjemplo* Si no
de&inimos una clase dentro de una de&inicin de espacio de nom$res Xcomo se /a /ec/o
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
en los ejemplos de temas pre(iosX se considera )ue sta pertenece al denominado
1;<967. 51 2.?C41; =-.C9- + su nom$re completamente cali&icado coincidir con el
nom$re )ue le demos al de&inirla**
Aparte de de&iniciones de tipo% tam$in es posi$le incluir como miem$ros de un espacio
de nom$res a otros espacios de nom$res* Es decir% como se muestra el siguiente ejemplo
es posi$le anidar espacios de nom$res3
namespace EspacioEjemplo
{
namespace EspacioEjemplo2
{
class ClaseEjemplo
{}
}
}
A/ora ClaseEjemplo tendr EspacioEjemplo.EspacioEjemplo2.ClaseEjemplo como nom$re
completamente cali&icado* En realidad es posi$le compactar las de&iniciones de espacios
de nom$res anidados usando esta sinta-is de cali&icacin completa para dar el nom$re
del espacio de nom$res a de&inir* Es decir% el ,ltimo ejemplo es e)ui(alente a3
namespace EspacioEjemplo.EspacioEjemplo2
{
class ClaseEjemplo
{}
}
En am$os casos lo )ue se /a de&inido es una clase llamada ClaseEjemplo perteneciente al
espacio de nom$res llamado EspacioEjemplo2 )ue% a su (ez% pertenece al espacio de
nom$res llamado EspacioEjemplo*
!mportacin de espacios de nombres
Sentencia using
En principio% si desde cdigo perteneciente a una clase de&inida en un cierto espacio de
nom$res se desea /acer re&erencia a tipos de&inidos en otros espacios de nom$res% se /a
de re&erir a los mismos usando su nom$re completamente cali&icado* Por ejemplo3
namespace EspacioEjemplo.EspacioEjemplo2
{
class ClaseEjemplo
{}
}
class Principal // Pertenece al espacio de nombres global
{
public static void Main ()
{
EspacioEjemplo.EspacioEjemplo2.ClaseEjemplo c = new
EspacioEjemplo.EspacioEjemplo2.ClaseEjemplo();
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
}
}
Como puede resultar mu+ pesado tener )ue escri$ir nom$res tan largos en cada
re&erencia a tipos as. de&inidos% en C# se /a incluido un mecanismo de importacin de
espacios de nom$res )ue usa la siguiente sinta-is3
using <espacioNombres>;
Este tipo de sentencias siempre /a de aparecer dentro de una de&inicin de espacio de
nom$res antes )ue cual)uier de&inicin de miem$ros de la misma + permiten indicar
cules sern los espacios de nom$res )ue se usarn impl.citamente dentro de ese
espacio de nom$res* A los miem$ros de los espacios de nom$res as. importados se les
podr /acer re&erencia sin tener )ue usar cali&icacin completa% como muestra la
siguiente (ersin del ,ltimo ejemplo3
using EspacioEjemplo.EspacioEjemplo2;
namespace EspacioEjemplo.EspacioEjemplo2
{
class ClaseEjemplo
{}
}
// (1)
class Principal // Pertenece al espacio de nombres global
{
public static void ()
{
// EspacioEjemplo.EspacioEjemplo2. est implcito
ClaseEjemplo c = new ClaseEjemplo();
}
}
4tese )ue la sentencia using no podr.a /a$erse incluido en la zona marcada en el
cdigo como (1) el cdigo por)ue entonces se (iolar.a la regla de )ue todo using /a
aparecer en un espacio de nom$res antes )ue cual)uier de&inicin de miem$ro% +a )ue la
de&inicin del espacio de nom$res EspacioEjemplo.EspacioEjemplo2 es un miem$ro del
espacio de nom$res glo$al* Sin em$argo% el siguiente cdigo si )ue ser.a (lido3
namespace EspacioEjemplo.EspacioEjemplo2
{
class ClaseEjemplo
{}
}
namespace Principal
{
using EspacioEjemplo.EspacioEjemplo2;
class Principal // Pertenece al espacio de nombres global
{
public static void Main()
{
ClaseEjemplo c = new ClaseEjemplo();
}
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
}
}
En este caso el using aparece antes )ue cual)uier otra de&inicin de tipos dentro del
espacio de nom$res en )ue se inclu+e APrincipalB Sin em$argo% a/ora la importacin
/ec/a con el using slo ser (lida dentro de cdigo incluido en ese mismo espacio de
nom$res% mientras )ue en el caso anterior era (lida en todo el &ic/ero al estar incluida
en el espacio de nom$res glo$al*
Si una sentencia using importa miem$ros de igual nom$re )ue miem$ros de&inidos en el
espacio de nom$res donde se inclu+e% el using no se produce error alguno pero se da
pre&erencia a los miem$ros no importados* Kn ejemplo3
namespace N1.N2
{
class A {}
class B {}
}
namespace N3
{
using N1.N2;
class A {}
class C: A {}
}
En este ejemplo C deri(a de N3.A en (ez de N1.N2.A* Si )ueremos )ue ocurra lo
contrario tendremos )ue re&erenciar a N1.N2.A por su nom$re completo al de&inir C o%
como se e-plica a continuacin% usar un 9-79;*
Especificacin de aIias
A,n en el caso de )ue usemos espacios de nom$res distintos para di&erenciar clases con
igual nom$re pero procedentes de distintos &a$ricantes% podr.an darse con&lictos sin
usamos sentencias using para importar los espacios de nom$res de dic/os &a$ricantes +a
)ue entonces al /acerse re&erencia a una de las clases comunes con tan solo su nom$re
simple el compilador no podr determinar a cual de ellas en concreto nos re&erimos*
Por ejemplo% si tenemos una clase de nom$re completamente cali&icado A.Clase% otra de
nom$re B.Clase% + /acemos3
using A;
using B;
class EjemploConflicto: Clase {}
_Cmo sa$r el compilador si lo )ue )ueremos es deri(ar de A.Clase o de B.Clase` En
realidad el compilador no puede determinarlo + producir un error in&ormando de )ue
/a+ una re&erencia am$igua a Clase*
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
Para resol(er am$igaedades de este tipo podr.a /acerse re&erencia a los tipos en
con&licto usando siempre sus nom$res completamente cali&icados% pero ello puede llegar
a ser mu+ &atigoso so$re todo si sus nom$res son mu+ largos* Para solucionar los
con&lictos de nom$res sin tener )ue escri$ir tanto se /a incluido en C# la posi$ilidad de
de&inir 9-79; para cual)uier tipo de dato% )ue son sinnimos para los mismos )ue se
de&inen usando la siguiente sinta-is3
using <alias> = <nombreCompletoTipo>;
Como cual)uier otro using% las de&iniciones de alias slo pueden incluirse al principio
de las de&iniciones de espacios de nom$res + slo tienen (alidez dentro de las mismas*
Ce&iniendo alias distintos para los tipos en con&lictos se resuel(en los pro$lemas de
am$igaedades* Por ejemplo% el pro$lema del ejemplo anterior se podr.a resol(er as.3
using A;
using B;
using ClaseA = A.Clase;
class EjemploConflicto: ClaseA {} // Heredamos de A.Clase
?os alias no tienen por)u ser slo re&erentes a tipos% sino )ue tam$in es posi$le
escri$ir alias de espacios de nom$res como muestra el siguiente ejemplo3
namespace N1.N2
{
class A {}
}
namespace N3
{
using R1 = N1;
using R2 = N1.N2;
class B
{
N1.N2.A a; // Campo de nombre completamente calificado N1.N2.A
R1.N2.A b; // Campo de nombre completamente calificado N1.N2.A
R2.A c; // Campo de nombre completamente calificado N1.N2.A
}
}
Al de&inir alias /a+ )ue tener cuidado con no de&inir en un mismo espacio de nom$res
(arios con igual nom$re o cu+os nom$res coincidan con los de miem$ros de dic/o
espacio de nom$res* 5am$in /a+ )ue tener en cuenta )ue no se pueden de&inir unos
alias en &uncin de otro% por lo )ue cdigos como el siguiente son incorrectos3
namespace N1.N2 {}
namespace N3
{
using R1 = N1;
using R2 = N1.N2;
using R3 = R1.N2; // ERROR: No se puede definir R3 en funcin de R1
}
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
Espacio de nombres distribuidos
Si /acemos (arias de&iniciones de un espacio de nom$res en un mismo &ic/ero o en
di&erentes + se compilan todas juntas% el compilador las &usionar en una sola de&inicin
cu+os miem$ros sern la concatenacin de los miem$ros de&inidos en cada una de las
de&iniciones realizadas* Por ejemplo3
namespace A // (1)
{
class B1 {}
}
namespace A // (2)
{
class B2 {}
}
8acer una de&inicin como la anterior es tratada por el compilador e-actamente igual
)ue si se /u$iese /ec/o3
namespace A
{
class B1 {}
class B2 {}
}
?o mismo ocurrir.a si las de&iniciones marcadas como (1) + (2) se /u$iesen /ec/o en
&ic/eros separados )ue se compilasen conjuntamente*
8a+ )ue tener en cuenta )ue las sentencias using% +a sean de importacin de espacios
de nom$res o de de&inicin de alias% no son consideradas miem$ros de los espacios de
nom$res + por tanto no participan en sus &usiones* As.% el siguiente cdigo es in(lido3
namespace A
{
class ClaseA {}
}
namespace B
{
using A;
}
namespace B
{
// using A;
class Principal: ClaseA {}
}
Este cdigo no es (lido de$ido a )ue aun)ue se importa el espacio de nom$res A al
principio de una de&inicin del espacio de nom$res donde se /a de&inido Principal% no se
importa en la de&inicin en donde se deri(a Principal de A.ClaseA* Para )ue todo
&uncionase a la per&eccin /a$r.a )ue descomentar la l.nea comentada en el ejemplo*
El lenguaje de programacin C# 5ema T3 Espacios de nom$res
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
TEMA 7: VariabIes y tipos de datos
)efinicin de variables
Kna A9479C-1 puede (erse simplemente como un almacn de o$jetos de un determinado
tipo al )ue se le da un cierto nom$re* Por tanto% para de&inir una (aria$le slo /a+ )ue
decir cul ser el nom$re )ue se le dar + cul ser el tipo de datos )ue podr
almacenar% lo )ue se /ace con la la siguiente sinta-is3
<tipoVariable> <nombreVariable>;
Kna (aria$le puede ser de&inida dentro de una de&inicin de clase% en cu+o caso se
corresponder.a con el tipo de miem$ro )ue /asta a/ora /emos denominado 69?<.*
5am$in puede de&inirse como un A9479C-1 -.69- a un mtodo% )ue es una (aria$le
de&inida dentro del cdigo del mtodo a la )ue slo puede accederse desde dentro de
dic/o cdigo* Ltra posi$ilidad es de&inirla como <94M?134. de un mtodo% )ue son
(aria$les )ue almacenan los (alores de llamada al mtodo + )ue% al igual )ue las
(aria$les locales% slo puede ser accedidas desde cdigo u$icado dentro del mtodo* El
siguiente ejemplo muestra como de&inir (aria$les de todos estos casos3
class A
{
int x, z;
int y;
void F(string a, string b)
{
Persona p;
}
}
En este ejemplo las (aria$les x% z e y son campos de tipo int% mientras )ue p es una
(aria$le local de tipo Persona + a + b son parmetros de tipo string* Como se muestra en
el ejemplo% si un mtodo toma (arios parmetros las de&iniciones de stos se separan
mediante comas Acarcter ,B% + si )ueremos de&inir (arios campos o (aria$les locales Ano
(lido para parmetrosB de un mismo tipo podemos incluirlos en una misma de&inicin
inclu+endo en <nombreVariable> sus nom$res separados por comas*
Con la sinta-is de de&inicin de (aria$les anteriormente dada simplemente de&inimos
(aria$les pero no almacenamos ning,n o$jeto inicial en ellas* El compilador dar un
(alor por de&ecto a los campos para los )ue no se indi)ue e-pl.citamente ning,n (alor
seg,n se e-plica en el siguiente apartado* Sin em$argo% a la (aria$les locales no les da
ning,n (alor inicial% pero detecta cual)uier intento de leerlas antes de darles (alor +
produce erores de compilacin en esos casos*
Va /emos (isto )ue para crear o$jetos se utiliza el operador 21D* Por tanto% una &orma
de asignar un (alor a la (aria$le p del ejemplo anterior ser.a as.3
Persona p;
p = new Persona(Jos, 22, 76543876-A );
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
Sin em$argo% C# tam$in proporciona una sinta-is ms sencilla con la )ue podremos
asignar un o$jeto a una (aria$le en el mismo momento se de&ine* Para ello se la /a de
de&inir usando esta otra notacin3
<tipoVariable> <nombreVariable> = <valornicial>;
Asi por ejemplo% la anterior asignacin de (alor a la (aria$le p podr.a reescri$irse de
esta otra &orma ms compacta3
Persona p = new Persona(Jos, 22, 76543876-A);
?a especi&icacin de un (alor inicial tam$in com$inarse con la de&inicin de m,ltiples
(aria$les separadas por comas en una misma l.nea* Por ejemplo% las siguientes
de&iniciones son (lidas3
Persona p1 = new Persona(Jos, 22, 76543876-A), p2 = new Persona(Juan, 21,
87654212-S);
V son tratadas por el compilador de &orma completamente e)ui(alentes a /a$erlas
declarado como3
Persona p1 = new Persona(Jos, 22, 76543876-A);
Persona p2 = new Persona(Juan, 21, 87654212-S);
Tipos de datos b1sicos
?os 37<.; 51 593.; CM;76.; son ciertos tipos de datos tan com,nmente utilizados en la
escritura de aplicaciones )ue en C# se /a incluido una sinta-is especial para tratarlos*
Por ejemplo% para representar n,meros enteros de ! $its con signo se utiliza el tipo de
dato System.Int32 de&inido en la 0C?% aun)ue a la /ora de crear un o$jeto a de este tipo
)ue represente el (alor se usa la siguiente sinta-is3
System.nt32 a = 2;
Como se (e% no se utiliza el operador new para crear o$jeto System.Int32% sino )ue
directamente se indica el literal )ue representa el (alor a crear% con lo )ue la sinta-is
necesaria para crear entero de este tipo se reduce considera$lemente* Es ms% dado lo
&recuente )ue es el uso de este tipo tam$in se /a prede&inido en C# el alias int para el
mismo% por lo )ue la de&inicin de (aria$le anterior )ueda as. de compacta3
int a = 2;
System.Int32 no es el ,nico tipo de dato $sico incluido en C#* En el espacio de
nom$res System se /an incluido todos estos3
T7<. D1;647<6782 B73; R92=. 51 A9-.41; A-79;
S0+te 3!tes con signo R X1R Z 1[ s$+te
0+te 3!tes sin signo R 2 Z QQ $+te
#nt1T Enteros cortos con signo 1T \X!*[TR% !*[T[] s/ort
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
K#nt1T Enteros cortos sin signo 1T \2% TQ*Q!Q] us/ort
#nt! Enteros normales ! \X*1"[*"R!*T"R% *1"[*"R!*T"[] int
K#nt! Enteros normales sin signo ! \2% "*:"*:T[*:Q] uint
#ntT"
Enteros largos T"
\X:*!*![*2!T*RQ"*[[Q*R2R%
:*!*![*2!T*RQ"*[[Q*R2[]
long
K#ntT" Enteros largos sin signo T" \2X1R*""T*[""*2[!*[2:*QQ1*T1Q] ulong
Single >eales con [ d.gitos de precisin ! \1%Qb12
X"Q
X !%"b12
!R
] &loat
Cou$le >eales de 1QX1T d.gitos de precisin T" \Q%2b12
X!"
X 1%[b12
!2R
] dou$le
Cecimal >eales de RX: d.gitos de precisin 1R \1%2b12
XR
X [%:b12
R
] decimal
0oolean ;alores lgicos ! 3401% @9-;1 $ool
C/ar Caracteres Knicode 1T \c^u2222d% c^uWWWWd] c/ar
String Cadenas de caracteres ;aria$le El permitido por la memoria string
L$ject Cual)uier o$jeto ;aria$le Cual)uier o$jeto o$ject
T9C-9 5 : 5ipos de datos $sicos
Pese a su sinta-is especial% en C# los tipos $sicos son tipos del mismo ni(el )ue
cual)uier otro tipo del lenguaje* Es decir% /eredan de System.Object + pueden ser
tratados como o$jetos de dic/a clase por cual)uier mtodo )ue espere un
System.Object% lo )ue es mu+ ,til para el dise1o de rutinas genricas )ue admitan
parmetros de cual)uier tipo + es una (entaja importante de C# &rente a lenguajes
similares como Ja(a donde los tipos $sicos no son considerados o$jetos*
El (alor )ue por de&ecto se da a los campos de tipos $sicos consiste en poner a cero
todo el rea de memoria )ue ocupen* Esto se traduce en )ue los campos de tipos $sicos
numricos se inicializan por de&ecto con el (alor 2% los de tipo booI lo /acen con faIse%
los de tipo char con '\u0000'% + los de tipo string + object con nuII*
A/ora )ue sa$emos cules son los tipos $sicos% es el momento de comentar cules son
los su&ijos )ue admiten los literales numricos para indicar al compilador cul es el tipo
)ue se /a de considerar )ue tiene* Por ejemplo% si tenemos en una clase los mtodos3
public static void F(int x)
{...}
public static void F(long x)
{...}
Ante una llamada como F(100)% _a cul de los mtodos se llamara` Pues $ien% en
principio se considera )ue el tipo de un literal entero es el correspondiente al primero de
estos tipos $sicos )ue permitan almacenarlo3 int% uint% Iong% uIong% por lo )ue en el caso
anterior se llamar.a al primer F() Para llamar al otro podr.a a1adirse el su&ijo L al literal
+ /acer la llamada con F(100L) En la 5a$la T se resumen los posi$les su&ijos (lidos3
S0@7>. T7<. 51- -73149- 12314.
ninguno Primero de3 int, uint, Iong% uIong
L I
:
Primero de3 Iong, uIong
U u Primero de3 int, uint
UL, UI, uL, uI, LU, Lu, IU Iu
uIong
T9C-9 *: Su&ijos de literales enteros
Por su parte% en la 5a$la [ se indican los su&ijos )ue admiten los literales reales son3
:
4o se recomiendad usar el su&ijo I% pues se parece muc/o al n,mero uno* Ce /ec/o% el compilador
produce un mensaje de a(iso si se usa + puede )ue en (ersiones &uturas genere un error*
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
S0@7>. T7<. 51- -73149- 419-
F f
fIoat
ninguno% D d
doubIe
M m decimaI
T9C-9 !: Su&ijos de literales reales
Tablas
TabIas unidimensionaIes
Kna 39C-9 02757?12;7.29- es un tipo especial de (aria$le )ue es capaz de almacenar en
su interior + de manera ordenada uno o (arios datos de un determinado tipo* Para
declarar (aria$les de este tipo especial se usa la siguiente sinta-is3
<tipoDatos>[] <nombreTabla>;
Por ejemplo% una ta$la )ue pueda almacenar o$jetos de tipo int se declara as.3
int[] tabla;
Con esto la ta$la creada no almacenar.a ning,n o$jeto% sino )ue (aldr.a nuII* Si se desea
)ue (erdaderamente almacene o$jetos /a+ )ue indicar cul es el n,mero de o$jetos )ue
podr almacenar% lo )ue puede /acerse usando la siguiente sinta-is al declararla3
<tipoDatos>[] <nombreTabla> = new <tipoDatos>[<nmeroDatos>];
Por ejemplo% una ta$la )ue pueda almacenar 122 o$jetos de tipo int se declara as.3
int[] tabla = new int[100];
Aun)ue tam$in ser.a posi$le de&inir el tama1o de la ta$la de &orma separada a su
declaracin de este modo3
int[] tabla;
tabla = new int[100];
Con esta ,ltima sinta-is es posi$le cam$iar dinmicamente el n,mero de elementos de
una (aria$le ta$la sin ms )ue irle asignando nue(as ta$las* Ello no signi&ica )ue una
ta$la se pueda redimensionar conser(ando los elementos )ue tu(iese antes del cam$io
de tama1o% sino )ue ocurre todo lo contrario3 cuando a una (aria$le ta$la se le asigna
una ta$la de otro tama1o% sus elementos antiguos son so$reescritos por los nue(os*
Si se crea una ta$la con la sinta-is /asta a/ora e-plicada todos sus elementos tendr.an el
(alor por de&ecto de su tipo de dato* Si )ueremos darles otros (alores al declarar la
ta$la% /emos de indicarlos entre lla(es usando esta sinta-is3
<tipoDatos>[] <nombreTabla> = new <tipoDatos>[] {<valores>};
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
8a de especi&icarse tantos <valores> como n,mero de elementos se desee )ue tenga la
ta$la% + si son ms de uno se /an de separar entre s. mediante comas A,B 4tese )ue
a/ora no es necesario indicar el n,mero de elementos de la ta$la Aaun)ue puede /acerseB
si se deseaB% pues el compilador puede deducirlo del n,mero de (alores especi&icados*
Por ejemplo% para declarar una ta$la de cuatro elementos de tipo int con (alores Q%1%"%2
se podr.a /acer lo siguiente3
int[] tabla = new int[] {5,1,4,0};
#ncluso se puede compactar a,n ms la sinta-is declarando la ta$la as.3
int[] tabla = {5,1,4,0};
5am$in podemos crear ta$las cu+o tama1o se pueda esta$lecer dinmicamente a partir
del (alor de cual)uier e-presin )ue produzca un (alor de tipo entero* Por ejemplo% para
crear una ta$la cu+o tama1o sea el (alor indicado por una (aria$le de tipo int Aluego su
(alor ser de tipo enteroB se /ar.a3

int i = 5;
...
int[] tablaDinmica = new int[i];
A la /ora de acceder a los elementos almacenados en una ta$la $asta indicar entre
corc/etes% + a continuacin de la re&erencia a la misma% la posicin )ue ocupe en la ta$la
el elemento al )ue acceder* Cuando se /aga /a+ )ue tener en cuenta )ue en C# las ta$las
se inde-an desde 2% lo )ue signi&ica )ue el primer elemento de la ta$la ocupar su
posicin 2% el segundo ocupar la posicin 1% + as. sucesi(amente para el resto de
elementos* Por ejemplo% aun)ue es ms ine&iciente% la ta$la declarada en el ,ltimo
&ragmento de cdigo de ejemplo tam$in podr.a /a$erse de&inido as.3
int[] tabla = new int[4];
tabla[0] = 5;
tabla[1]++; // Por defecto se inicializ a 0, luego ahora el valor de tabla[1] pasa a ser 1
tabla[2] = tabla[0] tabla[1]; // tabla[2] pasa a valer 4, pues 5-4 = 1
// El contenido de la tabla ser {5,1,4,0}, pues tabla[3] se inicializ por defecto a 0.
8a+ )ue tener cuidado a la /ora de acceder a los elementos de una ta$la +a )ue si se
especi&ica una posicin superior al n,mero de elementos )ue pueda almacenar la ta$la
se producir una e-cepcin de tipo System.OutOfBoundsException* En el Tema %2:
"nstr#$$iones se e-plica )u son las e-cepciones% pero por a/ora $asta considerar )ue
son o$jetos )ue in&orman de situaciones e-cepcionales Ageneralmente erroresB
producidas durante la ejecucin de una aplicacin* Para e(itar este tipo de e-cepciones
puede consultar el (alor del campo
12
de slo lectura Length )ue est asociado a toda
ta$la + contiene el n,mero de elementos de la misma* Por ejemplo% para asignar un [ al
,ltimo elemento de la ta$la anterior se /ar.a3
tabla[tabla.Length 1] = 7; // Se resta 1 porque tabla.Length devuelve 4 pero el ltimo
// elemento de la tabla es tabla[3]
12
Length es en realidad una propiedad% pero por a/ora podemos considerar )ue es campo*
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
TabIas dentadas
Kna 39C-9 5123959 no es ms )ue una ta$la cu+os elementos son a su (ez ta$las%
pudindose as. anidar cual)uier n,mero de ta$las* Para declarar ta$las de este tipo se
usa una sinta-is mu+ similar a la e-plicada para las ta$las unidimensionales solo )ue
a/ora se indican tantos corc/etes como ni(el de anidacin se desee* Por ejemplo% para
crear una ta$la de ta$las de elementos de tipo int &ormada por dos elementos% uno de los
cuales &uese una ta$la de elementos de tipo int &ormada por los elementos de (alores 1%
+ el otro &uese una ta$la de elementos de tipo int + (alores !%"%Q% se puede /acer3
int[][] tablaDentada = new int[2][] {new int[] {1,2}, new int[] {3,4,5}};
Como se indica e-pl.citamente cules son los elementos de la ta$la declarada no /ace
&alta indicar el tama1o de la ta$la% por lo )ue la declaracin anterior es e)ui(alente a3
int[][] tablaDentada = new int[][] {new int[] {1,2}, new int[] {3,4,5}};
Es ms% igual )ue como se (i con las ta$las unidimensionales tam$in es (lido /acer3
int[][] tablaDentada = {new int[] {1,2}, new int[] {3,4,5}};
Si no )uisisemos indicar cules son los elementos de las ta$las componentes% entonces
tendr.amos )ue indicar al menos cul es el n,mero de elementos )ue podrn almacenar
Ase inicializarn con (alores por de&ectoB )uedando3

int[][] tablaDentada = {new int[2], new int[3]};
Si no )ueremos crear las ta$las componentes en el momento de crear la ta$la dentada%
entonces tendremos )ue indicar por lo menos cul es el n,mero de ta$las componentes
posi$les Acada una (aldr.a nuIIB% con lo )ue )uedar.a3
int[][] tablaDentada = new int[2][];
Es importante se1alar )ue no es posi$le especi&icar todas las dimensiones de una ta$la
dentada en su de&inicin si no se indica e-pl.citamente el (alor inicial de stas entre
lla(es* Es decir% esta declaracin es incorrecta3
int[][] tablaDentada = new int[2][5];
Esto se de$e a )ue el tama1o de cada ta$la componente puede ser distinto + con la
sinta-is anterior no se puede decir cul es el tama1o de cada una* Kna opcin /u$iese
sido considerar )ue es Q para todas como se /ace en Ja(a% pero ello no se /a
implementado en C# + /a$r.a )ue declarar la ta$la de% por ejemplo% esta manera3
int[][] tablaDentada = {new int[5], new int[5]);

Winalmente% si slo )ueremos declarar una (aria$le ta$la dentada pero no )ueremos
indicar su n,mero de elementos% Aluego la (aria$le (aldr.a nuIIB% entonces $asta poner3
int[][] tablaDentada;
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
8a+ )ue precisar )ue aun)ue en los ejemplos /asta a/ora presentes se /an escrito
ejemplos $asados en ta$las dentadas de slo dos ni(eles de anidacin% tam$in es
posi$le crear ta$las dentadas de cual)uier n,mero de ni(eles de anidacin* Por ejemplo%
para una ta$la de ta$las de ta$las de enteros de elementos en la )ue el primero &uese
una ta$la dentada &ormada por dos ta$las de Q enteros + el segundo elemento &uese una
ta$la dentada &ormada por una ta$la de " enteros + otra de ! se podr.a de&inir as.3

int[][][] tablaDentada = new int[][][] { new int[][] {new int[5], new int[5]},
new int[][] {new int[4], new int[3]}};
A la /ora de acceder a los elementos de una ta$la dentada lo ,nico )ue /a+ )ue /acer es
indicar entre corc/etes cul es el elemento e-acto de las ta$las componentes al )ue se
desea acceder% indicndose un elemento de cada ni(el de anidacin entre unos corc/etes
di&erentes pero colocndose todas las parejas de corc/etes juntas + ordenadas de la ta$la
ms e-terna a la ms interna* Por ejemplo% para asignar el (alor 12 al elemento cuarto de
la ta$la )ue es elemento primero de la ta$la )ue es elemento segundo de la ta$la dentada
declarada en ,ltimo lugar se /ar.a3
tablaDentada[1][0][3] = 10;
TabIas muItidimensionaIes
Kna 39C-9 ?0-3757?12;7.29- es una ta$la cu+os elementos se encuentran organizando
una estructura de (arias dimensiones* Para de&inir este tipo de ta$las se usa una sinta-is
similar a la usada para declarar ta$las unidimensionales pero separando las di&erentes
dimensiones mediante comas A,B Por ejemplo% una ta$la multidimensional de elementos
de tipo int )ue conste de 1 elementos puede tener sus elementos distri$uidos en dos
dimensiones &ormando una estructura !-" similar a una matriz de la &orma3
1 ! "
Q T [ R
: 12 11 1
Esta ta$la se podr.a declarar as.3
int[,] tablaMultidimensional = new int[3,4] {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
En realidad no es necesario indicar el n,mero de elementos de cada dimensin de la
ta$la +a )ue pueden deducirse de los (alores e-pl.citamente indicados entre lla(es% por
lo )ue la de&inicin anterior es similar a esta3
int[,] tablaMultidimensional = new int[,] {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
#ncluso puede reducirse a,n ms la sinta-is necesaria )uedando tan slo3
int[,] tablaMultidimensional = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
Si no )ueremos indicar e-pl.citamente los elementos de la ta$la al declararla% podemos
o$(iarlos pero a,n as. indicar el tama1o de cada dimensin de la ta$la Aa los elementos
se les dar.a el (alor por de&ecto de su tipo de datoB as.3
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
int[,] tablaMultidimensional = new int[3,4];
5am$in podemos no especi&icar ni si)uiera el n,mero de elementos de la ta$la de esta
&orma AtablaMultidimensional contendr.a a/ora nuIIB3
int[,] tablaMultidimensional;
Aun)ue los ejemplos de ta$las multidimensionales /asta a/ora mostrados son de ta$las
de dos dimensiones% en general tam$in es posi$le crear ta$las de cual)uier n,mero de
dimensiones* Por ejemplo% una ta$la )ue almacene " elementos de tipo int + (alor 2 en
una estructura tridimensional !-"- se declarar.a as.3
int[,,] tablaMultidimensional = new int[3,4,2];
El acceso a los elementos de una ta$la multidimensional es mu+ sencillo3 slo /a+ )ue
indicar los .ndices de la posicin )ue ocupe en la estructura multidimensional el
elemento al )ue se desee acceder* Por ejemplo% para incrementar en una unidad el
elemento )ue ocupe la posicin A1%!%B de la ta$la anterior se /ar.a Ase indiza desde 2B3
tablaMultidimensional[0,2,1]++;
4tese )ue tanto las ta$las dentadas como las ta$las multidimensionales pueden ser
utilizadas tanto para representar estructuras matriciales como para% en general%
representar cual)uier estructura de (arias dimensiones* ?a di&erencia entre am$as son3
Como las ta$las dentadas son ta$las de ta$las% cada uno de sus elementos puede
ser una ta$la de un tama1o di&erente* As.% con las ta$las dentadas podemos
representar matrices en las )ue cada columna tenga un tama1o distinto Apor el
aspecto NaserradoO de este tipo de matrices es por lo )ue se les llama ta$las
dentadasB% mientras )ue usando ta$las multidimensionales slo es posi$le crear
matrices rectangulares o cuadradas* ?as estructuras aserradas pueden simularse
usando matrices multidimensionales con todas sus columnas del tama1o de la
columna ms grande necesaria% aun)ue ello implica desperdiciar muc/a
memoria so$re todo si los tama1os de cada columna son mu+ di&erentes + la
ta$la es grande Ce todos modos% las estructuras ms comunes )ue se usan en la
ma+or.a de aplicaciones suelen ser rectangulares o cuadradas*
?os tiempos )ue se tardan en crear + destruir ta$las dentadas son superiores a
los )ue se tardan en crear + destruir ta$las multidimensionales* Esto se de$e a
)ue las primeras son ta$las de ta$las mientras )ue las segundas son una ,nica
ta$la% Por ejemplo% para crear una ta$la dentada \122]\122] /a+ )ue crear 121
ta$las Ala ta$la dentada ms las 122 ta$las )ue contieneB% mientras )ue para
crear una crear una ta$la $idimensional \122%122] /a+ )ue crear una ,nica ta$la*
?as ta$las dentadas no &orman parte del C?S% por lo )ue no todos los lenguajes
gestionados los tienen por)u admitir* Por ejemplo ;isual 0asic*4E5 no las
admite% por lo )ue al usarlas en miem$ros p,$licos e)ui(ale a perder
interopera$ilidad con estos lenguajes*
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
TabIas mixtas
Kna 39C-9 ?7I39 es simplemente una ta$la &ormada por ta$las multidimensionales +
dentadas com$inadas entre s. de cual)uier manera* Para declarar una ta$la de este tipo
$asta con tan solo com$inar las notaciones +a (istas para las multidimensionales +
dentadas* Por ejemplo% para declarar una ta$la de ta$las multidimensionales cu+os
elementos sean ta$las unidimensionales de enteros se /ar.a lo siguiente3
int[][,][] tablaMixta;
Covarianza de tabIas
?a 6.A94792K9 51 39C-9; es el resultado de lle(ar el polimor&ismo al mundo de las
ta$las* Es decir% es la capacidad de toda ta$la de poder almacenar elementos de clases
/ijas de la clase de elementos )ue pueda almacenar* Por ejemplo% en tanto )ue todas
clases son /ijas de System.Object% la siguiente asignacin es (lida3
string[] tablaCadenas = {Manolo, Paco, Pepe};
object[] tablaObjetos = tablaCadenas;
8a+ )ue tener en cuenta )ue la co(arianza de ta$las slo se aplica a o$jetos de tipos
re&erencia + no a o$jetos de tipos (alor Por ejemplo% la siguiente asignacin no ser.a
(lida en tanto )ue int es un tipo por (alor3
int[] tablaEnteros = {1, 2, 3};
object[] tablaObjetos = tablaEnteros;
La cIase System.Array
En realidad% todas las ta$las )ue de&inamos% sea cual sea el tipo de elementos )ue
contengan% son o$jetos )ue deri(an de System.Array* Es decir% (an a disponer de todos
los miem$ros )ue se /an de&inido para esta clase% entre los )ue son destaca$les3
Length3 Campo
11
de slo lectura )ue in&orma del n,mero total de elementos )ue
contiene la ta$la* Si la ta$la tiene ms de una dimensin o ni(el de anidacin
indica el n,mero de elementos de todas sus dimensiones + ni(eles* Por ejemplo3
int[] tabla = {1,2,3,4};
int[][] tabla2 = {new int[] {1,2}, new int[] {3,4,5}};
int[,] tabla3 = {{1,2},{3,4,5,6}};
Console.WriteLine(tabla.Length); //mprime 4
Console.WriteLine(tabla2.Length); //mprime 5
Console.WriteLine(tabla3.Length); //mprime 6
Rank3 Campo de slo lectura )ue almacena el n,mero de dimensiones de la
ta$la* L$(iamente si la ta$la no es multidimensional (aldr 1* Por ejemplo3
11
En realidad todos los NcamposO descritos en este apartado no son en realidad campos% sino propiedades*
Aun)ue son conceptos di&erentes% por a/ora puede considerarlos como iguales*
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
int[] tabla = {1,2,3,4};
int[][] tabla2 = {new int[] {1,2}, new int[] {3,4,5}};
int[,] tabla3 = {{1,2},{3,4,5,6}};
Console.WriteLine(tabla.Rank); //mprime 1
Console.WriteLine(tabla2.Rank); //mprime 1
Console.WriteLine(tabla3.Rank); //mprime 2
int GetLength(int dimensin)3 6todo )ue de(uel(e el n,mero de elementos de
la dimensin especi&icada* ?as dimensiones se indican empezando a contar
desde cero% por lo )ue si )uiere o$tenerse el n,mero de elementos de la primera
dimensin /a$r )ue usar GetLength(0)% si se )uiere o$tener los de la segunda
/a$r )ue usar GetLength(1)% etc* Por ejemplo3
int[,] tabla = {{1,2}, {3,4,5,6}};
Console.WriteLine(tabla.GetLength(0)); // mprime 2
Console.WriteLine(<gtabla.GetLength(1)); // mprime 4
void CopyTo(Array destino, int posicin)3 Copia todos los elementos de la ta$la
so$re la )ue es aplica en la )ue se le pasa como primer parmetro a partir de la
posicin de la misma indicada como segundo parmetro* Por ejemplo3
int[] tabla1 = {1,2,3,4};
int[] tabla2 = {5,6,7,8};
tabla1.CopyTo(tabla2,0); // A partir de ahora, ambas tablas contienen {1,2,3,4}
Am$as ta$las /an de ser unidimensionales* Por otro lado% + como es o$(io% la
ta$la de destino /a de ser de un tipo )ue pueda almacenar los o$jetos de la ta$la
&uente% el .ndice especi&icado /a de ser (lido Ama+or o igual )ue cero + menor
)ue el tama1o de la ta$la de destinoB + no /a de (aler nuII ninguna* Si no &uese
as.% saltar.an e-cepciones de di(ersos tipos in&ormando del error cometido Aen la
documentacin del SCD puede (er cules son en concretoB
Aparte de los miem$ros a)u. se1alados% de System.Array cuenta con muc/os ms )ue
permiten realizar tareas tan &recuentes como $,s)uedas de elementos% ordenaciones% etc*
Cadenas de te2to
Kna 695129 51 31I3. no es ms )ue una secuencia de caracteres Knicode* En C# se
representan mediante o$jetos del tipo tipo de dato llamado string% )ue no es ms )ue un
alias del tipo System.String incluido en la 0C?*
?as cadenas de te-to suelen crearse a partir literales de cadena o de otras cadenas
pre(iamente creadas* Ejemplos de am$os casos se muestran a continuacin3
string cadena1 = Jos Antonio;
string cadena2 = cadena;
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
En el primer caso se /a creado un o$jeto string )ue representa a la cadena &ormada por
la secuencia de caracteres OosP .ntonio indicada literalmente Antese )ue las comillas
do$les entre las )ue se encierran los literales de cadena no &orman parte del contenido
de la cadena )ue representan sino )ue slo se usan como delimitadores de la mismaB En
el segundo caso la (aria$le cadena2 creada se genera a partir de la (aria$le cadena1 +a
e-istente% por lo )ue am$as (aria$les apuntarn al mismo o$jeto en memoria*
8a+ )ue tener en cuenta )ue el tipo string es un tipo re&erencia% por lo )ue en principio
la comparacin entre o$jetos de este tipo de$er.a comparar sus direcciones de memoria
como pasa con cual)uier tipo re&erencia* Sin em$argo% si ejecutamos el siguiente cdigo
(eremos )ue esto no ocurre en el caso de las cadenas3
using System;
public class gualdadCadenas
{
public static void Main()
{
string cadena1 = Jos Antonio;
string cadena2 = String.Copy(cadena1);
Console.WriteLine(cadena1==cadena2);
}
}
El mtodo Copy() de la clase String usado de(uel(e una copia del o$jeto )ue se le pasa
como parmetro* Por tanto% al ser o$jetos di&erentes se almacenarn en posiciones
distintas de memoria + al compararlos de$er.a de(ol(erse faIse como pasa con cual)uier
tipo re&erencia* Sin em$argo% si ejecuta el programa (er )ue lo )ue se o$tiene es
precisamente lo contrario3 true* Esto se de$e a )ue para /acer para /acer ms intuiti(o el
tra$ajo con cadenas% en C# se /a modi&icado el operador de igualdad para )ue cuando se
apli)ue entre cadenas se considere )ue sus operandos son iguales slo si son
le-icogr&icamente e)ui(alentes + no si re&erencian al mismo o$jeto en memoria*
Adems% esta comparacin se /ace teniendo en cuenta la capitalizacin usada% por lo
)ue Hola==HOLA Hola==hola de(ol(ern faIse +a )ue contienen las mismas letras
pero con distinta capitalizacin*
Si se )uisiese comparar cadenas por re&erencia /a$r.a )ue optar por una de estas dos
opciones3 compararlas con Object.ReferenceEquaIs() o con(ertirlas en objects + luego
compararlas con == Por ejemplo3

Console.WriteLine(Object.ReferecenceEquals(cadena1, cadena2));
Console.WriteLine( (object) cadena1 == (object) cadena2);
A/ora s. )ue lo )ue se comparan son las direcciones de los o$jetos )ue representan a las
cadenas en memoria% por lo )ue la salida )ue se mostrar por pantalla es3
Galse
Galse
8a+ )ue se1alar una cosa% + es )ue aun)ue en principio el siguiente cdigo de$er.a
mostrar la misma salida por pantalla )ue el anterior +a )ue las cadenas comparadas se
de$er.an corresponder a o$jetos )ue aun)ue sean le-icogr&icamente e)ui(alentes se
almacenan en posiciones di&erentes en memoria3
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
using System;
public class gualdadCadenas2
{
public static void Main()
{
string cadena1 = Jos Antonio;
string cadena2 = Jos Antonio;
Console.WriteLine(Object.ReferenceEquals(cadena1, cadena2));
Console.WriteLine( ((object) cadena1) == ((object) cadena2));
}
}
Si lo ejecutamos (eremos )ue la salida o$tenida es justamente la contraria3
True
True
Esto se de$e a )ue el compilador /a detectado )ue am$os literales de cadena son
le-icogr&icamente e)ui(alentes + /a decidido )ue para a/orra memoria lo mejor es
almacenar en memoria una ,nica copia de la cadena )ue representan + /acer )ue am$as
(aria$les apunten a esa copia com,n* Esto (a a a&ectar a la &orma en )ue es posi$le
manipular las cadenas como se e-plicar ms adelante*
Al igual )ue el signi&icado del operador == /a sido especialmente modi&icado para
tra$ajar con cadenas% lo mismo ocurre con el operador $inario +* En este caso% cuando se
aplica entre dos cadenas o una cadena + un carcter lo )ue /ace es de(ol(er una nue(a
cadena con el resultado de concatenar sus operandos* As. por ejemplo% en el siguiente
cdigo las dos (aria$les creadas almacenarn la cadena Hola Mundo3
public class Concatenacin
{
public static void Main()
{
string cadena = Hola + Mundo;
string cadena2 = Hola Mund + 'o';
}
}
Por otro lado% el acceso a las cadenas se /ace de manera similar a como si de ta$las de
caracteres se tratase3 su NcampoO Length almacenar el n,mero de caracteres )ue la
&orman + para acceder a sus elementos se utiliza el operador []* Por ejemplo% el siguiente
cdigo muestra por pantalla cada carcter de la cadena Hola en una l.nea di&erente3
using System;
public class AccesoCadenas
{
public static void Main()
{
string cadena = Hola;
Console.WriteLine(cadena[0]);
Console.WriteLine(cadena[1]);
Console.WriteLine(cadena[2]);
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
Console.WriteLine(cadena[3]);
}
}
Sin em$argo% /a+ )ue se1alar una di&erencia importante respecto a la &orma en )ue se
accede a las ta$las3 las cadenas son inmuta$les% lo )ue signi&ica )ue no es posi$le
modi&icar los caracteres )ue las &orman* Esto se de$e a )ue el compilador comparte en
memoria las re&erencias a literales de cadena le-icogr&icamente e)ui(alentes para as.
a/orrar memoria% + si se permitiese modi&icarlos los cam$ios )ue se /iciesen a tra(s de
una (aria$le a una cadena compartida a&ectar.an al resto de (aria$les )ue la compartan%
lo )ue podr.a causar errores di&.ciles de detectar* Por tanto% /acer esto es incorrecto3
string cadena = Hola;
cadena[0]=A; //Error: No se pueden modificar las cadenas
Sin em$argo% el /ec/o de )ue no se puedan modi&icar las cadenas no signi&ica )ue no se
puedan cam$iar los o$jetos almacenados en las (aria$les de tipo string*Por ejemplo% el
siguiente cdigo es (lido3
String cad = Hola;
cad = Adios; // Correcto, pues no se modifica la cadena almacenada en cad
// sino que se hace que cad pase a almacenar otra cadena distinta..

Si se desea tra$ajar con cadenas modi&ica$les puede usarse Sytem.Text.StringBuiIder%
)ue &unciona de manera similar a string pero permite la modi&icacin de sus cadenas en
tanto )ue estas no se comparten en memoria* Para crear o$jetos de este tipo $asta pasar
como parmetro de su constructor el o$jeto string )ue contiene la cadena a representar
mediante un StringBuiIder% + para con(ertir un StringBuiIder en String siempre puede
usarse su mtodo ToString() /eredado de System.Object* Por ejemplo3
using System.Text;
using System;
public class ModificacinCadenas
{
public static void Main()
{
StringBuilder cadena = new StringBuilder(Pelas);
String cadenanmutable;
cadena[0] = 'V';
Console.WriteLine(cadena); // Muestra Velas
cadenanmutable = cadena.ToString();
Console.WriteLine(cadenanmutable); // Muestra Velas
}
}
Aparte de los mtodos +a (istos% en la clase System.String se de&inen muc/os otros
mtodos aplica$les a cual)uier cadena + )ue permiten manipularla* ?os principales son3
int IndexOf(string subcadena)3 #ndica cul es el .ndice de la primera aparicin de la
subcadena indicada dentro de la cadena so$re la )ue se aplica* ?a $,s)ueda de dic/a
su$cadena se realiza desde el principio de la cadena% pero es posi$le indicar en un
segundo parmetro opcional de tipo int cul es el .ndice de la misma a partir del )ue
se desea empezar a $uscar* Cel mismo modo% la $,s)ueda aca$a al llegar al &inal de
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
la cadena so$re la )ue se $usca% pero pasando un tercer parmetro opcional de tipo
int es posi$le indicar alg,n .ndice anterior donde terminarla*
4tese )ue es un mtodo mu+ ,til para sa$er si una cadena contiene o no alguna
su$cadena determinada% pues slo si no la encuentra de(uel(e un -1*
int LastIndexOf(string subcadena)3 Wunciona de &orma similar a IndexOf() slo )ue
de(uel(e la posicin de la ,ltima aparicin de la subcadena $uscada en lugar de
de(ol(er la de la primera*
string Insert(int posicin, string subcadena)3 Ce(uel(e la cadena resultante de
insertar la subcadena indicada en la posicin especi&icada de la cadena so$re la )ue
se aplica*
string Remove(int posicin, int nmero)3 Ce(uel(e la cadena resultante de eliminar
el nmero de caracteres indicado )ue /u$iese en la cadena so$re al )ue se aplica a
partir de la posicin especi&icada*
string RepIace(string aSustituir, string sustitua)3 Ce(uel(e la cadena resultante de
sustituir en la cadena so$re la )ue se aplica toda aparacin de la cadena aSustituir
indicada por la cadena sustituta especi&icada como segundo parmetro*
string Substring(int posicin, int nmero)3 Ce(uel(e la su$cadena de la cadena so$re
la )ue se aplica )ue comienza en la posicin indicada + tiene el nmero de caracteres
especi&icados* Si no se indica dic/o n,mero se de(uel(e la su$cadena )ue (a desde
la posicin indicada /asta el &inal de la cadena*
string ToUpper() + string ToLower()3 Ce(uel(en% respecti(amente% la cadena )ue
resulte de con(ertir a ma+,sculas o min,sculas la cadena so$re la )ue se aplican*
Es preciso incidir en )ue aun)ue /a+an mtodos de insercin% reemplazo o eliminacin
de caracteres )ue puedan dar la sensacin de )ue es posi$le modi&icar el contenido de
una cadena% en realidad las cadenas son inmuta$les + dic/o mtodos lo )ue /acen es
de(ol(er una nue(a cadena con el contenido correspondiente a /a$er e&ectuado las
operaciones de modi&iacin solicitadas so$re la cadena a la )ue se aplican* Por ello% las
cadenas so$re las )ue se aplican )uedan intactas como muestra el siguiente ejemplo3
Using System;
public class Ejemplonmutabilidad
{
public static void Main()
{
string cadena1=Hola;
string cadena2=cadena1.Remove(0,1);
Console.WriteLine(cadena1);
Console.WriteLine(cadena2);
}
}
?a salida por pantalla de este ejemplo demuestra lo antes dic/o% pues es3
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
Hola
ola
Como se (e% tras el Remove() la cadena1 permance intacta + el contenido de cadena2 es
el )ue de$er.a tener cadena1 si se le /u$iese eliminado su primer carcter*
Constantes
Kna 6.2;39231 es una (aria$le cu+o (alor puede determinar el compilador durante la
compilacin + puede aplicar optimizaciones deri(adas de ello* Para )ue esto sea posi$le
se /a de cumplir )ue el (alor de una constante no pueda cam$iar durante la ejecucin%
por lo )ue el compilador in&ormar con un error de todo intento de modi&icar el (alor
inicial de una constante* ?as constantes se de&inen como (aria$les normales pero
precediendo el nom$re de su tipo del modi&icador const + dndoles siempre un (alor
inicial al declararlas* L sea% con esta sinta-is3
const <tipoConstante> <nombreConstante> = <valor>;
As.% ejemplos de de&inicin de constantes es el siguiente3
const int a = 123;
const int b = a + 125;
Cadas estas de&iniciones de constantes% lo )ue /ar el compilador ser sustituir en el
cdigo generado todas las re&erencias a las constantes a + b por los (alores 1! + "R
respecti(amente% por lo )ue el cdigo generado ser ms e&iciente +a )ue no incluir el
acceso + clculo de los (alores de a + b* 4tese )ue puede /acer esto por)ue en el
cdigo se indica e-pl.citamente cual es el (alor )ue siempre tendr a +% al ser este un
(alor &ijo% puede deducir cul ser el (alor )ue siempre tendr b* Para )ue el compilador
pueda /acer estos clculos se /a de cumplir )ue el (alor )ue se asigne a las constantes
en su declaracin sea una e-presin constante* Por ejemplo% el siguiente cdigo no es
(lido en tanto )ue el (alor de x no es constante3
int x = 123; // x es una variable normal, no una constante
const int y = x +123; // Error: x no tiene porqu tener valor constante (aunque aqu lo tenga)
Ce$ido a la necesidad de )ue el (alor dado a una constante sea precisamente constante%
no tiene muc/o sentido crear constantes de tipos de datos no $sicos% pues a no ser )ue
(algan nuII sus (alores no se pueden determinar durante la compilacin sino ,nicamente
tras la ejecucin de su constructor* ?a ,nica e-cepcin a esta regla son los tipos
enumerados% cu+os (alores se pueden determinar al compilar como se e-plicar cuando
los (eamos en el Tema %*: En#mera$iones
5odas las constantes son impl.citamente estticas% por lo se considera errneo incluir el
modi&icador static en su de&inicin al no tener sentido /acerlo* Ce /ec/o% para leer su
(alor desde cdigos e-ternos a la de&inicin de la clase donde est de&inida la constante%
/a$r )ue usar la sinta-is <nombreClase>.<nombreConstante> t.pica de los campos static*
Por ,ltimo% /a+ )ue tener en cuenta )ue una (aria$le slo puede ser de&inida como
constante si se es una (aria$le local o un campo% pero no si es un parmetro*
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
3ariables de slo lectura
Cado )ue /a+ ciertos casos en los )ue resulta interesante disponer de la capacidad de
slo lectura )ue tienen las constantes pero no es posi$le usarlas de$ido a las
restricciones )ue /a+ impuestas so$re su uso% en C# tam$in se da la posi$ilidad de
de&inir (aria$les )ue slo puedan ser le.das* Para ello se usa la siguiente sinta-is3
readonIy <tipoConstante> <nombreConstante> - <valor>;
Estas (aria$les superan la ma+or.a de las limitaciones de las constantes* Por ejemplo3
4o es o$ligatorio darles un (alor al de&inirlas% sino )ue puede drseles en el
constructor* A/ora $ien% una (ez dado un (alor a una (aria$le readonIy +a no es
posi$le (ol(erlo a modi&icar* Si no se le da ning,n (alor ni en su constructor ni
en su de&inicin tomar el (alor por de&ecto correspondiente a su tipo de dato*
4o tienen por)u almacenar (alores constantes% sino )ue el (alor )ue almacenen
puede calcularse durante la ejecucin de la aplicacin*
4o tienen por)u de&inirse como estticas% aun)ue si se desea puede /acerse*
Su (alor se determina durante la ejecucin de la aplicacin% lo )ue permite la
actualizacin de cdigos cliente sin necesidad de recompilar* Por ejemplo% dado3
namespace Programa1
{
public class Utilidad
{
public static readonly int X = 1;
}
}
namespace Programa2
{
class Test
{
public static void Main() {
System.Console.WriteLine(Programa1.Utilidad.X);
}
}
}
En principio% la ejecucin de este programa producir el (alor 1* Sin em$argo% si
cada espacio de nom$res se compilan en mdulos de cdigo separados )ue luego
se enlazan dinmicamete + cam$iamos el (alor de X% slo tendremos )ue
recompilar el mdulo donde est de&inido Programa1.Utilidad + Programa2.Test
podr ejecutarse usando el nue(o (alor de X sin necesidad de recompilalo*
Sin em$argo% pese a las (entajas )ue las (aria$les de slo lectura o&recen
respecto a las constantes% tienen dos incon(enientes respecto a stas3 slo
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
pueden de&inirse como campos Ano como (aria$les localesB + con ellas no es
posi$le realizar las optimizaciones de cdigo comentadas para las constantes*
&rden de inicializacin de variables
Para deducir el orden en )ue se inicializarn las (aria$les de un tipo de dato $asta sa$er
cul es el momento en )ue se inicializa cada una + cuando se llama a los constructores3
?os 69?<.; 1;3M376.; slo se inicializan la primera (ez )ue se accede al tipo al
)ue pertenecen% pero no en sucesi(os accesos* Estos accesos pueden ser tanto
para crear o$jetos de dic/o tipo como para acceder a sus miem$ros estticos* ?a
inicializacin se /ace de modo )ue en primer lugar se d a cada (aria$le el (alor
por de&ecto correspondiente a su tipo% luego se d a cada una el (alor inicial
especi&icado al de&inirlas% + por ,ltimo se llame al constructor del tipo* Kn
constructor de tipo es similar a un constructor normal slo )ue en su cdigo
,nicamente puede accederse a miem$ros static Ase (er en el Tema 8: MtodosB
?os 69?<.; 2. 1;3M376.; se inicializan cada (ez )ue se crea un o$jeto del tipo
de dato al )ue pertenecen* ?a inicializacin se /ace del mismo modo )ue en el
caso de los campos estticos% + una (ez terminada se pasa a ejecutar el cdigo
del constructor especi&icado al crear el o$jeto* En caso de )ue la creacin del
o$jeto sea el primer acceso )ue se /aga al tipo de dato del mismo% entonces
primero se inicializarn los campos estticos + luego los no estticos*
?os <94M?134.; se inicializan en cada llamada al mtodo al )ue pertenecen con
los (alores especi&icados al llamarlo*
?as A9479C-1; -.69-1; se inicializan en cada llamada al mtodo al cual
pertenecen pero tras /a$erse inicializado los parmetros de&inidos para el
mismo* Si no se les da (alor inicial no toman ninguno por de&ecto%
considerndose errneo todo acceso de lectura )ue se /aga a las mismas
mientras no se les escri$a alg,n (alor*
8a+ )ue tener en cuenta )ue al de&inirse campos estticos pueden /acerse de&iniciones
c.clicas en las )ue el (alor de unos campos dependa del de otros + el (alor de los
segundos dependa del de los primeros* Por ejemplo3
class ReferenciasCruzadas
{
static int a = b + 1;
static int b = a + 1;
public static void Main()
{
System.Console.WriteLine("a = {0}, b = {1}", a, b);
}
}
El lenguaje de programacin C# 5ema [3 ;aria$les + tipos de datos
Esto slo es posi$le /acerlo al de&inir campos estticos + no entre campos no estticas o
(aria$les locales% +a )ue no se puede inicializar campos no estticos en &uncin del
(alor de otros miem$ros no estticos del mismo o$jeto por)ue el o$jeto a,n no estar.a
incializados% + no se puede inicializar (aria$les locales en &uncin del (alor de otras
(aria$les locales de&inidas ms adelante por)ue no se pueden leer (aria$les no
inicializadas* Adems% aun)ue las constantes sean impl.citamente estticas tampoco
puede /acerse de&iniciones c.clicas entre constantes*
En primer lugar% /a+ )ue se1alar )ue escri$ir un cdigo como el del ejemplo anterior no
es un $uen /$ito de programacin +a )ue di&iculta innecesariamente la legi$ilidad del
programa* A,n as.% C# admite este tipo de cdigos + para determinar el (alor con )ue se
inicializarn $asta tener en cuenta )ue siempre se inicializan primero todos los campos
con sus (alores por de&ecto + luego se inicializan a)uellos )ue tengan (alores iniciales
con dic/os (alores iniciales + en el mismo orden en )ue aparezcan en el cdigo &uente*
Ce este modo% la salida del programa de ejemplo anterior ser3
a N C# - N D
4tese )ue lo )ue se /a /ec/o es inicializar primero a + b con sus (alores por de&ecto A2
en este casoB% luego calcular el (alor &inal de a + luego calcular el (alor &inal de b* Como
b (ale 2 cuando se calcula el (alor &inal de a% entonces el (alor &inal de a es 1U + como a
(ale 1 cuando se calcula el (alor &inal de b% entonces el (alor &inal de b es *
El lenguaje de programacin C# 5ema R3 6todos
TEMA 8: Mtodos
Concepto de m/todo
Kn ?N3.5. es un conjunto de instrucciones a las )ue se les da un determinado nom$re
de tal manera )ue sea posi$le ejecutarlas en cual)uier momento sin tenerlas )ue
reescri$ir sino usando slo su nom$re* A estas instrucciones se les denomina 6014<. del
mtodo% + a su ejecucin a tra(s de su nom$re se le denomina --9?959 al mtodo*
?a ejecucin de las instrucciones de un mtodo puede producir como resultado un
o$jeto de cual)uier tipo* A este o$jeto se le llama A9-.4 51 413.42. del mtodo + es
completamente opcional% pudindose escri$ir mtodos )ue no de(uel(an ninguno*
?a ejecucin de las instrucciones de un mtodo puede depender del (alor de unas
(aria$les especiales denominadas <94M?134.; del mtodo% de manera )ue en &uncin
del (alor )ue se d a estas (aria$les en cada llamada la ejecucin del mtodo se pueda
realizar de una u otra &orma + podr producir uno u otro (alor de retorno*
Al conjunto &ormado por el nom$re de un mtodo + el n,mero + tipo de sus parmetros
se le conoce como ;7=293049 del mtodo* ?a signatura de un mtodo es lo )ue
(erdaderamente lo identi&ica% de modo )ue es posi$le de&inir en un mismo tipo (arios
mtodos con idntico nom$re siempre + cuando tengan distintos parmetros* Cuando
esto ocurre se dice )ue el mtodo )ue tiene ese nom$re est ;.C41694=95.*
)efinicin de m/todos
Para de&inir un mtodo /a+ )ue indicar tanto cules son las instrucciones )ue &orman su
cuerpo como cul es el nom$re )ue se le dar% cul es el tipo de o$jeto )ue puede
de(ol(er + cules son los parmetros )ue puede tomar* Esto se indican de&inindolo as.3
<tipoRetorno> <nombreMtodo>(<parmetros>)
{
<cuerpo>
}
En <tipoRetorno> se indica cul es el tipo de dato del o$jeto )ue el mtodo de(uel(e% + si
no de(uel(e ninguno se /a de escri$ir A.75 en su lugar*
Como nom$re del mtodo se puede poner en <nombreMtodo> cual)uier identi&icador
(lido* Como se (er ms adelante en el Tema %5: "nter0a$es% tam$in es posi$le incluir
en <nombreMtodo> in&ormacin de e-plicitacin de implementacin de inter&az% pero
por a/ora podemos considerar )ue siempre ser un identi&icador*
Aun)ue es posi$le escri$ir mtodos )ue no tomen parmetros% si un mtodo los toma se
/a de indicar en <parmetros> cul es el nom$re + tipo de cada uno de ellos%
separndolos con comas si son ms de uno + siguiendo la sinta-is )ue ms adelante en
este mismo tema es e-plica*
El lenguaje de programacin C# 5ema R3 6todos
El <cuerpo> del mtodo tam$in es opcional% pero si el mtodo retorna alg,n tipo de
o$jeto entonces /a de incluir al menos una instruccin return )ue indi)ue cul es el
o$jeto a de(ol(er*
?a sinta-is anteriormente (ista no es la )ue se usa para de&inir ?N3.5.; 9C;34963.;*
Como +a se (io en el Tema 5: Clases% en esos casos lo )ue se /ace es sustituir el cuerpo
del mtodo + las lla(es )ue lo encierran por un simple punto + coma A;B 6s adelante en
este tema (eremos )ue eso es tam$in lo )ue se /ace para de&inir ?N3.5.; 1I3142.;*
A continuacin se muestra un ejemplo de cmo de&inir un mtodo de nom$re Saluda
cu+o cuerpo consista en escri$ir en la consola el mensaje Hola Mundo" + )ue de(uel(a
un o$jeto int de (alor 13
int Saluda()
{
Console.WriteLine(Hola Mundo);
return 1;
}
Llamada a m/todos
?a &orma en )ue se puede llamar a un mtodo depende del tipo de mtodo del )ue se
trate* Si es un ?N3.5. 51 .C>13. Amtodo no estticoB se /a de usar la notacin3
<objeto>.<nombreMtodo>(<valoresarmetros>)
El <objeto> indicado puede ser directamente una (aria$le del tipo de datos al )ue
pertenezca el mtodo o puede ser una e-presin )ue produzca como resultado una
(aria$le de ese tipo Arecordemos )ue% de$ido a la /erencia% el tipo del <objeto> puede ser
un su$tipo del tipo donde realmente se /a+a de&inido el mtodoBU pero si desde cdigo
de alg,n mtodo de un o$jeto se desea llamar a otro mtodo de ese mismo o$jeto%
entonces se /a de dar el (alor this a <objeto>*
En caso de )ue sea un ?N3.5. 51 37<. Amtodo estticoB% entones se /a de usar3
<tipo>.<nombreMtodo>(<valoresParmetros>)
A/ora en <tipo> /a de indicarse el tipo donde se /a+a de&inido el mtodo o alg,n su$tipo
su+o* Sin em$argo% si el mtodo pertenece al mismo tipo )ue el cdigo )ue lo llama
entonces se puede usar la notacin a$re(iada3
<nombreMtodo>(<valoresParmetros>)

El &ormato en )ue se pasen los (alores a cada parmetro en <valoresParmetros> a
a)uellos mtodos )ue tomen parmetros depende del tipo de parmetro )ue sea* Esto se
e-plica en el siguiente apartado*
El lenguaje de programacin C# 5ema R3 6todos
Tipos de par1metros. "inta2is de definicin
?a &orma en )ue se de&ine cada parmetro de un mtodo depende del tipo de parmetro
del )ue se trate* En C# se admiten cuatro tipos de parmetros3 parmetros de entrada%
parmetros de salida% parmetros por re&erencia + parmetros de n,mero inde&inido*
Parmetros de entrada
Kn <94M?134. 51 1234959 reci$e una copia del (alor )ue almacenar.a una (aria$le del
tipo del o$jeto )ue se le pase* Por tanto% si el o$jeto es de un tipo (alor se le pasar una
copia del o$jeto + cual)uier modi&icacin )ue se /aga al parmetro dentro del cuerpo
del mtodo no a&ectar al o$jeto original sino a su copiaU mientras )ue si el o$jeto es de
un tipo re&erencia entonces se le pasar una copia de la re&erencia al mismo + cual)uier
modi&icacin )ue se /aga al parmetro dentro del mtodo tam$in a&ectar al o$jeto
original +a )ue en realidad el parmetro re&erencia a ese mismo o$jeto original*
Para de&inir un parmetro de entrada $asta indicar cul el nom$re )ue se le desea dar +
el cul es tipo de dato )ue podr almacenar* Para ello se sigue la siguiente sinta-is3
<tipoParmetro> <nombreParmetro>
Por ejemplo% el siguiente cdigo de&ine un mtodo llamado Suma )ue toma dos
parmetros de entrada de tipo int llamados par1 + par2 + de(uel(e un int con su suma3
int Suma(int par1, int par2)
{
return par1+par2;
}
Como se (e% se usa la instruccin return para indicar cul es el (alor )ue /a de de(ol(er
el mtodo* Este (alor es el resultado de ejecutar la e-presin par1+par2U es decir% es la
suma de los (alores pasados a sus parmetros par1 + par2 al llamarlo*
En las llamadas a mtodos se e-presan los (alores )ue se deseen dar a este tipo de
parmetros indicando simplemente el (alor deseado* Por ejemplo% para llamar al mtodo
anterior con los (alores + Q se /ar.a <objeto>.Suma(2,5)% lo )ue de(ol(er.a el (alor [*
5odo esto se resume con el siguiente ejemplo3
using System;
class ParmetrosEntrada
{
public int a = 1;
public static void F(ParmetrosEntrada p)
{
p.a++;
}
public static void G(int p)
{
El lenguaje de programacin C# 5ema R3 6todos
p++;
}
public static void Main()
{
int obj1 = 0;
ParmetrosEntrada obj2 = new ParmetrosEntrada();
G(obj1);
F(obj2);
Console.WriteLine({0}, {1}, obj1, obj2.a);
}
}
Este programa muestra la siguiente salida por pantalla3
# D
Como se (e% la llamada al mtodo G() no modi&ica el (alor )ue ten.a obj1 antes de
llamarlo +a )ue obj1 es de un tipo (alor AintB Sin em$argo% como obj2 es de un tipo
re&erencia AParmetrosLlamadasB los cam$ios )ue se le /acen dentro de F() al pasrselo
como parmetro s. )ue le a&ectan*
Parmetros de saIida
Kn <94M?134. 51 ;9-759 se di&erencia de uno de entrada en )ue todo cam$io )ue se le
realice en el cdigo del mtodo al )ue pertenece a&ectar al o$jeto )ue se le pase al
llamar dic/o mtodo tanto si ste es de un tipo por como si es de un tipo re&erencia* Esto
se de$e a )ue lo )ue a estos parmetros se les pasa es siempre una re&erencia al (alor
)ue almacenar.a una (aria$le del tipo del o$jeto )ue se les pase*
Cual)uier parmetro de salida de un mtodo siempre /a de modi&icarse dentro del
cuerpo del mtodo + adems dic/a modi&icacin /a de /acerse antes )ue cual)uier
lectura de su (alor* Si esto no se /iciese as. el compilador lo detectar.a e in&ormar.a de
ello con un error* Por esta razn es posi$le pasar parmetros de salida )ue sean (aria$les
no inicializadas% pues se garantiza )ue en el mtodo se inicializarn antes de leerlas*
Adems% tras la llamada a un mtodo se considera )ue las (aria$les )ue se le pasaron
como parmetros de salida +a estarn inicializadas% pues dentro del mtodo seguro )ue
se las inicializaci*
4tese )ue este tipo de parmetros permiten dise1ar mtodos )ue de(uel(an m,ltiples
o$jetos3 un o$jeto se de(ol(er.a como (alor de retorno + los dems se de(ol(er.an
escri$iendos en los parmetros de salida*
?os parmetros de salida se de&inen de &orma parecida a los parmetros de entrada pero
se les /a de a1adir la pala$ra reser(ada out* L sea% se de&inen as.3
out <tipoParmetro> <nombreParmetro>
El lenguaje de programacin C# 5ema R3 6todos
Al llamar a un mtodo )ue tome parmetros de este tipo tam$in se /a preceder el (alor
especi&icado para estos parmetros del modi&icador out* Kna utilidad de esto es &acilitar
la legi$ilidad de las llamadas a mtodos* Por ejemplo% dada una llamada de la &orma3
a.f(x, out z)
Es &cil determinar )ue lo )ue se /ace es llamar al mtodo f() del o$jeto a pasndole x
como parmetro de entrada + z como parmetro de salida* Adems% tam$in se puede
deducir )ue el (alor de z cam$iar tras la llamada*
Sin em$argo% la (erdadera utilidad de &orzar a e-plicitar en las llamadas el tipo de paso
de cada parmetro es )ue permite e(itar errores deri(ados de )ue un programador pase
una (aria$le a un mtodo + no sepa )ue el mtodo la puede modi&icar* 5enindola )ue
e-plicitar se asegura )ue el programador sea consciente de lo )ue /ace*
Parmetros por referencia
Kn <94M?134. <.4 41@1412679 es similar a un parmetro de salida slo )ue no es
o$ligatorio modi&icarlo dentro del mtodo al )ue pertenece% por lo )ue ser o$ligatorio
pasarle una (aria$le inicializada +a )ue no se garantiza su inicializacin en el mtodo*
?os parmetros por re&erencia se de&inen igual )ue los parmetros de salida pero
sustitu+endo el modi&icador out por el modi&icador ref* Cel mismo modo% al pasar
(alores a parmetros por re&erencia tam$in /a+ )ue precederlos del ref*
Parmetros de nmero indefinido
C# permite dise1ar mtodos )ue puedan tomar cual)uier n,mero de parmetros* Para
ello /a+ )ue indicar como ,ltimo parmetro del mtodo un parmetro de alg,n tipo de
ta$la unidimensional o dentada precedido de la pala$ra reser(ada params* Por ejemplo3

static void F(int x, params object[] extras)
{}
5odos los parmetros de n,mero inde&inido )ue se pasan al mtodo al llamarlo /an de
ser del mismo tipo )ue la ta$la* 4tese )ue en el ejemplo ese tipo es la clase primigenia
object% con lo )ue se consigue )ue gracias al polimor&ismo el mtodo pueda tomar
cual)uier n,mero de parmetros de cual)uier tipo* Ejemplos de llamadas (lidas ser.an3
F(4); // Pueden pasarse 0 parmetros indefinidos
F(3,2);
F(1, 2, Hola, 3.0, new Persona());
F(1, new object[] {2,Hola, 3.0, new Persona});
El primer ejemplo demuestra )ue el n,mero de parmetros inde&inidos )ue se pasen
tam$in puede ser 2* Por su parte% los dos ,ltimos ejemplos son totalmente e)ui(alentes%
pues precisamente la utilidad de pala$ra reser(ada params es indicar )ue se desea )ue la
creacin de la ta$la object[] se /aga impl.citamente*
El lenguaje de programacin C# 5ema R3 6todos
Es importante se1alar )ue la prioridad de un mtodo )ue inclu+a el params es in&erior a
la de cual)uier otra so$recarga del mismo* Es decir% si se /u$iese de&inido una
so$recarga del mtodo anterior como la siguiente3
static void F(int x, int y)
{}
Cuando se /iciese una llamada como F(3,2) se llamar.a a esta ,ltima (ersin del mtodo%
+a )ue aun)ue la del params es tam$in aplica$le% se considera )ue es menos prioritaria*
Sobrecarga de tipos de parmetros
En realidad los modi&icadores ref + out de los parmetros de un mtodo tam$in &orman
parte de lo )ue se conoce como signatura del mtodo% por lo )ue esta clase es (lida3
class Sobrecarga
{
public void f(int x)
{}
public void f(out int x)
{}
}
4tese )ue esta clase es correcta por)ue cada uno de sus mtodos tiene una signatura
distinta3 el parmetro es de entrada en el primero + de salida en el segundo*
Sin em$argo% /a+ una restriccin3 no puede ocurrir )ue la ,nica di&erencia entre la
signatura de dos mtodos sea )ue en uno un determinado parmetro lle(e el modi&icador
ref + en el otro lle(e el modi&icador out* Por ejemplo% no es (lido3
class Sobrecarganvlida
{
public void f(ref int x)
{}
public void f(out int x)
{}
}
M/todos e2ternos
Kn ?N3.5. 1I3142. es a)ul cu+a implementacin no se da en el &ic/ero &uente en )ue
es declarado* Estos mtodos se declaran precediendo su declaracin del modi&icador
extern* Como su cdigo se da e-ternamente% en el &uente se sustitu+en las lla(es donde
de$er.a escri$irse su cuerpo por un punto + coma A;B% )uedando una sinta-is de la &orma3
extern <nombreMtodo>(<parmetros>);
?a &orma en )ue se asocie el cdigo e-terno al mtodo no est de&inida en la
especi&icacin de C# sino )ue depende de la implementacin )ue se /aga del lenguaje*
El ,nico re)uisito es )ue no pueda de&inirse un mtodo como a$stracto + e-terno a la
El lenguaje de programacin C# 5ema R3 6todos
(ez% pero por todo lo dems puede com$inarse con los dems modi&icadores% incluso
pudindose de&inir mtodos (irtuales e-ternos*
?a &orma ms /a$itual de asociar cdigo e-terno consiste en preceder la declaracin del
mtodo de un 9347C03. de tipo System.Runtime.InteropServices.DIIImport )ue indi)ue
en cul li$rer.a de enlace dinmico AC??B se /a implementado* Este atri$uto re)uiere
)ue el mtodo e-terno )ue le siga sea esttico% + un ejemplo de su uso es3
using System.Runtime.nteropServices; // Aqu est definido Dllmport
public class Externo
{
[Dllmport(kernel32)]
public static extern void CopyFile(string fuente, string destino);
public static void Main()
{
CopyFile(fuente.dat, destino.dat);
}
}
El concepto de atri$uto se e-plica detalladamente en el Tema %*:.tri#tos* Por a/ora
$asta sa$er )ue los atri$utos se usan de &orman similar a los mtodos slo )ue no estn
asociados a ning,n o$jeto ni tipo + se indican entre corc/etes A[]B antes de declaraciones
de elementos del lenguaje* En el caso concreto de DIIImport lo )ue indica el parmetro
)ue se le pasa es cul es el &ic/ero Apor de&ecto se considera )ue su e-tensin es .dllB
donde se encuentra la implementacin del mtodo e-terno a continuacin de&inido*
?o )ue el cdigo del ejemplo anterior /ace es simplemente de&inir un mtodo de
nom$re CopyFile() cu+o cdigo se corresponda con el de la &uncin CopyFiIe() del
&ic/ero Kernel(D.dll del API B723#* Este mtodo es llamado en Main() para copiar el
&ic/ero de nom$re <uente.dat en otro de nom$re destino.dat* 4tese )ue dado )ue
CopyFile() se /a declarado como static + se le llama desde la misma clase donde se /a
declarado% no es necesario precederlo de la notacin <nombreClase>. para llamarlo*
Como se (e% la utilidad principal de los mtodos e-ternos es permitir /acer --9?959; 9
6857=. 2937A. desde cdigo gestionado% lo )ue puede ser ,til por razones de e&iciencia o
para reutilizar cdigo antiguamente escrito pero reduce la porta$ilidad de la aplicacin*
Constructores
Concepto de constructores
?os 6.2;34063.41; de un tipo de datos son mtodos especiales )ue se de&inen como
miem$ros de ste + )ue contienen cdigo a ejecutar cada (ez )ue se cree un o$jeto de
ese tipo* <ste cdigo suele usarse para la$ores de inicializacin de los campos del o$jeto
a crear% so$re todo cuando el (alor de stos no es constante o inclu+e acciones ms all
de una asignacin de (alor Aaperturas de &ic/eros% accesos a redes% etc*B
8a+ )ue tener en cuenta )ue la ejecucin del constructor siempre se realiza despus de
/a$erse inicializado todos los campos del o$jeto% +a sea con los (alores iniciales )ue se
/u$iesen especi&icado en su de&inicin o dejndolos con el (alor por de&ecto de su tipo*
El lenguaje de programacin C# 5ema R3 6todos
Aparte de su especial sinta-is de de&inicin% los constructores + los mtodos normales
tienen una di&erencia mu+ importante3 -.; 6.2;34063.41; 2. ;1 J141592*
Definicin de constructores
?a sinta-is $sica de de&inicin de constructores consiste en de&inirlos como cual)uier
otro mtodo pero dndoles el mismo nom$re )ue el tipo de dato al )ue pertenecen + no
indicando el tipo de (alor de retorno de$ido a )ue nunca pueden de(ol(er nada* Es
decir% se usa la sinta-is3
<modificadores> <nombreTipo>(<parmetros>)
{
<cdigo>
}
Kn constructor nunca puede de(ol(er ning,n tipo de o$jeto por)ue% como +a se /a
(isto% slo se usa junto al operador new% )ue de(uel(e una re&erencia al o$jeto recin
creado* Por ello% es a$surdo )ue de(uel(a alg,n (alor +a )ue nunca podr.a ser capturado
en tanto )ue new nunca lo de(ol(er.a* Por esta razn el compilador considera errneo
indicar alg,n tipo de retorno en su de&inicin% incluso aun)ue se indi)ue void*
LIamada aI constructor
Al constructor de una clase se le llama en el momento en )ue se crea alg,n o$jeto de la
misma usando el operador new* Ce /ec/o% la &orma de uso de este operador es3
new <llamadaConstructor>
Por ejemplo% el siguiente programa demuestra cmo al crearse un o$jeto se ejecutan las
instrucciones de su constructor3
class Prueba
{
Prueba(int x)
{
System.Console.Write(Creado objeto Prueba con x={0},x);
}
public static void Main()
{
Prueba p = new Prueba(5);
}
}
?a salida por pantalla de este programa demuestra )ue se /a llamado al constructor del
o$jeto de clase Prueba creado en Main()% pues es3
Creado objeto Prueba con x=5;
El lenguaje de programacin C# 5ema R3 6todos
LIamadas entre constructores
Al igual )ue ocurre con cual)uier otro mtodo% tam$in es posi$le so$recargar los
constructores* Es decir% se pueden de&inir (arios constructores siempre + cuando estos
tomen di&erentes n,meros o tipos de parmetros* Adems% desde el cdigo de un
constructor puede llamarse a otros constructores del mismo tipo de dato antes de
ejecutar las instrucciones del cuerpo del primero* Para ello se a1ade un 727679-7K95.4
3J7; al constructor% )ue es estructura )ue precede a la lla(e de apertura de su cuerpo tal +
como se muestra en el siguiente ejemplo3

class A
{
int total;
A(int valor): this(valor, 2); // (1)
{
}
A(int valor, int peso) // (2)
{
total = valor*peso;
}
}
El this incluido /ace )ue la llamada al constructor (1) de la clase A pro(o)ue una
llamada al constructor (2) de esa misma clase en la )ue se le pase como primer
parmetro el (alor originalmente pasado al constructor (1) + como segundo parmetro el
(alor * Es importante se1alar )ue la llamada al constructor (2) en (1) se /ace antes de
ejecutar cual)uier instruccin de (1)
4tese )ue la so$recarga de constructores X+ de cual)uier mtodo en generalX es un
$uen modo de de&inir (ersiones ms compactas de mtodos de uso &recuente en las )ue
se tomen (alores por de&ecto para parmetros de otras (ersiones menos compactas del
mismo mtodo* ?a implementacin de estas (ersiones compactas consistir.a en /acer
una llamada a la (ersin menos compacta del mtodo en la )ue se le pasen esos (alores
por de&ecto Aa tra(s del this en el caso de los constructoresB + si acaso luego A+Jo antes%
si no es un constructorB se /agan la$ores espec.&icas en el cuerpo del mtodo compacto*
Cel mismo modo )ue en la de&inicin de un constructor de un tipo de datos es posi$le
llamar a otros constructores del mismo tipo de datos% tam$in es posi$le /acer llamadas
a constructores de su tipo padre sustitu+endo en su inicializador la pala$ra reser(ada
this por base* Por ejemplo3
class A
{
int total;

A(int valor, int peso)
{
total = valor*peso;
}
}
class B:A
El lenguaje de programacin C# 5ema R3 6todos
{
B(int valor):base(valor,2)
{}
}
En am$os casos% los (alores pasados como parmetros en el inicializador no pueden
contener re&erencias a campos del o$jeto )ue se est creando% +a )ue se considera )ue
un o$jeto no est creado /asta )ue no se ejecute su constructor +% por tanto% al llamar al
inicializador a,n no est creado* Sin em$argo% lo )ue s. pueden incluir son re&erencias a
los parmetros con los )ue se llam al constructor* Por ejemplo% ser.a (lido /acer3
A(int x, int y): this(x+y)
{}
Constructor por defecto
5odo tipo de datos /a de disponer de al menos un constructor* Cuando se de&ine un tipo
sin especi&icar ninguno el compilador considera )ue impl.citamente se /a de&inido uno
sin cuerpo ni parmetros de la siguiente &orma3
public <nombreClase>(): base()
{}
En el caso de )ue el tipo sea una clase a$stracta% entonces el constructor por de&ecto
introducido es el )ue se muestra a continuacin% +a )ue el anterior no ser.a (lido
por)ue permitir.a crear o$jetos de la clase a la )ue pertenece3
protected <nombreClase>(): base()
{}
En el momento en se de&ina e-pl.citamente alg,n constructor el compilador dejar de
introducir impl.citamente el anterior* 8a+ )ue tener especial cuidado con la llamada )ue
este constructor por de&ecto realiza en su inicializador% pues pueden producirse errores
como el del siguiente ejemplo3
class A
{
public A(int x)
{}
}
class B:A
{
public static void Main()
{
B b = new B(); // Error: No hay constructor base
}
}
En este caso% la creacin del o$jeto de clase B en Main() no es posi$le de$ido a )ue el
constructor )ue por de&ecto el compilador crea para la clase B llama al constructor sin
parmetros de su clase $ase A% pero A carece de dic/o constructor por)ue no se le /a
El lenguaje de programacin C# 5ema R3 6todos
de&inido e-pl.citamente ninguno con esas caracter.sticas pero se le /a de&inido otro )ue
/a /ec/o )ue el compilador no le de&ina impl.citamente el primero*
Ltro error )ue podr.a darse consistir.a en )ue aun)ue el tipo padre tu(iese un
constructor sin parmetros% ste &uese pri(ado + por tanto inaccesi$le para el tipo /ijo*
5am$in es importante se1alar )ue a,n en el caso de )ue de&inamos nuestras propios
constructores% si no especi&icamos un inicializador el compilador introducir por
nosotros uno de la &orma :base() Por tanto% en estos casos tam$in /a+ )ue asegurarse de
)ue el tipo donde se /a+a de&inido el constructor /erede de otro )ue tenga un
constructor sin parmetros no pri(ado*
LIamadas poIimrficas en constructores
Es con(eniente e(itar en la medida de lo posi$le la realizacin de llamadas a mtodos
(irtuales dentro de los constructores% +a )ue ello puede pro(ocar errores mu+ di&.ciles
de detectar de$ido a )ue se ejecuten mtodos cuando la parte del o$jeto )ue manipulan
a,n no se /a sido inicializado* Kn ejemplo de esto es el siguiente3
using System;
public class Base
{
public Base()
{
Console.WriteLine("Constructor de Base");
this.F();
}
public virtual void F()
{
Console.WriteLine("Base.F");
}
}
public class Derivada:Base
{
Derivada()
{
Console.WriteLine("Constructor de Derivada");
}
public override void F()
{
Console.WriteLine("Derivada.F()");
}
public static void Main()
{
Base b = new Derivada();
}
}
?a salida por pantalla mostrada por este programa al ejecutarse es la siguiente3
El lenguaje de programacin C# 5ema R3 6todos
Constructor de 1ase
9eri2ada.G(%
Constructor de 9eri2ada
?o )ue /a ocurrido es lo siguiente3 Al crearse el o$jeto Derivada se /a llamado a su
constructor sin parmetros% )ue como no tiene inicializador impl.citamente llama al
constructor sin parmetros de su clase $ase* El constructor de Base realiza una llamada
al mtodo (irtual F()% + como el (erdadero tipo del o$jeto )ue se est contru+endo es
Derivada% entonces (ersin del mtodo (irtual ejecutada es la rede&inicin del mismo
incluida en dic/a clase* Por ,ltimo% se termina llamando al constructor de Derivada +
&inaliza la construccin del o$jeto*
4tese )ue se /a ejecutado el mtodo F() de Derivada antes )ue el cdigo del constructor
de dic/a clase% por lo )ue si ese mtodo manipulase campos de&inidos en Derivada )ue
se inicializasen a tra(s de constructor% se /a$r.a accedido a ellos antes de inicializarlos
+ ello seguramente pro(ocar.a errores de causas di&.ciles de a(eriguar*
Constructor de tipo
5odo tipo puede tener opcionalmente un 6.2;34063.4 51 37<.% )ue es un mtodo
especial )ue &unciona de &orma similar a los constructores ordinarios slo )ue para lo
)ue se usa es para inicializar los campos static del tipo donde se /a de&inido*
Cada tipo de dato slo puede tener un constructor de tipo* <ste constructor es llamado
automticamente por el compilador la primera (ez )ue se accede al tipo% +a sea para
crear o$jetos del mismo o para acceder a sus campos estticos* Esta llamada se /ace
justo despus de inicializar los campos estticos del tipo con los (alores iniciales
especi&icados al de&inirlos Ao% en su ausencia% con los (alores por de&ecto de sus tipos de
datoB% por lo )ue el programador no tiene &orma de controlar la &orma en )ue se le llama
+% por tanto% no puede pasarle parmetros )ue condicionen su ejecucin*
Como cada tipo slo puede tener un constructor de tipo no tiene sentido poderse usar
this en su inicializador para llamar a otro* V adems% tampoco tiene sentido usar base
de$ido a )ue ste siempre /ar re&erencia al constructor de tipo sin parmetros de su
clase $ase* L sea% 02 6.2;34063.4 51 37<. 2. <0151 31214 727679-7K95.4*
Adems% no tiene sentido darle modi&icadores de acceso +a )ue el programador nunca lo
podr llamar sino )ue slo ser llamado automticamente + slo al accederse al tipo por
primera (ez* Como es a$surdo% el compilador considera un error drselos*
?a &orma en )ue se de&ine el constructor de tipo es similar a la de los constructores
normales% slo )ue a/ora la de&inicin /a de ir pre&ijada del modi&icador static + no
puede contar con parmetros ni inicializador* L sea% se de&ine de la siguiente manera3
static <nombreTipo>()
{
<cdigo>
}
El lenguaje de programacin C# 5ema R3 6todos
En la especi&icicacin de C# no se /a recogido cul /a de ser el orden e-acto de las
llamadas a los constructores de tipos cuando se com$inan con /erencia% aun)ue lo )ue s.
se indica es )ue se /a de asegurar de )ue no se accede a un campo esttico sin /a$erse
ejecutado antes su constructor de tipo* 5odo esto puede (erse ms claro con un ejemplo3

using System;
class A
{
public static X;
static A()
{
Console.WriteLine(Constructor de A);
X=1;
}
}
class B:A
{
static B()
{
Console.WriteLine(Constructor de B);
X=2;
}
public static void Main()
{
B b = new B();
Console.WriteLine(B.X);
}
}
?a salida )ue muestra por pantalla la ejecucin de este programa es la siguiente3
;nicialiEada clase 1
;nicialiEada clase .
D
En principio la salida de este programa puede resultar con&usa de$ido a )ue los primeros
dos mensajes parecen dar la sensacin de )ue la creacin del o$jeto b pro(oc )ue se
ejecutase el constructor de la clase /ija antes )ue al de la clase padre% pero el ,ltimo
mensaje se corresponde con una ejecucin en el orden opuesto* Pues $ien% lo )ue /a
ocurrido es lo siguiente3 como el orden de llamada a constructores de tipo no est
esta$lecido% el compilador de 6icroso&t /a llamado antes al de la clase /ija + por ello el
primer mensaje mostrado es ;nicialiEada clase 1* Sin em$argo% cuando en este
constructor se (a a acceder al campo X se detecta )ue la clase donde se de&ini a,n no
est inicializada + entonces se llama a su constructor de tipo% lo )ue /ace )ue se muestre
el mensaje ;ncialiEada clase .* 5ras esta llamada se mac/aca el (alor )ue el
constructor de A di a X A(alor 1B por el (alor )ue el constructor de B le da A(alor B
Winalmente% el ,ltimo WriteLine() muestra un D% )ue es el ,ltimo (alor escrito en X*

)estructores
El lenguaje de programacin C# 5ema R3 6todos
Al igual )ue es posi$le de&inir mtodos constructores )ue inclu+an cdigo )ue gestione
la creacin de o$jetos de un tipo de dato% tam$in es posi$le de&inir un 51;34063.4 )ue
gestione cmo se destru+en los o$jetos de ese tipo de dato* Este mtodo suele ser ,til
para li$erar recursos tales como los &ic/eros o las cone-iones de redes a$iertas )ue el
o$jeto a destruir estu(iese acaparando en el momento en )ue se &uese a destruir*
?a destruccin de un o$jeto es realizada por el recolector de $asura cuando realiza una
recoleccin de $asura + detecta )ue no e-isten re&erencias a ese o$jeto ni en pila% ni en
registros ni desde otros o$jetos s. re&erenciados* ?as recolecciones se inician
automticamente cuando el recolector detecta )ue )ueda poca memoria li$re o )ue se (a
a &inalizar la ejecucin de la aplicacin% aun)ue tam$in puede &orzarse llamando al
mtodo CoIIect() de la clase System.GC
?a sinta-is )ue se usa para de&inir un destructor es la siguiente3
~<nombreTipo>()
{
<cdigo>
}
5ras la ejecucin del destructor de un o$jeto de un determinado tipo siempre se llama al
destructor de su tipo padre% &ormndose as. una cadena de llamadas a destructores )ue
aca$a al llegarse al destructor de object* <ste ,ltimo destructor no contiene cdigo
alguno% + dado )ue object no tiene padre% tampoco llama a ning,n otro destructor*
?os destructores no se /eredan* Sin em$argo% para asegurar )ue la cadena de llamadas a
destructores &uncione correctamente si no incluimos ninguna de&inicin de destructor en
un tipo% el compilador introducir en esos casos una por nosotros de la siguiente &orma3
~<nombreTipo>()
{}
El siguiente ejemplo muestra como se de&inen destructores + cmo &unciona la cadena
de llamada a destructores3
using System;
class A
{
~A()
{
Console.WriteLine(Destruido objeto de clase A);
}
}
class B:A
{
~B()
{
Console.WriteLine(Destruido objeto de clase B);
}
public static void Main()
{
new B();
El lenguaje de programacin C# 5ema R3 6todos
}
}
El cdigo del mtodo Main() de este programa crea un o$jeto de clase B pero no
almacena ninguna re&erencia al mismo* ?uego &inaliza la ejecucin del programa% lo )ue
pro(oca la actuacin del recolector de $asura + la destruccin del o$jeto creado
llamando antes a su destructor* ?a salida )ue o&rece por pantalla el programa demuestra
)ue tras llamar al destructor de B se llama al de su clase padre% +a )ue es3
9estruido o-7eto de clase 1
9estruido o-7eto de clase .
4tese )ue aun)ue no se /a+a guardado ninguna re&erencia al o$jeto de tipo B creado +
por tanto sea innacesi$le para el programador% al recolector de $asura no le pasa lo
mismo + siempre tiene acceso a los o$jetos% aun)ue sean in,tiles para el programador*
Es importante recalcar )ue no es (lido incluir ning,n modi&icador en la de&inicin de
un destructor% ni si)uiera modi&icadores de acceso% +a )ue como nunca se le puede
llamar e-pl.citamente no tiene ning,n ni(el de acceso para el programador* Sin
em$argo% ello no implica )ue cuando se les llame no se tenga en cuenta el (erdadero
tipo de los o$jetos a destruir% como demuestra el siguiente ejemplo3
using System;
public class Base
{
public virtual void F()
{
Console.WriteLine("Base.F");
}
~Base()
{
Console.WriteLine("Destructor de Base");
this.F();
}
}
public class Derivada:Base
{
~Derivada()
{
Console.WriteLine("Destructor de Derivada");
}
public override void F()
{
Console.WriteLine("Derivada.F()");
}
public static void Main()
{
Base b = new Derivada();
}
}
?a salida mostrada )ue muestra por pantalla este programa al ejecutarlo es3
El lenguaje de programacin C# 5ema R3 6todos
9estructor de 9eri2ada
9estructor de 1ase
9eri2ada.G(%
Como se (e% aun)ue el o$jeto creado se almacene en una (aria$le de tipo Base% su
(erdadero tipo es Derivada + por ello se llama al destructor de esta clase al destruirlo*
5ras ejecutarse dic/o contructor se llama al constructor de su clase padre siguindose la
cadena de llamadas a destructores* En este constructor padre /a+ una llamada al mtodo
(irtual F()% )ue como nue(amente el o$jeto )ue se est destru+endo es de tipo Derivada%
la (ersin de F() a la )ue se llamar es a la de la dic/a clase*
4tese )ue una llamada a un mtodo (irtual dentro de un destructor como la )ue se /ace
en el ejemplo anterior puede dar lugar a errores di&.ciles de detectar% pues cuando se
llama al mtodo (irtual +a se /a destruido la parte del o$jeto correspondiente al tipo
donde se de&ini el mtodo ejecutado* As.% en el ejemplo anterior se /a ejecutado
Derivada.F() tras Derivada.~F()% por lo )ue si en Derivada.F() se usase alg,n campo
destruido en Derivada.~F() podr.an producirse errores di&.ciles de detectar*
El lenguaje de programacin C# 5ema :3 Propiedades
TEMA 9: Propiedades
Concepto de propiedad
Kna <4.<71595 es una mezcla entre el concepto de campo + el concepto de mtodo*
E-ternamente es accedida como si de un campo normal se tratase% pero internamente es
posi$le asociar cdigo a ejecutar en cada asignacin o lectura de su (alor* <ste cdigo
puede usarse para compro$ar )ue no se asignen (alores in(lidos% para calcular su (alor
slo al solicitar su lectura% etc*
Kna propiedad no almacena datos% sino slo se utiliza como si los almacenase* En la
prctica lo )ue se suele /acer escri$ir como cdigo a ejecutar cuando se le asigne un
(alor% cdigo )ue controle )ue ese (alor sea correcto + )ue lo almacene en un campo
pri(ado si lo esU + como cdigo a ejecutar cuando se lea su (alor% cdigo )ue de(uel(a
el (alor almacenado en ese campo p,$lico* As. se simula )ue se tiene un campo p,$lico
sin los incon(enientes )ue estos presentan por no poderse controlar el acceso a ellos*
)efinicin de propiedades
Para de&inir una propiedad se usa la siguiente sinta-is3
< tipoPropiedad> <nombrePropiedad>
{
set
{
<cdigoEscritura>
}
get
{
<cdigoLectura>
}
}
Kna propiedad as. de&inida ser.a accedida como si de un campo de tipo <tipoPropiedad>
se tratase% pero en cada lectura de su (alor se ejecutar.a el <cdigoLectura> + en cada
escritura de un (alor en ella se ejecutar.a <cdigoEscritura>
Al escri$ir los $lo)ues de cdigo get + set /a+ )ue tener en cuenta )ue dentro del
cdigo set se puede /acer re&erencia al (alor )ue se solicita asignar a tra(s de un
parmetro especial del mismo tipo de dato )ue la propiedad llamado vaIue Aluego
nosotros no podemos de&inir uno con ese nom$re en <cdigoEscritura>BU + )ue dentro del
cdigo get se /a de de(ol(er siempre un o$jeto del tipo de dato de la propiedad*
En realidad el orden en )ue aparezcan los $lo)ues de cdigo set + get es irrele(ante*
Adems% es posi$le de&inir propiedades )ue slo tengan el $lo)ue get A<4.<715951; 51
;8-. -163049B o )ue slo tengan el $lo)ue set A<4.<715951; 51 ;8-. 1;6473049B ?o )ue
no es (lido es de&inir propiedades )ue no inclu+an ninguno de los dos $lo)ues*
El lenguaje de programacin C# 5ema :3 Propiedades
?as propiedades participan del mecanismo de polimor&ismo igual )ue los mtodos%
siendo incluso posi$le de&inir propiedades cu+os $lo)ues de cdigo get o set sean
a$stractos* Esto se /ar.a pre&ijando el $lo)ue apropiado con un modi&icador abstract +
sustitu+endo la de&inicin de su cdigo por un punto + coma* Por ejemplo3
using System;
abstract class A
{
public abstract int PropiedadEjemplo
{
set;
get;
}
}
class B:A
{
private int valor;
public override int PropiedadEjemplo
{
get
{
Console.WriteLine(Ledo {0} de PropiedadEjemplo, valor);
return valor;
}
set
{
valor = value;
Console.WriteLine(Escrito {0} en PropiedadEjemplo, valor);
}
}
}
En este ejemplo se (e cmo se de&inen + rede&inen propiedades a$stractas* Al igual )ue
abstract + override% tam$in es posi$le usar cual)uiera de los modi&icadores relati(os a
/erencia + polimor&ismo +a (istos3 virtuaI% new + seaIed*
4tese )ue aun)ue en el ejemplo se /a optado por asociar un campo pri(ado valor a la
propiedad PropiedadEjemplo% en realidad nada o$liga a )ue ello se /aga + es posi$le
de&inir propiedades )ue no tenga campos asociados* Es decir% una propiedad no se tiene
por)u corresponder con un almacn de datos*
4cceso a propiedades
?a &orma de acceder a una propiedad% +a sea para lectura o escritura% es e-actamente la
misma )ue la )ue se usar.a para acceder a un campo de su mismo tipo* Por ejemplo% se
podr.a acceder a la propiedad de un o$jeto de la clase B del ejemplo anterior con3
B obj = new B();
obj.PropiedadEjemplo++;
El lenguaje de programacin C# 5ema :3 Propiedades
El resultado )ue por pantalla se mostrar.a al /acer una asignacin como la anterior ser.a3
LeQdo de 4ro5iedad@7em5lo&
@scrito C en 4ro5iedad@7em5lo&
4tese )ue en el primer mensaje se muestra )ue el (alor le.do es 2 por)ue lo )ue
de(uel(e el $lo)ue get de la propiedad es el (alor por de&ecto del campo pri(ado valor%
)ue como es de tipo int tiene como (alor por de&ecto 2*
!mplementacin interna de propiedades
En realidad la de&inicin de una propiedad con la sinta-is antes (ista es con(ertida por
el compilador en la de&inicin de un par de mtodos de la siguiente &orma3
<tipoPropiedad> get_<nombrePropiedad>()
{ // Mtodo en que se convierte el bloque get
<cdigoLectura>
}
void set_<nombrePropiedad> (<tipoPropiedad> vaIue)
{ // Mtodo en que se convierte el bloque set
<cdigoEscritura>
}
Esto se /ace para )ue desde lenguajes )ue no soporten las propiedades se pueda acceder
tam$in a ellas* Si una propiedad es de slo lectura slo se generar el mtodo get_X()% +
si es de slo escritura slo se generar el set_X() A/ora $ien% en cual)uier caso /a+ )ue
tener cuidado con no de&inir en un mismo tipo de dato mtodos con signaturas como
estas si se (an a generar internamente de$ido a la de&inicin de una propiedad% +a )ue
ello pro(ocar.a un error de de&inicin m,ltiple de mtodo*
5eniendo en cuenta la implementacin interna de las propiedades% es &cil (er )ue el
,ltimo ejemplo de acceso a propiedad es e)ui(alente a3
B b = new B();
obj.set_PropiedadEjemplo(obj.get_Propiedad_Ejemplo()++);
Como se (e% gracias a las propiedades se tiene una sinta-is muc/o ms compacta + clara
para acceder a campos de manera controlada* Se podr.a pensar )ue la contrapartida de
esto es )ue el tiempo de acceso al campo aumenta considera$lemente por perderse
tiempo en /acer las llamada a mtodos setJget* Pues $ien% esto no tiene por)u ser as. +a
)ue el compilador de C# elimina llamadas /aciendo 72-7272= Asustitucin de la llamada
por su cuerpoB en los accesos a $lo)ues getJset no (irtuales + de cdigos pe)ue1os% )ue
son los ms /a$ituales*

4tese )ue de la &orma en )ue se de&inen los mtodos generados por el compilador se
puede deducir el por)u del /ec/o de )ue en el $lo)ue set se pueda acceder a tra(s de
vaIue al (alor asignado + de )ue el o$jeto de(uelto por el cdigo de un $lo)ue get tenga
)ue ser del mismo tipo de dato )ue la propiedad a la )ue pertenece*
El lenguaje de programacin C# 5ema :3 Propiedades
El lenguaje de programacin C# 5ema 123 #ndizadores
TEMA 10: Indizadores
Concepto de indizador
Kn 7257K95.4 es una de&inicin de cmo se puede aplicar el operador de acceso a ta$las
A[ ]B a los o$jetos de un tipo de dato* Esto es especialmente ,til para /acer ms clara la
sinta-is de acceso a elementos de o$jetos )ue puedan contener colecciones de
elementos% pues permite tratarlos como si &uesen ta$las normales*
?os indizadores permiten de&inir cdigo a ejecutar cada (ez )ue se acceda a un o$jeto
del tipo del )ue son miem$ros usando la sinta-is propia de las ta$las% +a sea para leer o
escri$ir* A di&erencia de las ta$las% los .ndices )ue se les pase entre corc/etes no tiene
por)u ser enteros% pudindose de&inir (arios indizadores en un mismo tipo siempre +
cuando cada uno tome un n,mero o tipo de .ndices di&erente*
)efinicin de indizador
A la /ora de de&inir un indizador se usa una sinta-is parecida a la de las propiedades3
<tipondizador> this[<ndices>]
{
set
{
<cdigoEscritura>
}
get
{
<cdigoLectura>
}
}
?as ,nicas di&erencias entre esta sinta-is + la de las propiedades son3
El nom$re dado a un indizador siempre /a de ser this% pues carece de sentido
poder darle cual)uiera en tanto )ue a un indizador no se accede por su nom$re
sino aplicando el operador [ ] a un o$jeto* Por ello% lo )ue di&erenciar a unos
indizadores de otros ser el n,mero + tipo de sus <ndices>
En <ndices> se indica cules son los .ndices )ue se pueden usar al acceder al
indizador* Para ello la sinta-is usada es casi la misma )ue la )ue se usa para
especi&icar los parmetros de un mtodo% slo )ue no se admite la inclusin de
modi&icadores ref% out o params + )ue siempre /a de de&inirse al menos un
parmetro* L$(iamente% el nom$re )ue se d a cada .ndice ser el nom$re con el
)ue luego se podr acceder al mismo en los $lo)ues setJget*
4o se pueden de&inir indizadores estticos% sino slo indizadores de o$jetos*
El lenguaje de programacin C# 5ema 123 #ndizadores
Por todo lo dems% la sinta-is de de&inicin de los indizadores es la misma )ue la de las
propiedades3 pueden ser de slo lectura o de slo escritura% da igual el orden en )ue se
de&inan sus $lo)ues setJget% dentro del $lo)ue set se puede acceder al (alor a escri$ir a
tra(s del parmetro especial vaIue del tipo del indizador% el cdigo del $lo)ue get /a de
de(ol(er un o$jeto de dic/o tipo% etc*
A continuacin se muestra un ejemplo de de&inicin de una clase )ue consta de dos
indizadores3 am$os permiten almacenar elementos de tipo entero% pero uno toma como
.ndice un entero + el otro toma dos cadenas3
using System;
public class A
{
public int this[int ndice]
{
set
{
Console.WriteLine(Escrito {0} en posicin {1}, value, ndice);
}
get
{
Console.WriteLine(Ledo 1 de posicin {0}, ndice);
return 1;
}
}
public int this[string cad1, string cad2]
{
set
{
Console.WriteLine(Escrito {0} en posicin ({1},{2}), value, cad1, cad2);
}
get
{
Console.WriteLine(Ledo prueba de posicin ({0},{1}), cad1, cad2);
return 2;
}
}
}
4cceso a indizadores
Para acceder a un indizador se utiliza e-ctamente la misma sinta-is )ue para acceder a
una ta$la% slo )ue los .ndices no tienen por)u ser enteros sino )ue pueden ser de
cual)uier tipo de dato )ue se /a+a especi&icado en su de&inicin* Por ejemplo% accesos
(lidos a los indizadores de un o$jeto de la clase A de&inida en el ep.gra&e anterior son3
A obj = new A();
obj[100] = obj[barco, coche];
?a ejecucin de la asignacin de este ejemplo producir esta salida por pantalla3
Ledo prueba de posicin (barco, coche)
Escrito 2 en posicin 100
El lenguaje de programacin C# 5ema 123 #ndizadores
!mplementacin interna de indizadores
Al igual )ue las propiedades% para &acilitar la interopera$ilidad entre lenguajes los
indizadores son tam$in con(ertidos por el compilador en llamadas a mtodos cu+a
de&inicin se deduce de la de&inicin del indizador* A/ora los mtodos son de la &orma3
<tipondizador> get_Item(<ndices>)
{
<cdigoLectura>
}
void set_Item(<ndices>, <tipondizador> value)
{
<cdigoEscritura>
}
4ue(amente% /a+ )ue tener cuidado con la signatura de los mtodos )ue se de&inan en
una clase +a )ue como la de alguno coincida con la generada automticamente por el
compilador para los indizadores se producir un error de am$igaedad*
El lenguaje de programacin C# 5ema 123 #ndizadores
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
TEMA 11: Redefinicin de operadores
Concepto de redefinicin de operador
Kn .<1495.4 en C# no es ms )ue un s.m$olo &ormado por uno o ms caracteres )ue
permite realizar una determinada operacin entre uno o ms datos + produce un
resultado* En el Tema *: .spe$tos +/i$os +a /emos (isto )ue C# cuenta con un $uen
n,mero de operadores )ue permiten realizar con una sinta-is clara e intuiti(a las
operaciones comunes a la ma+or.a de lenguajes Aaritmtica% lgica% etcB as. como otras
operaciones ms particulares de C# Aoperador is% operador stackaIIoc% etc*B
En C# (iene prede&inido el comportamiento de sus operadores cuando se aplican a
ciertos tipos de datos* Por ejemplo% si se aplica el operador + entre dos o$jetos int
de(uel(e su suma% + si se aplica entre dos o$jetos string de(uel(e su concatenacin* Sin
em$argo% tam$in se permite )ue el programador pueda de&inir el signi&icado la ma+or.a
de estos operadores cuando se apli)uen a o$jetos de tipos )ue l /a+a de&inido% + esto es
a lo )ue se le conoce como 4151@7276782 51 .<1495.4*
4tese )ue en realidad la posi$ilidad de rede&inir un operador no aporta ninguna nue(a
&uncionalidad al lenguaje + slo se /a incluido en C# para &acilitar la legi$ilidad del
cdigo* Por ejemplo% si tenemos una clase Complejo )ue representa n,meros complejos
podr.amos de&inir una &uncin Sumar() para sus o$jetos de modo )ue a tra(s de ella se
pudiese conseguir la suma de dos o$jetos de esta clase como muestra este ejemplo3
Complejo c1 = new Complejo(3,2); // c1 = 3 + 2i
Complejo c2 = new Complejo(5,2); // c2 = 5 + 2i
Complejo c3 = c1.Sumar(c2); // c3 = 8 + 4i
Sin em$argo% el cdigo ser.a muc/o ms legi$le e intuiti(o si en (ez de tenerse )ue usar
el mtodo Sumar() se rede&iniese el signi&icado del operador + para )ue al aplicarlo entre
o$jetos Complejo de(ol(iese su suma* Con ello% el cdigo anterior )uedar.a as.3
Complejo c1 = new Complejo(3,2); // c1 = 3 + 2i
Complejo c2 = new Complejo(5,2); // c2 = 5 + 2i
Complejo c3 = c1 + c2; // c3 = 8 + 4i
<sta es precisamente la utilidad de la rede&inicin de operadores3 /acer ms claro +
legi$le el cdigo% no /acerlo ms corto* Por tanto% cuando se rede&ina un operador es
importante )ue se le d un signi&icado intuiti(o +a )ue si no se ir.a contra de la &iloso&.a
de la rede&inicin de operadores* Por ejemplo% aun)ue ser.a posi$le rede&inir el operador
* para )ue cuando se aplicase entre o$jetos de tipo Complejo de(uel(a su suma o
imprimiese los (alroes de sus operandos en la (entana de consola% ser.a a$surdo /acerlo
+a )ue ms )ue clari&icar el cdigo lo )ue /ar.a ser.a di&icultar su comprensin*
Ce todas &ormas% suele ser $uena idea )ue cada (ez )ue se rede&ina un operador en un
tipo de dato tam$in se d una de&inicin de un mtodo )ue &uncione de &orma
e)ui(alente al operador* As. desde lenguajes )ue no soporten la rede&inicin de
operadores tam$in podr realizarse la operacin + el tipo ser ms reutiliza$le*
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
)efinicin de redefiniciones de operadores
Sintaxis generaI de redefinicin de operador
?a &orma en )ue se rede&ine un operador depende del tipo de operador del )ue se trate%
+a )ue no es lo mismo de&inir un operador unario )ue uno $inario* Sin em$argo% como
regla general podemos considerar )ue se de&iniendo un mtodo p,$lico + esttico cu+o
nom$re sea el s.m$olo del operador a rede&inir + (enga precedido de la pala$ra
reser(ada operator* Es decir% se sigue una sinta-is de la &orma3

pubIic static <tipoDevuelto> operator <smbolo>(<operandos>)
{
<cuerpo>
}
?os modi&icadores pubIic + static pueden permutarse si se desea% lo )ue es importante es
)ue siempre aparezcan en toda rede&inicin de operador* Se puede rede&inir tanto
operadores unarios como $inarios% + en <operandos> se /a de incluir tantos parmetros
como operandos pueda tomar el operador a rede&inir% +a )ue cada uno representar a
uno de sus operandos* Por ,ltimo% en <cuerpo> se /a de escri$ir las instrucciones a
ejecutar cada (ez )ue se apli)ue la operacin cu+o operador es <smbolo> a operandos
de los tipos indicados en <operandos>
<tipoDevuelto> no puede ser void% pues por de&inicin toda operacin tiene un resultado%
por lo )ue todo operador /a de de(ol(er algo* Adems% permitirlo complicar.a
innecesariamente el compilador + ste tendr.a )ue admitir instrucciones poco intuiti(as
Acomo a+b; si el + estu(iese rede&inido con (alor de retorno void para los tipos de a + bB

Adems% los operadores no pueden rede&inirse con total li$ertad +a )ue ello di&icultar.a
inncesariamente la legi$ilidad del cdigo% por lo )ue se /an introducido las siguientes
restricciones al rede&inirlos3
Al menos uno de los operandos /a de ser del mismo tipo de dato del )ue sea
miem$ro la rede&inicin del operador* Como puede deducirse% ello implica )ue
aun)ue puedan so$recargarse los operadores $inarios nunca podr /acerse lo mismo
con los $inarios +a )ue su ,nico parmetro slo puede ser de un ,nico tipo Ael tipo
dentro del )ue se de&inaB Adems% ello tam$in pro(oca )ue no pueden rede&inirse
las con(ersiones +a incluidas en la 0C? por)ue al menos uno de los operandos
siempre /a$r de ser de alg,n nue(o tipo de&inido por el usuario*
4o puede alterarse sus reglas de precedencia% asociati(idad% u$icacin + n,mero de
operandos% pues si +a de por s. es di&.cil para muc/os recordarlas cuando son &ijas%
muc/o ms lo ser.a si pudiesen modi&icarse seg,n los tipos de sus operandos*
4o puede de&inirse nue(os operadores ni com$inaciones de los +a e-istentes con
nue(os signi&icados Apor ejemplo ** para representar e-ponenciacinB% pues ello
complicar.a innecesariamente el compilador% el lenguaje + la legi$ilidad del cdigo
cuando en realidad es algo )ue puede simularse de&iniendo mtodos*
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
4o todos los operadores incluidos en el lenguaje pueden rede&inirse% pues muc/os
de ellos Acomo .% new% =% etc*B son $sicos para el lenguaje + su rede&inicin es
in(ia$le% poco ,til o di&icultar.a innecesariamente la legi$ilidad de los &uentes*
Adems% no todos los rede&ini$les se rede&inen usando la sinta-is general /asta
a/ora (ista% aun)ue en su momento se irn e-plicando cules son los rede&ini$les +
cules son las peculiaridades de a)uellos )ue re)uieran una rede&inicin especial*
A continuacin se muestra cmo se rede&inir.a el signi&icado del operador + para los
o$jetos Complejo del ejemplo anterior3
class Complejo;
{
public float ParteReal;
public float Partemaginaria;
public Complejo (float parteReal, float partemaginaria)
{
this.ParteReal = parteReal;
this.Partemaginaria = partemaginaria;
}
public static Complejo operator +(Complejo op1, Complejo op2)
{
Complejo resultado = new Complejo();
resultado.ParteReal = op1.ParteReal + op2.ParteReal;
resultado.Partemaginaria = op1.Partemaginaria + op2.Partemaginaria;
return resultado;
}
}
Es &cil (er )ue lo )ue en el ejemplo se /a rede&inido es el signi&icado del operador +
para )ue cuando se apli)ue entre dos o$jetos de clase Complejo de(uel(a un nue(o
o$jeto Complejo cu+as partes real e imaginaria sea la suma de las de sus operandos*
Se considera errneo incluir la pala$ra reser(ada new en la rede&inicin de un operador%
+a )ue no pueden ocultarse rede&iniciones de operadores en tanto )ue estos no se
aplican a usando el nom$re del tipo en )ue estn de&inidos* ?as ,nicas posi$les
coincidencias se dar.a en situaciones como la del siguiente ejemplo3
using System;
class A
{
public static int operator +(A obj1, B obj2)
{
Console.WriteLine(Aplicado + de A);
return 1;
}
}
class B:A
{
public static int operator +(A obj1, B obj2)
{
Console.WriteLine(Aplicado + de B);
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
return 1;
}
public static void Main()
{
A o1 = new A();
B o2 = new B();
Console.WriteLine(o1+o2={0}, o1+o2);
}
}
Sin em$argo% ms )ue una ocultacin de operadores lo )ue se tiene es un pro$lema de
am$igaedad en la de&inicin del operador + entre o$jetos de tipos A + B, de la )ue se
in&ormar al compilar +a )ue el compilador no sa$r cul (ersin del operador de$e usar
para traducir o1+o2 a cdigo $inario*
Redefinicin de operadores unarios
?os ,nicos operadores unarios rede&ini$les son3 !# +# -# ~# ++# --# true y faIse% + toda
rede&inicin de un operador unario /a de tomar un ,nico parmetro )ue /a de ser del
mismo tipo )ue el tipo de dato al )ue pertenezca la rede&inicin*
?os operadores ++ + -- siempre /a de rede&inirse de manera )ue el tipo de dato del
o$jeto de(uelto sea el mismo )ue el tipo de dato donde se de&inen* Cuando se usen de
&orma pre&ija se de(ol(er ese o$jeto% + cuando se usen de &orma posti&ja el compilador
lo )ue /ar ser de(ol(er el o$jeto original )ue se les pas como parmetro en lugar del
indicado en el return* Por ello es importante no modi&icar dic/o parmetro si es de un
tipo re&erencia + )ueremos )ue estos operadores tengan su signi&icado tradicional* Kn
ejemplo de cmo /acerlo es la siguiente rede&inicin de ++ para el tipo Complejo3

public static Complejo operator ++ (Complejo op)
{
Complejo resultado = new Complejo(op.ParteReal + 1, op.Partemaginaria);
return resultado;
}
4tese )ue si /u$isemos rede&inido el ++ de esta otra &orma3
public static Complejo operator ++ (Complejo op)
{
op.ParteReal++;
return op;
}
entonces el resultado de(uelto al aplicrselo a un o$jeto siempre ser.a el mismo tanto si
&ue aplicado de &orma pre&ija como si lo &ue de &orma posti&ija% +a )ue en am$os casos
el o$jeto de(uelto ser.a el mismo* Sin em$argo% eso no ocurrir.a si Complejo &uese una
estructura% +a )ue entonces op no ser.a el o$jeto original sino una copia de ste + los
cam$ios )ue se le /iciesen en el cuerpo de la rede&inicin de ++ no a&ectar.an al o$jeto
original% )ue es el )ue se de(uel(e cuando se usa ++ de manera post&ija*
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
>especto a los operadores true + faIse% estos indican respecti(amente% cuando se /a de
considerar )ue un o$jeto representa el (alor lgico cierto + cuando se /a de considerar
)ue representa el (alor lgico &also% por lo )ue su rede&iniciones siempre /an de
de(ol(er un o$jeto de tipo booI )ue indi)ue dic/a situacin* Adems% si se rede&ine uno
de estos operadores% entonces es o$ligatorio rede&inir tam$in el otro% en tanto )ue
siempre es posi$le usar indistintamente uno u otro para determinar el (alor lgico )ue
un o$jeto de ese tipo represente*
En realidad los operadores true + faIse no pueden usarse directamente en el cdigo
&uente% sino )ue rede&inirlos para un tipo de dato es ,til por)ue permitir usar o$jetos de
ese tipo en e-presiones condicionales tal + como si de un (alor lgico se tratase* Por
ejemplo% podemos rede&inir estos operadores en el tipo Complejo de modo )ue
consideren cierto a todo complejo distinto de 2 ' 2i + &also a 2 ' 2i3
public static bool operator true(Complejo op)
{
return (op.ParteReal != 0 || op.Partemaginaria != 0);
}
public static bool operator false(Complejo op)
{
return (op.ParteReal == 0 && op.Partemaginaria == 0);
}
Con estas rede&iniciones% un cdigo como el )ue sigue mostrar.a por pantalla el mensaje
@s cierto3
Complejo c1 = new Complejo(1, 0); // c1 = 1 + 0i
if (c1)
System.Console.WriteLine(Es cierto);
Redefinicin de operadores binarios
?os operadores $inarios rede&ini$les son +% 8% ,% /% 9% /% 0% :% ;;% <<% ==% >=% <% ;% <= +
<= 5oda rede&inicin )ue se /aga de ellos /a de tomar dos parmetros tales )ue al
menos uno de ellos sea del mismo tipo )ue el tipo de dato del )ue es miem$ro la
rede&inicin*
8a+ )ue tener en cuenta )ue a)uellos de estos operadores )ue tengan complementario
siempre /an de rede&inirse junto con ste* Es decir% siempre )ue se rede&ina en un tipo el
operador > tam$in /a de rede&inirse en l el operador <% siempre )ue se rede&ina >= /a
de rede&inirse <=% + siempre )ue se rede&ina == /a de rede&inirse !=*
5am$in /a+ )ue se1alar )ue% como puede deducirse de la lista de operadores $inarios
rede&ini$les dada% no es rede&inir directamente ni el operador de asignacin Y ni los
operadores compuestos A+=% -=% etc*B Sin em$argo% en el caso de estos ,ltimos dic/a
rede&inicin ocurre de manera automtica al rede&inir su parte Nno =O Es decir% al
rede&inir + )uedar rede&inido consecuentemente +=% al rede&inir * lo /ar *=% etc*
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
Por otra parte% tam$in ca$e se1alar )ue no es posi$le rede&inir dirctamente los
operadores && + ||* Esto se de$e a )ue el compilador los trata de una manera especial
)ue consiste en e(aluarlos perezosamente* Sin em$argo% es posi$le simular su
rede&inicin rede&iniendo los operadores unarios true + faIse% los operadores $inarios &
+ | + teniendo en cuenta )ue && + || se e(al,an as.3
&&3 Si tenemos una e-presin de la &orma x && y% se aplica primero el operador
faIse a x* Si de(uel(e faIse% entonces x && y de(uel(e el resultado de e(aluar xU +
si no% entonces de(uel(e el resultado de e(aluar x & y
||3 Si tenemos una e-presin de la &orma x || y% se aplica primero el operador true
a x* Si de(uel(e true% se de(uel(e el resultado de e(aluar xU + si no% se de(uel(e
el de e(aluar x | y*
Redefiniciones de operadores de conversin
En el Tema *: .spe$tos +/i$os +a (imos )ue para con(ertir o$jetos de un tipo de dato
en otro se puede usar un operador de con(ersin )ue tiene la siguiente sinta-is3
(<tipoDestino>) <expresin>
?o )ue este operador /ace es de(ol(er el o$jeto resultante de con(ertir al tipo de dato de
nom$re <tipoDestino> el o$jeto resultante de e(aluar <expresin> Para )ue la con(ersin
pueda aplicarse es preciso )ue e-ista alguna de&inicin de cmo se /a de con(ertir a
<tipoDestino> los o$jetos del tipo resultante de e(aluar <expresin> Esto puede indicarse
introduciendo como miem$ro del tipo de esos o$jetos o del tipo <tipoDestino> una
rede&inicin del operador de con(ersin )ue indi)ue cmo /acer la con(ersin del tipo
del resultado de e(aluar Ee-presinF a <tipoDestino>
?as rede&iniciones de operadores de con(ersin puede ser de dos tipos3
EI<-L6739;: ?a con(ersin slo se realiza cuando se usen e-pl.citamente los
operadores de con(ersin antes comentado*
I?<-L6739;: ?a con(ersin tam$in se realiza automticamente cada (ez )ue se
asigne un o$jeto de ese tipo de dato a un o$jeto del tipo <tipoDestino>* Estas
con(ersiones son ms cmodas )ue las e-pl.citas pero tam$in ms peligrosas
+a )ue pueden ocurrir sin )ue el programador se d cuenta* Por ello% slo
de$er.an de&inirse como impl.citas las con(ersin seguras en las )ue no se
puedan producir e-cepciones ni perderse in&ormacin al realizarlas*
En un mismo tipo de dato pueden de&inirse m,ltiples con(ersiones siempre + cuando el
tipo origen de las mismas sea di&erente* Por tanto% no es (lido de&inir a la (ez en un
mismo tipo una (ersin impl.cita de una cierta con(ersin + otra e-pl.cita*
?a sinta-is )ue se usa para /acer rede&inir una operador de con(ersin es parecida a la
usada para cual)uier otro operador slo )ue no /a+ )ue darle nom$re% toma un ,nico
parmetro + /a+ )ue preceder la pala$ra reser(ada operator con las pala$ras reser(adas
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
expIicit o impIicit seg,n se de&ina la con(ersin como e-pl.cita o impl.cita* Por ejemplo%
para de&inir una con(ersin impl.cita de Complejo a fIoat podr.a /acerse3
public static implicit operator float(Complejo op)
{
return op.ParteReal;
}
4tese )ue el tipo del parmetro usado al de&inir la con(ersin se corresponde con el
tipo de dato del o$jeto al )ue se puede aplicar la con(ersin A37<. .47=12B% mientras )ue
el tipo del (alor de(uelto ser el tipo al )ue se realice la con(ersin A37<. 51;372.B Con
esta de&inicin podr.an escri$irse cdigos como el siguiente3
Complejo c1 = new Complejo(5,2); // c1 = 5 + 2i
float f = c1; // f = 5
4tese )ue en la con(ersin de Complejo a fIoat se pierde in&ormacin Ala parte
imaginariaB% por lo )ue ser.a mejor de&inir la con(ersin como e-pl.cita sustitu+endo en
su de&inicin la pala$ra reser(ada impIicit por expIicit* En ese caso% el cdigo anterior
/a$r.a de cam$iarse por3
Complejo c1 = new Complejo(5,2); // c1 = 5 + 2i
float f = (float) c1; // f = 5
Por otro lado% si lo )ue /acemos es rede&inir la con(ersin de fIoat a Complejo con3
public static implicit operator Complejo(float op)
{
return (new Complejo(op, 0));
}
Entonces se podr.a crear o$jetos Complejo as.3
Complejo c2 = 5; // c2 = 5 + 0i
;ase )ue en este caso nunca se perder in&ormacin + la con(ersin nunca &allar% por
lo )ue es per&ectamente (lido de&inirla como impl.cita* Adems% ntese como
rede&iniendo con(ersiones impl.citas puede conseguirse )ue los tipos de&inidos por el
usuario puedan inicializarse directamente a partir de (alores literales tal + como si
&uesen tipos $sicos del lenguaje*
En realidad% cuando se de&inan con(ersiones no tiene por)us siempre ocurrir )ue eltipo
destino indicado sea el tipo del )ue sea miem$ro la rede&inicin% sino )ue slo /a de
cumplirse )ue o el tipo destino o el tipo origen sean de dic/o tipo* L sea% dentro de un
tipo de dato slo pueden de&inirse con(ersiones de ese tipo a otro o de otro tipo a ese*
Sin em$argo% al permitirse con(ersiones en am$os sentidos /a+ )ue tener cuidado
por)ue ello puede producir pro$lemas si se solicitan con(ersiones para las )ue e-ista
una de&inicin de cmo realizarlas en el tipo &uente + otra en el tipo destino* Por
ejemplo% el siguiente cdigo pro(oca un error al compilar de$ido a ello3
class A
{
static void Main(string[] args)
{
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
A obj = new B(); // Error: Conversin de B en A ambigua
}
public static implicit operator A(B obj)
{
return new A();
}
}
class B
{
public static implicit operator A(B obj)
{
return new A();
}
}
El pro$lema de este tipo de errores es )ue puede resulta di&.cil descu$rir sus causas en
tanto )ue el mensaje )ue el compilador emite indica )ue no se pueden con(ertir los
o$jetos A en o$jetos B pero no aclara )ue ello se de$a a una am$igaedad*
Ltro error con el )ue /a+ )ue tener cuidado es con el /ec/o de )ue puede ocurrir )ue al
mezclar rede&iniciones impl.citas con mtodos so$recargados puedan /a$er
am$iguedades al determinar a )u (ersin del mtodo se /a de llamar* Por ejemplo%
dado el cdigo3
using System;
class A
{
public static implicit operator A(B obj)
{
return new A();
}
public static void MtodoSobrecargado(A o)
{
Console.WriteLine("Versin que toma A");
}
public static void MtodoSobrecargado(C o)
{
Console.WriteLine("Versin que toma C");
}
static void Main(string[] args)
{
MtodoSobrecargado(new B());
}
}
class B
{
public static implicit operator C(B obj)
{
return new C();
}
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
}
class C
{}
Al compilarlo se producir un error de$ido a )ue en la llamada a MtodoSobrecargado()
el compilador no puede deducir a )u (ersin del mtodo se desea llamar +a )ue e-isten
con(ersiones impl.ctas de o$jetos de tipo B en cual)uiera de los tipos admitidos por sus
distintas (ersiones* Para resol(erlo lo mejor especi&icar e-pl.citamente en la llamada la
con(ersin a aplicar usando el operador () Por ejemplo% para usar usar la (ersin del
mtodo )ue toma como parmetro un o$jeto de tipo A se podr.a /acer3
MtodoSobrecargado ( (A) new B());
Sin em$argo% /a+ )ue tener cuidado +a )ue si en (ez del cdigo anterior se tu(iese3
class A
{
public static implicit operator A(B obj)
{
return new A();
}
public static void MtodoSobrecargado(A o)
{
Console.WriteLine("Versin que toma A");
}
public static void MtodoSobrecargado(C o)
{
Console.WriteLine("Versin que toma C");
}
static void Main(string[] args)
{
MtodoSobrecargado(new B());
}
}
class B
{
public static implicit operator A(B obj)
{
return new A();
}
public static implicit operator C(B obj)
{
return new C();
}
}
class C
{}
Entonces el &uente compilar.a con normalidad + al ejecutarlo se mostrar.a el siguiente
mensaje )ue demuestra )ue se /a usado la (ersin del mtodo )ue toma un o$jeto C*
El lenguaje de programacin C# 5ema 113 >ede&inicin de operadores
Winalmente% /a+ )ue se1alar )ue no es posi$le de&inir cual)uier tipo de con(ersin% sino
)ue a)uellas para los )ue +a e-ista un mecanismo prede&inido en el lenguaje no son
(lidas* Es decir% no pueden de&inirse con(ersiones entre un tipo + sus antecesores Apor
el polimor&ismo +a e-istenB% ni entre un tipo + l mismo% ni entre tipos e inter&aces por
ellos implementadas Alas inter&aces se e-plicarn en el Tema %2: "nter0a$esB
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
TEMA 12: DeIegados y eventos
Concepto de delegado
Kn 51-1=95. es un tipo especial de clase cu+os o$jetos pueden almacenar re&erencias a
uno o ms mtodos de tal manera )ue a tra(s del o$jeto sea posi$le solicitar la
ejecucin en cadena de todos ellos*
?os delegados son mu+ ,tiles +a )ue permiten disponer de o$jetos cu+os mtodos
puedan ser modi&icados dinmicamente durante la ejecucin de un programa* Ce /ec/o%
son el mecanismo $sico en el )ue se $asa la escritura de aplicaciones de (entanas en la
plata&orma *4E5* Por ejemplo% si en los o$jetos de una clase Button )ue represente a los
$otones estndar de Hindo=s de&inimos un campo de tipo delegado% podemos
conseguir )ue cada $otn )ue se cree ejecute un cdigo di&erente al ser pulsado sin ms
)ue almacenar el cdigo a ejecutar por cada $otn en su campo de tipo delegado + luego
solicitar la ejecucin todo este cdigo almacenado cada (ez )ue se pulse el $otn*
Sin em$argo% tam$in son ,tiles para muc/.simas otras cosas tales como asociacin de
cdigo a la carga + descarga de ensam$lados% a cam$ios en $ases de datos% a cam$ios en
el sistema de arc/i(os% a la &inalizacin de operaciones as.ncronas% la ordenacin de
conjuntos de elementos% etc* En general% son ,tiles en todos a)uellos casos en )ue
interese pasar mtodos como parmetros de otros mtodos*
Adems% los delegados proporcionan un mecanismos mediante el cual unos o$jetos
pueden solicitar a otros )ue se les noti&i)ue cuando ocurran ciertos sucesos* Para ello%
$astar.a seguir el patrn consistente en /acer )ue los o$jetos noti&icadores dispongan de
alg,n campo de tipo delegado + /acer )ue los o$jetos interesados almacenen mtodos
su+os en dic/os campos de modo )ue cuando ocurra el suceso apropiado el o$jeto
noti&icador simule la noti&icacin ejecutando todos los mtodos as. asociados a l*
*
)efinicin de delegados
Kn delegado no es ms )ue un tipo especial de su$clase System.MuIticastDeIegate* Sin
em$argo% para de&inir estas clases no se puede utilizar el mecanismo de /erencia normal
sino )ue /a de seguirse la siguiente sinta-is especial3
<modi!icadores> deIegate <tipoRetorno> <nombreDelegado> (<parmetros>);
<nombreDelegado> ser el nom$re de la clase delegado )ue se de&ine% mientras )ue
<tipoRetorno> + <parmetros> se correspondern% respecti(amente% con el tipo del (alor
de retorno + la lista de parmetros de los mtodos cu+os cdigos puede almacenar en su
interior los o$jetos de ese tipo delegado A.C>13.; 51-1=95.;B
Kn ejemplo de cmo de&inir un delegado de nom$re Deleg cu+os o$jetos puedan
almacenar mtodos )ue de(uel(an un string + tomen como parmetro un int es3
delegate string Deleg(int valor);
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
?os o$jetos delegados de este tipo slo podrn almacenar cdigos de mtodos )ue no
de(uel(an nada + tomen un ,nico parmetro de tipo int* Cual)uier intento de almacenar
mtodos con otras caracter.sticas producir un error de compilacin o% si no puede
detectarse al compilar% una e-cepcin de tipo System.ArgumentNuIIException en tiempo
de ejecucin tal + como muestra el siguiente programa de ejemplo3
using System;
using System.Reflection;
public delegate void D();
public class ComprobacinDelegados
{
public static void Main()
{
Type t = typeof(ComprobacinDelegados);
Methodnfo m = t.GetMethod(Mtodo1);
D obj = (D) Delegate.CreateDelegate(typeof(D), m);
obj();
}
public static void Mtodo1()
{ Console.WriteLine(Ejecutado Mtodo1); }
public static void Mtodo2(string s)
{ Console.WriteLine(Ejecutado Mtodo2); }
}
?o )ue se /ace en el mtodo Main() de este programa es crear a partir del o$jeto Type
)ue representa al tipo ComprobacinDelegados un o$jeto System.RefIection.MethodInfo
)ue representa a su mtodo Mtodo1* Como se (e% para crear el o$jeto Type se utiliza el
operador typeof +a estudiado% + para o$tener el o$jeto MethodInfo se usa su mtodo
GetMethod() )ue toma como parmetro una cadena con el nom$re del mtodo cu+o
MethodInfo desee o$tenerse* Kna (ez conseguido% se crea un o$jeto delegado de tipo D
)ue almacene una re&erencia al mtodo por l representado a tra(s del mtodo
CreateDeIegate() de la clase DeIegate + se llama dic/o o$jeto% lo )ue muestra el mensaje3
@7ecutado MPtodoC
Aun)ue en (ez de o$tener el MethodInfo )ue representa al Mtodo1 se /u$iese o$tenido
el )ue representa al Mtodo2 el compilador no detectar.a nada raro al compilar +a )ue no
es lo $astante inteligente como para sa$er )ue dic/o o$jeto no representa a un mtodo
almacena$le en o$jetos delegados de tipo D* Sin em$argo% al ejecutarse la aplicacin el
C?> s. )ue lo detectar.a + ello pro(ocar.a una ArgumentNuIIException
<sto es un di&erencia importante de los delegados respecto a los punteros a &uncin de
CJC'' A)ue tam$in pueden almacenar re&erencias a mtodosB% +a )ue con estos ,ltimos
no se realizan dic/as compro$aciones en tiempo de ejecucin + puede terminar
ocurriendo )ue un puntero a &uncin apunte a un mtodo cu+a signatura o (alor de
retorno no se correspondan con los indicados en su de&inicin% lo )ue puede ocasionar
)ue el programa &alle por causas di&.ciles de detectar*
?as de&iniciones de delegados tam$in pueden incluir cual)uiera de los modi&icadores
de accesi$ilidad (lidos para una clase% +a )ue al &in + al ca$o los delegados son clases*
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
Es decir% todos pueden incluir los modi&icadores pubIic e internaI% + los se de&inan
dentro de otro tipo tam$in pueden incluir protectedP private + protected internaI*
Manipulacin de ob'etos delegados
Kn o$jeto de un tipo delegado se crea e-actamente igual )ue un o$jeto de cual)uier
clase slo )ue en su constructor /a de pasrsele el nom$re del mtodo cu+o cdigo
almacenar* Este mtodo puede tanto ser un mtodo esttico como uno no esttico* En
el primer caso se indicar.a su nom$re con la sinta-is <nombreTipo>.<nombreMtodo>, +
en el segundo se indicar.a con <objeto>.<nombreMtodo>
Para llamar al cdigo almacenado en el delegado se usa una sinta-is similar a la de las
llamadas a mtodos% slo )ue no /a+ )ue pre&ijar el o$jeto delegado de ning,n nom$re
de tipo o de o$jeto + se usa simplemente <objetoDelegado>(<valoresParmetros>)
El siguiente ejemplo muestra cmo crear un o$jeto delegado de tipo D% asociarle el
cdigo de un mtodo llamado F + ejecutar dic/o cdigo a tra(s del o$jeto delegado3
using System;
delegate void D(int valor);
class EjemploDelegado
{
public static void Main()
{
D objDelegado = new D(F);
objDelegado(3);
}
public static void F(int x)
{
Console.WriteLine( Pasado valor {0} a F());
}
}
?a ejecucin de este programa producir la siguiente salida por pantalla3
4asado 2alor ( a G(%
4tese )ue para asociar el cdigo de F() al delegado no se /a indicado el nom$re de este
mtodo esttico con la sinta-is <nombreTipo>.<nombreMtodo> antes comentada* Esto se
de$e a )ue no es necesario incluir el <nombreTipo>* cuando el mtodo a asociar a un
delegado es esttico + est de&inido en el mismo tipo )ue el cdigo donde es asociado
En realidad un o$jeto delegado puede almacenar cdigos de m,ltiples mtodos tanto
estticos como no estticos de manera )ue una llamada a tra(s su+a produzca la
ejecucin en cadena de todos ellos en el mismo orden en )ue se almacenaron en l*
4tese )ue si los mtodos de(uel(en alg,n (alor% tras la ejecucin de la cadena de
llamadas slo se de(ol(er el (alor de retorno de la ,ltima llamada*
Adems% cuando se realiza una llamada a tra(s de un o$jeto delegado no se tienen en
cuenta los modi&icadores de (isi$ilidad de los mtodos )ue se ejecutarn% lo )ue permite
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
llamar desde un tipo a mtodos pri(ados de otros tipos )ue estn almacenados en un
delegado por accesi$le desde el primero tal + como muestra el siguiente ejemplo3
using System;
public delegate void D();
class A
{
public static D obj;
public static void Main()
{
B.AlmacenaPrivado();
obj();
}
}
class B
{
private static void Privado()
{ Console.WriteLine(Llamado a mtodo privado); }
public static void AlmacenaPrivado()
{ A.obj += new D(Privado); }
}
?a llamada a AlmacenaPrivado en el mtodo Main() de la clase A pro(oca )ue en el campo
delegado obj de dic/a clase se almacene una re&erencia al mtodo pri(ado Privado() de la
clase B% + la instruccin siguiente pro(oca la llamada a dic/o mtodo pri(ado desde una
clase e-terna a la de su de&inicin como demuestra la salida del programa3
Llamado a mPtodo 5ri2ado
Para a1adir nue(os mtodos a un o$jeto delegado se le aplica el operador += pasndole
como operando derec/o un o$jeto delegado de su mismo tipo Ano (ale de otro aun)ue
admita los mismos tipos de parmetros + (alor de retornoB )ue contenga los mtodos a
a1adirle% + para )uitrselos se /ace lo mismo pero con el operador -=* Por ejemplo% el
siguiente cdigo muestra los e&ectos de am$os operadores3
using System;
delegate void D(int valor);
class EjemploDelegado
{
public string Nombre;
EjemploDelegado(string nombre)
{
Nombre = nombre;
}
public static void Main()
{
EjemploDelegado obj1 += new EjemploDelegado(obj1);
D objDelegado = new D(f);
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
objDelegado += new D(obj1.g);
objDelegado(3);
objDelegado -= new D(obj1.g);
objDelegado(5);
}
public void g(int x)
{
Console.WriteLine(Pasado valor {0} a g() en objeto {1}, x, Nombre);
}
public static void f(int x)
{
Console.WriteLine( Pasado valor {0} a f(), x);
}
}

?a salida producida por pantalla por este programa ser3
4asado 2alor ( a <(%
4asado 2alor ( a g(% en o-7eto o-7C
4asado 2alor 5 a <(%
Como se (e% cuando a/ora se /ace la llamada objDelegado(3) se ejecutan los cdigos de
los dos mtodos almacenados en objDelegado% + al )uitrsele luego uno de estos cdigos
la siguiente llamada slo ejecuta el cdigo del )ue )ueda* 4tese adems en el ejemplo
como la rede&inicin de + realizada para los delegados permite )ue se pueda inicializar
objDelegado usando += en (ez de =* Es decir% si uno de los operandos de + (ale nuII no
se produce ninguna e-cepcin% sino )ue tan slo no se a1ade ning,n mtodo al otro*

8a+ )ue se1alar )ue un o$jeto delegado (ale nuII si no tiene ning,n mtodo asociado%
+a sea por)ue no se /a llamado a,n a su constructor o por)ue los )ue tu(iese asociado
se le /a+an )uitado con -=* As.% si al Main() del ejemplo anterior le a1adimos al &inal3
objDelegado -= new D(f);
objDelegado(6);
Se producir al ejecutarlo una e-cepcin de tipo System.NuIIReferenceException
indicando )ue se /a intentado acceder a una re&erencia nula*
5am$in /a+ )ue se1alar )ue para )ue el operador -= &uncione se le /a de pasar como
operador derec/o un o$jeto delegado )ue almacene alg,n mtodo e-actamente igual al
mtodo )ue se le )uiera )uitar al o$jeto delegado de su lado iz)uierdo* Por ejemplo% si
se le )uiere )uitar un mtodo de un cierto o$jeto% se le /a de pasar un o$jeto delegado
)ue almacene ese mtodo de ese mismo o$jeto% + no (ale )ue almacene ese mtodo pero
de otro o$jeto de su mismo tipo* Por ejemplo% si al Main() anterior le a1adimos al &inal3
objDelegado -= new g(obj1.g);
objDelegado(6);
Entonces no se producir ninguna e-cepcin +a )ue el -= no eliminar ning,n mtodo
de objDelegado de$ido a )ue ese o$jeto delegado no contiene ning,n mtodo g()
procedente del o$jeto obj1* Es ms% la salida )ue se producir por pantalla ser3

4asado 2alor ( a <(%
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
4asado 2alor ( a g(% en o-7eto o-7C
4asado 2alor 5 a <(%
4asado 2alor R a <(%
La clase "%stem.Multicast)elegate
Va se /a dic/o )ue la sinta-is especial de de&inicin de delegados no es ms )ue una
&orma especial de&inir su$clases de System.MuIticastDeIegate* Esta clase a su (ez deri(a
de System.DeIegate% )ue representa a o$jetos delegados )ue slo puede almacenar un
,nico mtodo* Por tanto% todos los o$jetos delegado )ue se de&inan contarn con los
siguientes miem$ros comunes /eredados de estas clases3

object Target3 Propiedad de slo lectura )ue almacena el o$jeto al )ue pertenece
el ,ltimo mtodo a1adido al o$jeto delegado* Si es un mtodo de clase (ale nuII*
MethodInfo Method3 Propiedad de slo lectura )ue almacena un o$jeto
System.RefIection.MethodInfo con in&ormacin so$re el ,ltimo mtodo a1adido
al o$jeto Anom$re% modi&icadores% etc*B Para sa$er cmo acceder a estos datos
puede consultar la documentacin incluida en el SCD so$re la clase MethodInfo

DeIegate[] getInvocationList()3 Permite acceder a todos los mtodos almacenados
en un delegado% +a )ue de(uel(e una ta$la cu+os elementos son delegados cada
uno de los cuales almacenan uno% + slo uno% de los mtodos del original* Estos
delegados se encuentran ordenados en la ta$la en el mismo orden en )ue sus
mtodos &ueron &ue almacenados en el o$jeto delegado original*
Este mtodo es especialmente ,til por)ue a tra(s de la ta$la )ue retorna se
pueden /acer cosas tales como ejecutar los mtodos del delegado en un orden
di&erente al de su almacenamiento% procesar los (alores de retorno de todas las
llamadas a los mtodos del delegado original% e(itar )ue una e-cepcin en la
ejecucin de uno de los mtodos impida la ejecucin de los dems% etc*
Aparte de estos mtodos de o$jeto% la clase System.MuIticastDeIegate tam$in cuenta
con los siguientes mtodos de tipo de uso &recuente3
static DeIegate Combine(DeIegate fuente, DeIegate destino)3 Ce(uel(e un nue(o
o$jeto delegado )ue almacena la concatenacin de los mtodos de fuente con los
de destino* Por tanto% ntese )ue estas tres instrucciones son e)ui(alentes3
objDelegado += new D(obj1.g);
objDelegado = objDelegado + new D(obj1.g);
objDelegado = (D) MulticastDelegate.Combine(objDelegado, new D(obj1.g);
Es ms% en realidad el compilador de C# lo )ue /ace es con(ertir toda aplicacin
del operador + entre delegados en una llamada a Combine() como la mostrada*
8a+ )ue tener cuidado con los tipos de los delegados a com$inar +a )ue /an de
ser e-ctamente los mismos o si no se lanza una System.ArgumentException% +
ello ocurre a,n en el caso de )ue dic/os slo se di&erencien en su nom$re + no
en sus tipos de parmetros + (alor de retorno*
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
static DeIegate Combine(DeIegate[] tabIa)3 Ce(uel(e un nue(o delegado cu+os
mtodos almacenados son la concatenacin de todos los de la lista )ue se le pasa
como parmetro + en el orden en )ue apareciesen en ella* Es una $uena &orma de
crear delegados con muc/os mtodos sin tener )ue aplicar += (arias (eces*
5odos los o$jetos delegados de la tabla /an de ser del mismo tipo% pues si no se
producir.a una System.ArgumentException*
static DeIegate Remove(DeIegate originaI, DeIegate aBorrar)3 Ce(uel(e un nue(o
delegado cu+os mtodos almacenados son el resultado de eliminar de original los
)ue tu(iese aBorrar* Por tanto% estas instrucciones son e)ui(alentes3
objDelegado -= new D(obj1.g);
objDelegado - objDelegado - new D(obj1.g);
objDelegado = (D) MulticastDelegate.Remove(objDelegado, new D(obj1.g);
4ue(amente% lo )ue /ace el compilador de C# es con(ertir toda aplicacin del
operador - entre delegados en una llamada a Remove() como la mostrada* Por
tanto% al igual )ue con -=% para $orrar mtodos de o$jeto se /a de especi&icar en
aBorrar un o$jeto delegado )ue contenga re&erencias a mtodos asociados a
e-ctamente los mismos o$jetos )ue los almacenados en original*
static DeIegate CreateDeIegate (Type tipo, MehodInfo mtodo)3 Va se us este
mtodo en el ejemplo de compro$acin de tipos del ep.gra&e 4De0ini$i)n de
dele(ados5 de este mismo tema* Como recordar pemrite crear dinmicamente
o$jetos delegados% +a )ue de(uel(e un o$jeto delegado del tipo indicado )ue
almacena una re&erencia al mtodo representado por su segundo parmetro*
Llamadas as#ncronas
?a &orma de llamar a mtodos )ue /asta a/ora se /a e-plicado realiza la llamada de
manera ;L264.29% lo )ue signi&ica )ue la instruccin siguiente a la llamada no se ejecuta
/asta )ue no &inalice el mtodo llamado* Sin em$argo% a todo mtodo almacenado en un
o$jeto delegado tam$in es posi$le llamarde manera 9;L264.29 a tra(s de los mtodos
del mismo% lo )ue consiste en )ue no se espera a )ue aca$e de ejecutarse para pasar a la
instruccin siguiente a su llamada sino )ue su ejecucin se deja en manos de un /ilo
aparte )ue se ir ejecutndolo en paralelo con el /ilo llamante*

Por tanto los delegados proporcionan un cmodo mecanismo para ejecutar cual)uier
mtodo as.ncronamente% pues para ello $asta introducirlo en un o$jeto delegado del tipo
apropiado* Sin em$argo% este mecanismo de llamada as.ncrona tiene una limitacin% + es
)ue slo es (lido para o$jetos delegados )ue almacenen un ,nico mtodo*
Para /acer posi$le la llamadas as.ncronas% aparte de los mtodos /eredados de
System.MuIticastDeIegate todo o$jeto delegado cuenta con estos otros dos mtodos )ue
el compilador de&ine a su medida en al clase en )ue traduce la de&inicin de su tipo3

IAsyncResuIt BeginInvoke(<parmetros>, AsyncCaIIback cb, Object o)
<tipoRetorno> EndInvoke(<parmetros"e!#ut>, IASyncResuIt ar)
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
BeginInvoke() crea un /ilo )ue ejecutar los mtodos almacenados en el o$jeto delegado
so$re el )ue se aplica con los parmetros indicados en <parmetros> + de(uel(e un
o$jeto IAsyncResuIt )ue almacenar in&ormacin relati(a a ese /ilo Apor ejemplo% a
tra(s de su propiedad de slo lectura booI IsCompIete puede consultarse si /a
terminado su la$orB Slo tiene sentido llamarlo si el o$jeto delegado so$re el )ue se
aplica almacena un ,nico mtodo% pues si no se lanza una System.ArgumentException*
El parmetro cb de BeginInvoke() es un o$jeto de tipo delegado )ue puede almacenar
mtodos a ejecutar cuando el /ilo antes comentado &inalice su tra$ajo* A estos mtodos
el C?> les pasar automticamente como parmetro el IAsyncResuIt de(uelto por
BeginInvoke()% estndo as. de&inido el delegado destinado a almacenarlos3
public delegate void ASyncCallback(ASyncResult obj);
Por su parte% el parmetro o de BeginInvoke puede usarse para almacenar cual)uier
in&ormacin adicional )ue se considere oportuna* Es posi$le acceder a l a tra(s de la
propiedad object AsyncState del o$jeto IAsyncResuIt de(uelto por BeginInvoke()
En caso de )ue no se desee ejecutar ning,n cdigo especial al &inalizar el /ilo de
ejecucin as.ncrona o no desee usar in&ormacin adicional% puede darse sin ning,n tipo
de pro$lema el (alor nuII a los ,ltimos parmetros de BeginInvoke() seg,n corresponda*
Winalmente% EndInvoke() se usa para recoger los resultados de la ejecucin as.ncrona de
los mtodos iniciada a tra(s BeginInvoke() Por ello% su (alor de retorno es del mismo
tipo )ue los mtodos almacena$les en el o$jeto delegado al )ue pertenece + en
<parmetrosRefOut> se indican los parmetros de salida + por re&erencia de dic/os
mtodos* Su tercer parmetro es el IAsyncResuIt de(uelto por el BeginInvoke() )ue cre
el /ilo cu+os se solicita recoger + se usa precisamente para identi&icarlo* En caso de )ue
ese /ilo no /a+a terminado a,n de /acer las llamadas se esperar a )ue lo /aga*
Para ilustrar mejor el concepto de llamadas as.ncronas% el siguiente ejemplo muestra
cmo encapsular en un o$jeto delegado un mtodo F() para ejecutarlo as.ncronamente3
D objDelegado = new D (F);
AsyncResult hilo = objDelegado.Beginnvoke(3, new AsyncCallback(M), prueba);
// ... Hacer cosas
objDelegado.Endnvoke(hilo);
Conde el mtodo M /a sido de&inido en la misma clase )ue este cdigo as.3
public static void M(AsyncResult obj)
{
Console.WriteLine(Llamado a M() con {0}, obj.AsyncState);
}
Si entre el BeginInvoke() + el EndInvoke() no /u$iese /a$ido ninguna escritura en
pantalla% la salida del &ragmento de cdigo anterior ser.a3
4asado 2alor ( a G(%
Llamado a M(% con 5rue-a
?a llamada a BeginInvoke() lanzar un /ilo )ue ejecutar el mtodo F() almacenado en
objDelegado% pero mientras tanto tam$in seguir ejecutndose el cdigo del /ilo desde
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
donde se llam a BeginInvoke() Slo tras llamar a EndInvoke() se puede asegurar )ue se
/a$r ejecutado el cdigo de F()% pues mientras tanto la e(olucin de am$os /ilos es
prcticamente indetermina$le +a )ue depende del cmo act,e el plani&icador de /ilos*
A,n si el /ilo llamador modi&ica el (alor de alguno de los parmetros de salida o por
re&erencia de tipos (alor% el (alor actualizado de stos no ser (isi$le para el /ilo
llamante /asta no llamar a EndInvoke() Sin em$argo% el (alor de los parmetros de tipos
re&erencia s. )ue podr.a serlo* Por ejemplo% dado un cdigo como3
int x=0;
Persona p = new Persona(Josan, 7361928-E, 22);
AsyncResult res = objetoDelegado.Beginnvoke(ref x, p, null, null);
// Hacer cosas...
objetoDelegado.Endnvoke(ref x, res);
Si en un punto del cdigo comentado con // Hacer cosas... donde el /ilo as.ncrono +a
/u$iese modi&icado los contenidos de x + p se intentase leer los (alores de estas
(aria$les slo se leer.a el (alor actualizado de p% mientras el de x no se (er.a /asta
despus de la llamada a EndInvoke()
Por otro lado% /a+ )ue se1alar )ue si durante la ejecucin as.ncrona de un mtodo se
produce alguna e-cepcin% sta no ser.a noti&icada pero pro(ocar.a )ue el /ilo as.ncrono
a$ortase* Si posteriormente se llamase a EndInvoke() con el IAsyncResuIt asociado a
dic/o /ilo% se relanzar.a la e-cepcin )ue produjo el a$orto + entonces podr.a tratarse*
Para optimizar las llamadas as.ncronas es recomenda$le marcar con el atri$uto OneWay
de&inido en System.Runtime.Remoting.Messaging los mtodos cu+o (alor de retorno +
(alores de parmetros de salida no nos importen% pues ello indica a la in&raestructura
encargada de /acer las llamadas as.ncronas )ue no /a de considerar* Por ejemplo3
S/neWayT 5u-lic 2oid MPtodo(%
{!
A/ora $ien% /a+ )ue tener en cuenta )ue /acer esto implica perder toda posi$ilidad de
tratar las e-cepciones )ue pudiese producirse al ejecutar as.ncronamente el mtodo
atri$uido% pues con ello llamar a EndInvoke() dejar.a de relanzar la e-cepcin producida*
Por ,ltimo% a modo de resumen a continuacin se indican cules son los patrones )ue
pueden seguirse para recoger los resultados de una llamada as.ncrona3
1* Cetectar si la llamada as.ncrona /a &inalizado mirando el (alor de la propiedad
IsCompIete del o$jeto IAsyncResuIt de(uelto por BeginInvoke() Cuando sea as.%
con EndInvoke() puede recogerse sus resultados*
* Pasar un o$jeto delegado en el pen,ltimo parmetro de BeginInvoke() con el
mtodo a ejecutar cuando &inalice el /ilo as.ncrono% lo )ue li$erar.a al /ilo
llamante de la tarea de tener )ue andar mirando si /a &inalizado o no*
Si desde dic/o mtodo se necesitase acceder a los resultados del mtodo llamado
podr.a accederse a ellos a tra(s de la propiedad AsyncDeIegate del o$jeto
IAsyncResuIt )ue reci$e* Esta propiedad contiene el o$jeto delegado al )ue se
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
llam% aun)ue se muestra a continuacin antes de acceder a ella /a+ )ue
con(ertir el parmetro IAsyncResuIt de ese mtodo en un AsyncResuIt3
public static void M(AsyncResult iar)
{
D objetoDelegado = (D) ((AsyncResult iar)).AsyncDelegate;
// A partir de aqu podra llamarse a Endnvoke() a travs de objetoDelegado
}
!mplementacin interna de los delegados
Cuando /acemos una de&inicin de delegado de la &orma3
<modificadores> deIegate <tipoRetorno> <nombre>(<parmetros>);
El compilador internamente la trans&orma en una de&inicin de clase de la &orma3
<modificadores> cIass <nombre>:System.MuIticastDeIegate
{
private object _target;
private int _methodPtr;
private MuIticastDeIegate _prev;
pubIic <nombre>(object objetivo, int punteroMtodo)
{...}
pubIic virtuaI <tipoRetorno> Invoke(<parmetros>)
{...}

pubIic virtuaI IAsyncResuIt BeginInvoke(<parmetros>, AsyncCaIIback cb, Object o)
Q***R
pubIic virtuaI <tipoRetorno> EndInvoke(<parmetros"e!#ut>, IASyncResuIt ar)
{...}
}
?o primero )ue llama la atencin al leer la de&inicin de esta clase es )ue su constructor
no se parece en a$soluto al )ue /emos estado usando /asta a/ora para crear o$jetos
delegado* Esto se de$e a )ue en realidad% a partir de los datos especi&icados en la &orma
de usar el constructor )ue el programador utiliza% el compilador es capaz de determinar
los (alores apropiados para los parmetros del (erdadero constructor% )ue son3
object objetivo contiene el o$jeto al cual pertenece el mtodo especi&icado% + su
(alor se guarda en el campo _target* Si es un mtodo esttico almacena nuII*
int punteroMtodo contiene un entero )ue permite al compilador determinar cul
es el mtodo del o$jeto al )ue se desea llamar% + su (alor se guarda en el campo
S?13J.5P34* Seg,n donde se /a+a de&inido dic/o mtodo% el (alor de este
parmetro proceder de las ta$las MethodDef o MethodRef de los metadatos*
El campo pri(ado _prev de un delegado almacena una re&erencia al delegado pre(io al
mismo en la cadena de mtodos* En realidad% en un o$jeto delegado con m,ltiples
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
mtodos lo )ue se tiene es una cadena de o$jetos delegados cada uno de los cuales
contiene uno de los mtodos + una re&erencia Aen _prevB a otro o$jeto delegado )ue
contendr otro de los mtodos de la cadena*
Cuando se crea un o$jeto delegado con new se da el (alor nuII a su campo _prev para as.
indicar )ue no pertenece a una cadena sino )ue slo contiene un mtodo* Cuando se
com$inen dos o$jetos delegados Acon + o DeIegate.Combine()B el campo _prev del nue(o
o$jeto delegado creado enlazar a los dos originalesU + cuando se eliminen mtodos de
la cadena Acon - o DeIegate.Remove()B se actualizarn los campos _prev de la cadena
para )ue salten a los o$jetos delegados )ue conten.an los mtodos eliminados*
Cuando se solicita la ejecucin de los mtodos almacenados en un delegado de manera
as.ncrona lo )ue se /ace es llamar al mtodo Invoke() del mismo* Por ejemplo% una
llamada como esta3
objDelegado(49);
Es con(ertida por el compilador en3
objDelegado.nvoke(49);
Aun)ue Invoke() es un mtodo p,$lico% C# no permite )ue el programador lo llame
e-pl.citamente* Sin em$argo% otros lenguajes gestionados s. )ue podr.an permitirlo*
El mtodo Invoke() se sir(e de la in&ormacin almacenada en _target% _methodPtr +
_prev% para determinar a cul mtodo se /a de llamar + en )u orden se le /a de llamar*
As.% la implementacin de Invoke() ser de la &orma3
pubIic virtuaI <tipoRetorno> Invoke(<parmetros>)
{
if (_prev!=nuII)
_prev.Invoke(<parmetros>);
return _target._methodPtr(<parmetros>);
}
L$(iamente la sinta-is S394=13.?13J.5P34 no es (lida en C#% +a )ue S?13J.5P34 no
es un mtodo sino un campo* Sin em$argo% se /a escrito as. para poner de mani&iesto
)ue lo )ue el compilador /ace es generar el cdigo apropiado para llamar al mtodo
perteneciente al o$jeto indicado en _target e identi&icado con el (alor de _methodPtr
4tese )ue la instruccin if incluida se usa para asegurar )ue las llamadas a los mtodos
de la cadena se /agan en orden3 si el o$jeto delegado no es el ,ltimo de la cadena*
AS<41ATU20--B se llamar antes al mtodo I2A.E1() de su predecesor*
Por ,ltimo% slo se1alar )ue% como es lgico% en caso de )ue los mtodos )ue el o$jeto
delegado pueda almacenar no tengan (alor de retorno Aste sea voidB% el cuerpo de
Invoke() slo (ar.a en )ue la pala$ra reser(ada return es eliminada del mismo*
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
Eventos
Concepto de evento
Kn 1A123. es una (ariante de las propiedades para los campos cu+os tipos sean
delegados* Es decir% permiten controlar la &orman en )ue se accede a los campos
delegados + dan la posi$ilidad de asociar cdigo a ejecutar cada (ez )ue se a1ada o
elimine un mtodo de un campo delegado*
Sintaxis bsica de definicin de deIegados
?a sinta-is $sica de de&inicin de un e(ento consiste en de&inirlo como cual)uier otro
campo con la ,nica peculiaridad de )ue se le /a de anteponer la pala$ra reser(ada event
al nom$re de su tipo A)ue ser un delegadoB L sea% se sigue la sinta-is3
<modificadores> event <tipoDelegado> <nombreEvento>;
Por ejemplo% para de&inir un e(ento de nom$re Prue$a + tipo delegado C se /ar.a3
public event D PruebaU
5am$in pueden de&inirse m,ltiples e(entos en una misma l.nea separando sus nom$res
mediante comas* Por ejemplo3
public event D Prueba1, Prueba2;
Cesde cdigo u$icado dentro del mismo tipo de dato donde se /a+a de&inido el e(ento
se puede usar el e(ento tal + como si de un campo delegado normal se tratase* Sin
em$argo% desde cdigo u$icado e-ternamente se imponen una serie de restricciones )ue
permite controlar la &orma en )ue se accede al mismo* <stas son3
4o se le puede aplicar los mtodos /eredados de System.MuIticastDeIegate*
Slo se le puede aplicar dos operaciones3 a1adido de mtodos con += +
eliminacin de mtodos con -=* Ce este modo se e(ita )ue se use sin )uerer = en
(ez de += -= + se sustitu+an todos los mtodos de la lista de mtodos del
campo delegado por otro )ue en realidad se le )uer.a a1adir o )uitar Asi ese otro
(aliese nuII% ello incluso podr.a pro(ocar una System.NuIIReferenceException)
4o es posi$le llamar a los mtodos almacenados en un campo delegado a tra(s
del mismo* Esto permite controlar la &orma en )ue se les llama% +a )ue o$liga a
)ue la llamada tenga )ue /acerse a tra(s de alg,n mtodo p,$lico de&inido en la
de&inicin del tipo de dato donde el e(ento &ue de&inido*
Sintaxis compIeta de definicin de deIegados
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
?a (erdadera utilidad de un e(ento es )ue permite controlar la &orma en )ue se asocian +
)uitan mtodos de los o$jetos delegados con += + -=* Para ello se /an de de&inir con la
siguiente sinta-is a(anzada3
<modificadores> event <tipoDelegado> <nombreEvento>
{
add
{
<cdigoAdd>
}
remove
{
<cdigoRemove>
}
}
Con esta sinta-is no pueden de&inirse (arios e(entos en una misma l.nea como ocurr.a
con la $sica* Su signi&icado es el siguiente3 cuando se asocie un mtodo con += al
e(ento se ejecutar el <cdigoAdd>% + cuando se le )uite alguno con -= se ejecutar el
<cdigoRemove>* Esta sinta-is es similar a la de los $lo)ues setVget de las propiedades
pero con una importante di&erencia3 aun)ue pueden permutarse las secciones add +
remove% es o$ligatorio incluir siempre a am$as*
?a sinta-is $sica es en realidad una &orma a$re(iada de usar la a(anzada* As.% la
de&inicin public event D Prueba(int valor); la interpretar.a el compilador como3

private D prueba
public event D Prueba
{
[Methodmpl(MethodmlOptions.Synchronized)]
add
{
prueba = (D) Delegate.Combine(prueba, value);
}
[Methodmpl(MethodmlOptions.Synchronized)]
remove
{
prueba = (D) Delegate.Remove(prueba, value);
}
}
Es decir% el compilador de&inir un campo delegado pri(ado + cdigos para add +
remove )ue /agan )ue el uso de += + -= so$re el e(ento tenga el e&ecto )ue normalmente
tendr.an si se aplicasen directamente so$re el campo pri(ado* Como se (e% dentro de
estos mtodos se puede usar vaIue para /acer re&erencia al operando derec/o de los
operadores += + -=* El atri$uto System.Runtime.InteropServices.MethodImpI )ue precede
a los $lo)ues add + remove slo se inclu+e para asegurar )ue un cam$io de /ilo no
pueda interrumpir la ejecucin de sus cdigos asociados*
?as restricciones de uso de e(entos desde cdigos e-ternos al tipo donde se /an de&inido
se de$en a )ue en realidad stos no son o$jetos delegados sino )ue el o$jeto delegado es
el campo pri(ado )ue internamente de&ine el compilador* El compilador traduce toda
El lenguaje de programacin C# 5ema 13 Celegados + e(entos
llamada al e(ento en una llamada al campo delegado* Como este es pri(ado% por eso
slo pueda accederse a l desde cdigo de su propio tipo de dato*
En realidad% el compilador internamente traduce las secciones add + remove de la
de&inicin de un e(ento en mtodos de la &orma3
void add_<nombreEvento>(<tipoDelegado> vaIue)
void remove_<nombreEvento>(<tipoDelegado> vaIue)
5oda aplicacin de += + -= a un e(ento no es con(ertida en una llamada al campo
pri(ado sino en una llamada al mtodo addJremove apropiado% como se puede o$ser(ar
analizando el 6S#? de cual)uier &uente donde se usen += + -= so$re e(entos* Adems%
como estos mtodos de(uel(en void se ser el tipo del (alor de(uelto al aplicar += -=
A+ no el o$jeto asignadoB% lo )ue e(itar )ue cdigo e-terno al tipo donde se /a+a
de&inido el e(ento pueda acceder directamente al campo delegado pri(ado*
Si en (ez de la sinta-is $sica usamos la completa no se de&inir automticamente un
campo delegado por cada e(ento )ue se de&ina% por lo )ue tampoco ser posi$le /acer
re&erencia al mismo desde cdigo u$icado en la misma clase donde se /a de&inido* Sin
em$argo ello permite )ue el programador pueda determinar% a tra(s de secciones add +
remove% cmo se almacenarn los mtodos* Por ejemplo% para a/orrar memoria se puede
optar por usar un diccionario donde almacenar los mtodos asociados a (arios e(entos
de un mismo o$jeto en lugar de usar un o$jeto delegado por cada uno*
Cado )ue las secciones add + remove se traducen como mtodos% los e(entos tam$in
podrn participar en el mecanismo de /erencia + rede&iniciones t.pico de los mtodos*
Es decir% en <modificadores> aparte de modi&icadores de acceso + el modi&icador static%
tam$in se podrn incluir los modi&icadores relati(os a /erencia* En este sentido /a+
)ue precisar algo3 un e(ento de&inido como abstract /a de de&inirse siempre con la
sinta-is $sica Ano incluir secciones add o removeB
El lenguaje de programacin C# 5ema 1!3 Estructuras
TEMA 13: Estructuras
Concepto de estructura
Kna 1;34063049 es un tipo especial de clase pensada para representar o$jetos ligeros* Es
decir% )ue ocupen poca memoria + de$an ser manipulados con (elocidad% como o$jetos
)ue representen puntos% &ec/as% etc* Ejemplos de estructuras incluidas en la 0C? son la
ma+or.a de los tipos $sicos Ae-cepto string + objectB% + de /ec/o las estructuras junto
con la rede&inicin de operadores son la &orma ideal de de&inir nue(os tipos $sicos a
los )ue se apli)uen las misma optimizaciones )ue a los prede&inidos*
)iferencias entre clases % estructuras
A di&erencia de una clase + &ielmente a su esp.ritu de NligerezaO% una estructura no
puede deri(ar de ning,n tipo + ning,n tipo puede deri(ar de ella Por estas razones sus
miem$ros no pueden incluir modi&icadores relati(os a /erencia% aun)ue con una
e-cepcin3 pueden incluir override para rede&inir los miem$ros de System.Object*
Ltra di&erencia entre las estructuras + las clases es )ue sus (aria$les no almacenan
re&erencias a zonas de memoria dinmica donde se encuentran almacenados o$jetos sino
directamente re&erencian a o$jetos* Por ello se dice )ue las clases son 37<.; 41@1412679 +
las estructuras son 37<.; A9-.4% siendo posi$le tanto encontrar o$jetos de estructuras en
pila Ano son campos de clasesB como en memoria dinmica Ason campos de clasesB
Kna primera consecuencia de esto es )ue los accesos a miem$ros de o$jetos de tipos
(alor son muc/o ms rpidos )ue los accesos a miem$ros de pilas% +a )ue es necesario
pasar por una re&erencia menos a la /ora de acceder a ellos* Adems% el tiempo de
creacin + destruccin de estructuras tam$in es in&erior* Ce /ec/o% la destruccin de
los o$jetos almacenados en pila es prcticamente inaprecia$le +a )ue se realiza con un
simple decremento del puntero de pila + no inter(iene en ella el recolector de $asura*
Ltra consecuencia de lo anterior es )ue cuando se realicen asignaciones entre (aria$les
de tipos (alor% lo )ue se (a a copiar en la (aria$le destino es el o$jeto almacenado por la
(aria$le &uente + no la direccin de memoria dinmica a la )ue apunta$a sta* Por
ejemplo% dado el siguiente tipo Antese )ue las estructuras se de&inen igual )ue las clases
pero usando la pala$ra reser(ada struct en (ez de cIassB3
struct Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
@
El lenguaje de programacin C# 5ema 1!3 Estructuras
Si usamos este tipo en un cdigo como el siguiente3
Punto p = new Punto(10,10);
Punto p2 = p;
p2.x = 100;
Console.WriteLine(p.x);
?o )ue se mostrar por pantalla ser C* Esto se de$e a )ue el (alor de x modi&icado es
el de p2% )ue es como es una copia de p los cam$ios )ue se le /agan no a&ectarn a p*
Sin em$argo% si Punto /u$iese sido de&inido como una clase entonces s. )ue se /u$iese
mostrado por pantalla C% +a )ue en ese caso lo )ue se /a$r.a copiado en p2 /a$r.a sido
una re&erencia a la misma direccin de memoria dinmica re&erenciada por p% por lo )ue
cual)uier cam$io )ue se /aga en esa zona a tra(s de p2 tam$in a&ectar a p*
Ce lo anterior se deduce )ue la asignacin entre o$jetos de tipos estructuras es muc/o
ms lenta )ue la asignacin entre o$jetos de clases% +a )ue se /a de copiar un o$jeto
completo + no solo una re&erencia* Para ali(iar esto al pasar o$jetos de tipos estructura
como parmetros% se da la posi$ilidad de pasarlos como parmetros por re&erencia
Amodi&icador refB o parmetros de salida AoutB en (ez de como parmetros de entrada*
5odas las estructuras deri(an impl.citamente del tipo System.VaIueType% )ue a su (ez
deri(a de la clase primigenia System.Object* VaIueType tiene los mismos miem$ros )ue
su padre% + la ,nica di&erencia se1ala$le entre am$os es )ue en VaIueType se /a
rede&inido EquaIs() de modo )ue de(uel(a true si los o$jetos comparados tienen el
mismo (alor en todos sus campos + faIse si no* Es decir% la comparacin entre
estructuras con EquaIs() se realiza por (alor*
>especto a la implementacin de la igualdad en los tipos de&inidos como estructuras%
tam$in es importante tener mu+ en cuenta )ue el operador == no es en principio
aplica$le a las estructuras )ue de&ina el programador* Si se desea )ue lo tenga /a de
drsele e-pl.citamente una rede&inicin al de&inir dic/as estructuras*
$o2ing % unbo2ing
Cado )ue toda estructura deri(a de System.Object% /a de ser posi$le a tra(s del
polimor&ismo almacenar o$jetos de estos tipos en o$jetos object* Sin em$argo% esto no
puede /acerse directamente de$ido a las di&erencias semnticas + de almacenamiento
)ue e-isten entre clases + estructuras3 un object siempre /a de almacenar una re&erencia
a un o$jeto en memoria dinmica + una estructura no tiene por)u estarlo* Por ello /a de
realizrsele antes al o$jeto de tipo (alor una con(ersin conocida como C.I72=*
>ec.procamente% al proceso de con(ersin de un object )ue contenga un o$jeto de un
tipo (alor al tipo (alor original se le denomina 02C.I72=*
El proceso de $o-ing es mu+ sencillo* Consiste en en(ol(er el o$jeto de tipo (alor en un
o$jeto de un tipo re&erencia creado espec.&icamente para ello* Por ejemplo% para un
o$jeto de un tipo (alor T% el tipo re&erencia creado ser.a de la &orma3
class T_Box
{
T value;
El lenguaje de programacin C# 5ema 1!3 Estructuras
T_Box(T t)
{
value = t;
}
}
En realidad todo esto ocurre de &orma transparente al programador% el cual simplemente
asigna el o$jeto de tipo (alor a un o$jeto de tipo re&erencia como si de cual)uier
asignacin polimr&ica se tratase* Por ejemplo3
int p = new Punto(10,10);
object o = p; // boxing. Es equivalente a object o = new Punto_Box(p);
En realidad la clase en(oltorio arri$a escrita no se crea nunca% pero conceptualmente es
como si se crease* Esto se puede compro$ar (iendo a tra(s del siguiente cdigo )ue el
(erdadero tipo del o$jeto o del ejemplo anterior sigue siendo Punto A+ no Punto_BoxB3
Console.WriteLine((p is Punto));
?a salida por pantalla de este cdigo es True% lo )ue con&irma )ue se sigue
considerando )ue en realidad o almacena un Punto Arecurdese )ue el operador is slo
de(uel(e true si el o$jeto )ue se le pasa como operando iz)uierdo es del tipo )ue se le
indica como operando derec/oB
El proceso de un$o-ing es tam$in transparente al programador* Por ejemplo% para
recuperar como Punto el (alor de tipo Punto almacenado en el o$jeto o anterior se /ar.a3
p = (Punto) o; // Es equivalente a ((Punto_Box) o).value
L$(iamente durante el un$o-ing se /ar una compro$acin de tipo para asegurar )ue el
o$jeto almacenado en o es realmente de tipo Punto* Esta compro$acin es tan estricta
)ue se /a de cumplir )ue el tipo especi&icado sea e-actamente el mismo )ue el tipo
original del o$jeto% no (ale )ue sea un compati$le* Por tanto% este cdigo es in(lido3
int i = 123;
object o = i;
long l = (long) o // Error: o contiene un int, no un long
Sin em$argo% lo )ue si ser.a (lido es /acer3
long l = (long) (int) o;
Como se puede apreciar en el constructor del tipo en(oltorio creado% durante el $o-ing
el en(oltorio )ue se crea reci$e una copia del (alor del o$jeto a con(ertir% por lo )ue los
cam$ios )ue se le /agan no a&ectarn al o$jeto original* Por ello% la salida del siguiente
cdigo ser 123
Punto p = new Punto(10,10);
object o = p; // boxing
p.X = 100;
Console.WriteLine( ((Punto) o).X); // unboxing
El lenguaje de programacin C# 5ema 1!3 Estructuras
Sin em$argo% si Punto se /u$iese de&inido como una clase entonces s. )ue se mostrar.a
por pantalla un 122 +a )ue entonces no se /ar.a $o-ing en la asignacin de p a o sino
)ue se aplicar.a el mecanismo de polimor&ismo normal% )ue consiste en tratar p a tra(s
de o como si &uese de tipo o$ject pero sin realizarse ninguna con(ersin*
El pro$lema del $o-ing + el un$o-ing es )ue son procesos lentos% +a )ue implican la creacin +
destruccin de o$jetos en(oltorio* Por ello puede interesar e(itarlos en a)uellas situaciones
donde la (elocidad de ejecucin de la aplicacin sea cr.tica% + para ello se proponen (arias
tcnicas3
Si el pro$lema se de$e al paso de estructuras como parmetros de mtodos
genricos )ue tomen parmetros de tipo object% puede con(enir de&inir
so$recargas de esos mtodos )ue en lugar de tomar objects tomen o$jetos de los
tipos estructura )ue en concreto la aplicacin utiliza
Siguiendo en la l.nea de lo anterior% puede )ue interese usar <-9237--9; en lugar
de tipos genricos* <stas no son ms )ue de&iniciones de tipos de datos en las
)ue no se indica cul es el tipo e-acto de ciertas (aria$les sino )ue se deja en
&uncin de parmetros a los )ue puede drseles distintos (alores al crear cada
o$jeto de ese tipo* As.% en (ez de crearse siempre o$jetos con mtodos )ue
tomen parmetros object% se podr.an ir creando di&erentes (ersiones del tipo
seg,n el tipo de estructura con la )ue se (a+a a tra$ajar*
Actulmente el C?> puede tra$ajar con plantillas% pero se espera )ue en
(ersiones &uturas del *4E5 Wrame=orI lo /aga + el lenguaje C# las inclu+a*
6uc/as (eces con(iene /acer un$o-ing para poder acceder a miem$ros
espec.&icos de ciertas estructuras almacenadas en objects% aun)ue a continuacin
(uel(a a necesitarse realmacenar la estructura en un object* Para e(itar esto una
posi$ilidad ser.a almacenar en el o$jecto no directamente la estructura sino un
o$jeto de una clase en(ol(ente creada a medida por el programador + )ue
inclu+a los miem$ros necesarios para /acer las operaciones anteriores* As. se
e(itar.a tener )ue /acer un$o-ing% pues se con(ertir.a de object a esa clase% )ue
no es un tipo (alor + por tanto no implica un$o-ing*
Con la misma idea% otra posii$ilidad ser.a )ue el tipo estructura implementase
ciertas inter&aces mediante las )ue se pudiese /acer las operaciones antes
comentadas* Aun)ue las inter&aces no se tratarn /asta el Tema %5: "nter0a$es%
por a/ora $asta sa$er )ue las inter&aces son tam$in tipos re&erencia + por tanto
con(ertir de object a un tipo inter&az no implica un$o-ing*
Constructores
?os constructores de las estructuras se comportan de una &orma distinta a los de las
clases* Por un lado% no pueden incluir ning,n inicializador $ase de$ido a )ue como no
puede /a$er /erencia el compilador siempre sa$e )ue /a de llamar al constructor sin
parmetros de System.VaIueType* Por otro% dentro de su cuerpo no se puede acceder a
sus miem$ros /asta inicializarlos% pues para a/orrar tiempo no se les da ning,n (alor
inicial antes de llamar al constructor*
El lenguaje de programacin C# 5ema 1!3 Estructuras
Sin em$argo% la di&erencia ms importante entre los constructores de am$os tipos se
encuentra en la implementacin del constructor sin parmetros3 como los o$jetos
estructura no puede almacenar el (alor por de&ecto nuII cuando se declaran sin usar
constructor +a )ue ese (alor indica re&erencia a posicin de memoria dinmica
indeterminada + los o$jetos estructura no almacenan re&erencias% toda estructura
siempre tiene de&inido un constructor sin parmetros )ue lo )ue /ace es darle en esos
casos un (alor por de&ecto a los o$jetos declarados* Ese (alor consiste en poner a cero
toda la memoria ocupada por el o$jeto% lo )ue tiene el e&ecto de dar como (alor a cada
campo el cero de su tipo
1
* Por ejemplo% el siguiente cdigo imprime un 2 en pantalla3

Punto p = new Punto();
Console.WriteLine(p.X);
V el siguiente tam$in3
using System;
struct Punto
{
public int X,Y;
}
class EjemploConstructorDefecto
{
Punto p;
public static void Main()
{
Console.WriteLine(p.X);
}
}
Sin em$argo% el /ec/o de )ue este constructor por de&ecto se apli)ue no implica )ue se
pueda acceder a las (aria$les locales sin antes inicializarlas con otro (alor* Por ejemplo%
el siguiente &ragmente de cdigo de un mtodo ser.a incorrecto3
Punto p;
Console.WriteLine(p.X); // X no inicializada
Sin em$rago% como a las estructuras declaradas sin constructor no se les da el (alor por
de&ecto nuII% s. )ue ser.a (lido3

Punto p;
p.X = 2;
Console.WriteLine(p.X);
Para asegurar un (alor por de&ecto com,n a todos los o$jetos estructura% se pro/.$e al
programador dar una de&inicin propia de su constructor sin parmetros* 6ientras )ue
en las clases es opcional implementarlo + si no se /ace el compilador introduce uno por
de&ecto% en las estructuras no es (lido /acerlo* Adems% a,n en el caso de )ue se
de&inan otros constructores% el constructor sin parmetros seguir siendo introducido
1
L sea% cero para los campos de tipos numricos% '\u0000' para los de tipo char% faIse para los de tipo booI
+ nuII para los de tipos re&erencia*
El lenguaje de programacin C# 5ema 1!3 Estructuras
automticamente por el compilador a di&erencia de cmo ocurr.a con las clases donde
en ese caso el compilador no lo introduc.a*
Por otro lado% para conseguir )ue el (alor por de&ecto de todos los o$jetos estructuras
sea el mismo% se pro/.$e darles una (alor inicial a sus campos en el momento de
declararlos% pues si no el constructor por de&ecto /a$r.a de tenerlos en cuenta + su
ejecucin ser.a ms ine&iciente* Por esta razn% los constructores de&inidos por el
programador para una estructura /an de inicializar todos sus miem$ros no estticos en
tanto )ue antes de llamarlos no se les da ning,n (alor inicial*
4tese )ue de$ido a la e-istencia de un constructor por de&ecto cu+a implementacin
escapa de manos del programador% el cdigo de los mtodos de una estructura puede
tener )ue considerar la posi$ilidad de )ue se acceda a ellos con los (alores resultantes
de una inicializacin con ese constructor* Por ejemplo% dado3
struct A
{
public readonly string S;
public A(string s)
{
if (s==null)
throw (new ArgumentNullException());
this.s = S;
}
}
4ada asegura )ue en este cdigo los o$jetos de clase A siempre se inicialicen con un
(alor distinto de nuII en su campo S% pues aun)ue el constructor de&inido para A
comprue$a )ue eso no ocurra lanzando una e-cepcin en caso de )ue se le pase una
cadena )ue (alga nuII% si el programador usa el constructor por de&ecto crear un o$jeto
en el )ue S (alga nuII* Adems% ni si)uiera es (lido especi&icar un (alor inicial a S en
su de&inicin% +a )ue para inicializar rpidamente las estructuras sus campos no
estticos no pueden tener (alores iniciales*
El lenguaje de programacin C# 5ema 1"3 Enumeraciones
TEMA 14: Enumeraciones
Concepto de enumeracin
Kna 120?1496782 es un tipo especial de estructura en la )ue los literales de los (alores
)ue pueden tomar sus o$jetos se indican e-pl.citamente en su de&inicin* Por ejemplo%
una enumeracin de nom$re Tamao cu+os o$jetos pudiesen tomar los (alores literales
Pequeo% Mediano o Grande se de&inir.a as.3
enum Tamao
{
Pequeo,
Mediano,
Grande
}
Estos tipos son mu+ ,tiles por)ue &acilitan la escritura + legi$ilidad del cdigo* Por
ejemplo% en (ez de de&inir un mtodo )ue tome como parmetro un entero )ue indi)ue
el tama1o con el )ue se /a de mostrar un te-to% es mejor de&inirlo con un parmetro de
tipo Tamao +a )ue as. el programador usuario no /a de recordar en cual es el n,mero
)ue corresponde a cada color + aparte es ms &cil leer las llamadas al mismo* 4tese
como la llamada (2) es muc/o ms legi$le )ue la (1)3
obj.MuestreaTexto(2); // (1)
obj.MuestraTexto(Tamao.Mediano); // (2)
Adems% si se usa la enumeracin el cdigo es ms &cil de mantener* Por ejemplo% si el
mtodo (1) anterior lo /u$isemos de&inido de &orma )ue 1 signi&icase tama1o pe)ue1o%
tama1o mediano + ! tama1o grande% cuando )ueramos incluir un nue(o tama1o
intermedio entre pe)ue1o + mediano /a$remos de darle un (alor superior a ! o in&erior
a 1 +a )ue los dems estn cogidos* Eso romper.a la ordenacin de menor a ma+or entre
los n,meros asociados a cada tama1o* Sin em$argo% usando una enumeracin no ser.a
importante mantener el orden relati(o + $astar.a a1adir un nue(o literal a la misma*
)efinicin de enumeraciones
Va /emos (isto un ejemplo de cmo de&inir una enumeracin* Sin em$argo% la sinta-is
completa )ue se puede usar para de&inirlas es3
enum <nombreEnumeracin> : <tipoBase>
{
<literales>
}
En realidad una enumeracin es un tipo especial de estructura Aluego System.VaIueType
ser tipo padre de ellaB )ue slo puede tener como miem$ros campos p,$licos
constantes + estticos* Esos campos se indican en <literales>% + como sus modi&icadores
son siempre los mismos no /a+ )ue especi&icarlos Ade /ec/o% es errneo /acerloB
El lenguaje de programacin C# 5ema 1"3 Enumeraciones
El tipo por de&ecto de las constantes )ue &orman una enumeracin es int% aun)ue puede
drseles cual)uier otro tipo $sico entero Abyte% sbyte% short% ushort% uint% int% Iong o
uIongB indicndolo en <tipoBase>
Si no se especi&ica (alor inicial para cada constante% el compilador les dar por de&ecto
(alores )ue empiecen desde 2 + se incrementen en una unidad para cada constante
seg,n su orden de aparicin en la de&inicin de la enumeracin* As.% el ejemplo del
principio del tema es e)ui(alente /a3
enum Tamao:int
{
Pequeo = 0,
Mediano = 1,
Grande = 2
}
Es posi$le alterar los (alores iniciales de cada constante indicndolos e-pl.citamente
como en el cdigo recin mostrado* Ltra posi$ilidad es alterar el (alor $ase a partir del
cual se (a calculando el (alor de las siguientes constantes como en este otro ejemplo3
enum Tamao
{
Pequeo,
Mediano = 5,
Grande
}
En este ,ltimo ejemplo el (alor asociado a Pequeo ser 2% el asociado a Mediano ser Q%
+ el asociado a Grande ser T +a )ue como no se le indica e-pl.citamente ning,n otro se
considera )ue este (alor es el de la constante anterior ms 1*
L$(iamente% el nom$re )ue se de a cada constante /a de ser di&erente al de las dems de
su misma enumeracin + el (alor )ue se de a cada una /a de estar incluido en el rango
de (alores admitidos por su tipo $ase* Sin em$argo% nada o$liga a )ue el (alor )ue se de
a cada constante tenga )ue ser di&erente al de las dems% + de /ec/o puede especi&icarse
el (alor de una constante en &uncin del (alor de otra como muestra este ejemplo3
enum Tamao
{
Pequeo,
Mediano = Pequeo,
Grande = Pequeo + Mediano
}
En realidad% lo ,nico )ue importa es )ue el (alor )ue se d a cada literal% si es )ue se le
da alguno e-pl.citamente% sea una e-presin constante cu+o resultado se encuentre en el
rango admitido por el tipo $ase de la enumeracin + no pro(o)ue de&iniciones
circulares* Por ejemplo% la siguiente de&inicin de enumeracin es incorrecta +a )ue en
ella los literales Pequeo + Mediano se /an de&inido circularmente3
enum TamaoMal
{
Pequeo = Mediano,
El lenguaje de programacin C# 5ema 1"3 Enumeraciones
Mediano = Pequeo,
Grande
}
4tese )ue la siguiente de&inicin de enumeracin tam$in ser.a incorrecta +a )ue en
ella el (alor de B depende del de A impl.citamente Aser.a el de A ms 1B3
enum EnumMal
{
A = B,
B
}
5so de enumeraciones
?as (aria$les de tipos enumerados se de&inen como cual)uier otra (aria$le Asinta-is
<nombreTipo> <nombreVariable>B Por ejemplo3
Tamao t;
El (alor por de&ecto para un o$jeto de una enumeracin es 2% )ue puede o no
corresponderse con alguno de los literales de&inidos para sta* As.% si la t del ejemplo
&uese un campo su (alor ser.a Tamao.Pequeo* 5am$in puede drsele otro (alor al
de&inirla% como muestra el siguiente ejemplo donde se le da el (alor Tamao.Grande3
Tamao t = Tamao.Grande; // Ahora t vale Tamao.Grande
4tese )ue a la /ora de /acer re&erencia a los literales de una enumeracin se usa la
sinta-is <nombreEnumeracin>.<nombreLiteral>% como es lgico si tenemos en cuenta )ue
en realidad los literales de una enumeracin son constantes pu$licas + estticas% pues es
la sinta-is )ue se usa para acceder a ese tipo de miem$ros* El ,nico sitio donde no es
necesario preceder el nom$re del literal de <nombreEnumeracin>. es en la propia
de&inicin de la enumeracin% como tam$in ocurre con cual)uier constante esttica*
En realidad los literales de una enumeracin son constantes de tipos enteros + las
(aria$les de tipo enumerado son (aria$les del tipo entero $ase de la enumeracin* Por
eso es posi$le almacenar (alores de enumeraciones en (aria$les de tipos enteros +
(alores de tipos enteros en (aria$les de enumeraciones* Por ejemplo3
int i = Tamao.Pequeo; // Ahora i vale 0
Tamao t = (Tamao) 0; //Ahora t vale Tamao.Pequeo (=0)
t = (Tamao) 100; // Ahora t vale 100, que no se corresponde con ningn literal
Como se (e en el ,ltimo ejemplo% tam$in es posi$le darle a una enumeracin (alores
enteros )ue no se correspondan con ninguno de sus literales*
Cado )ue los (alores de una enumeracin son enteros% es posi$le aplicarles muc/os de
las operaciones )ue se pueden aplicar a los mismos3 ==% >=% ;% <% ;=% <=% % 8% :% /% 0% ?%
% -- + sizeof* Sin em$argo% /a+ )ue concretar )ue los operadores $inarios + + - no
pueden aplicarse entre dos operandos de enumeraciones% sino )ue al menos uno de ellos
El lenguaje de programacin C# 5ema 1"3 Enumeraciones
/a de ser un tipo enteroU + )ue W% / y : sBlo 5ueden a5licarse entre
enumeraciones.
La clase "%stem.Enum
5odos los tipos enumerados deri(an de System.Enum% )ue deri(a de System.VaIueType
+ sta a su (ez deri(a de la clase primigenia System.Object* Aparte de los mtodos
/eredados de estas clases padres + +a estudiados% toda enumeracin tam$in dispone de
otros mtodos /eredados de System.Enum% siendo los principales de ellos3
static Type getUnderIyingType(Type enum)3 Ce(uel(e un o$jeto System.Type
con in&ormacin so$re el tipo $ase de la enumeracin representada por el o$jeto
System.Type )ue se le pasa como parmetro
1!
*
static object[] GetVaIues(Type enum)3 Ce(uel(e una ta$la con los (alores de
todos los literales de la enumeracin representada por el o$jeto System.Type )ue
se le pasa como parmetro* Por ejemplo3
object[] tabla = Enum.GetValues(typeof(Tamao));
Console.WriteLine(tabla[0]); // Muestra 0, pues Pequeo = 0
Console.WriteLine(tabla[1]); // Muestra 1, pues Mediano = 1
Console.WriteLine(tabla[2]); // Muestra 1, pues Grande = Pequeo+Mediano
static string GetName(Type enum, object vaIor)3 Ce(uel(e una cadena con el
nom$re del literal de la enumeracin representada por enum )ue tenga el (alor
especi&icado en valor* Por ejemplo% este cdigo muestra Pequeo por pantalla3
Console.WriteLine(Enum.GetName(typeof(Tamao), 0)); //mprime Pequeo
Si la enumeracin no contiene ning,n literal con ese (alor de(uel(e nuII% + si
tu(iese (arios con ese mismo (alor de(ol(er.a slo el nom$re del ,ltimo* Si se
)uiere o$tener el de todos es mejor usar GetNames()% )ue se usa como GetName()
pero de(uel(e un string[] con los nom$res de todos los literales )ue tengan el
(alor indicado ordenados seg,n su orden de de&inicin en la enumeracin*
static booI isDefined (Type enum, object vaIor)3 Ce(uel(e un $ooleano )ue indica
si alg,n literal de la enumeracin indicada tiene el (alor indicado*
1!
>ecurdese )ue para o$tener el System.Type de un tipo de dato $asta usar el operador typeof pasndole
como parmetros el nom$re del tipo cu+o System.Type se desea o$tener* Por ejemplo% typeof(int)
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
TEMA 15: Interfaces
Concepto de interfaz
Kna 72314@9K es la de&inicin de un conjunto de mtodos para los )ue no se da
implementacin% sino )ue se les de&ine de manera similar a como se de&inen los
mtodos a$stractos* Es ms% una inter&az puede (erse como una &orma especial de
de&inir clases )ue slo cuenten con miem$ros a$stractos*
Como las clases a$stractas% las inter&aces son tipos re&erencia% no puede crearse o$jetos
de ellas sino slo de tipos )ue deri(en de ellas% + participan del polimor&ismo* Sin
em$argo% tam$in tiene muc/as di&erencias con stas3
E; <.;7C-1 51@7274 37<.; /01 5147A12 51 ?M; 51 029 72314@9K* Esto se de$e a
)ue los pro$lemas )ue se pueden presentar a la /ora de crear tipos )ue /ereden
de (arios tipos son de$idos a )ue pueden /a$er con&lictos di&.ciles de resol(er +
si un tipo /ereda ms de una (ersin de un mismo mtodo procedentes de padres
di&erentes + con cdigos distintos* Sin em$argo% con las inter&aces las inter&aces
se permite la /erencia m,ltiple por)ue esto nunca puede ocurrir de$ido a )ue las
inter&aces no inclu+en cdigo*
Aun)ue las estructuras no pueden /eredar clases% s. pueden /acerlo de inter&aces
5odo tipo )ue deri(e de una inter&az /a de dar una implementacin de todos los
miem$ros )ue /ereda de esta% + no como ocurre con las clases a$stractas donde
es posi$le no darla si se de&ine como a$stracta tam$in la clase /ija* Ce esta
manera )ueda de&inido un contrato en la clase )ue la /ereda )ue (a a permitir
poder usarla con seguridad en situaciones polimr&icas3 toda clase )ue /erede
una inter&az implementar todos los mtodos de la misma* Por esta razn se
suele denominar 7?<-1?12394 una inter&az al /ec/o de /eredar de ella*
?as inter&aces slo pueden tener como miem$ros mtodos normales% e(entos%
propiedades e indizadoresU pero no pueden incluir de&iniciones de campos%
operadores% constructores o destructores*
)efinicin de interfaces
?a sinta-is general )ue se sigue a la /ora de de&inir una inter&az es3
<modificadores> interface <nombre>0<inter!aces$ase>
{
<miembros>
}
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
?os <modificadores> admitidos por las inter&aces son los mismos )ue los de las clases Es
decir% pubIic% internaI, private% protected% protected internaI o new Ae igualmente% los
cuatro ,ltimo slo son aplica$les a inter&aces de&inidas dentro de otros tiposB
El <nombre> de una inter&az puede ser cual)uier identi&icador (lido% aun)ue por
con(enio se suele usar como primer carcter del mismo AComparable% A% etcB
?os <miembros> de las inter&aces pueden ser de&iniciones de mtodos% propiedades%
indizadores o e(entos% pero no campos% operadores% constructores o destructores* ?a
sinta-is )ue se sigue para de&inir cada tipo de miem$ro es la misma )ue para de&inirlos
como a$stractos en una clase pero sin incluir abstract por suponerse imp.citamente3

MN3.5.;: <tipoRetorno> <nombreMtodo>(<parmetros>);
P4.<715951;: <tipo> <nombrePropiedad> {set6 get6}
?os $lo)ues get + set pueden intercam$iarse + puede no incluirse uno de ellos
Apropiedad de slo lectura o de slo escritura seg,n el casoB% pero no los dos*
I257K95.41;: <tipo> this[<ndices>] {set6 get6}
Al igual )ue las propiedades% los $lo)ues set + get pueden intercam$iarse +
o$(iarse uno de ellos al de&inirlos*
EA123.;: event <delegado> <nombreEvento>;
4tese )ue a di&erencia de las propiedades e indizadores% no es necesario indicar
nada so$re sus $lo)ues add + remove* Esto se de$e a )ue siempre se /an de
implementar am$os% aun)ue si se usa la sinta-is $sica el compilador les da una
implementacin por de&ecto automticamente*
Cual)uier de&inicin de un miem$ro de una inter&az puede incluir el modi&icador new
para indicar )ue pretende ocultar otra /eredada de alguna inter&az padre* Sin em$argo%
el resto de modi&icadores no son (lidos +a )ue impl.citamente siempre se considera
)ue son pubIic + abstract* Adems% una inter&az tampoco puede incluir miem$ros de
tipo% por lo )ue es incorrecto incluir el modi&icador static al de&inir sus miem$ros*

Cada inter&az puede /eredar de (arias inter&aces% )ue se indicar.an en <interfacesBase>
separadas por comas* Esta lista slo puede incluir inter&aces% pero no clases o
estructurasU + a continuacin se muestra un ejemplo de cmo de&inir una inter&az C )ue
/ereda de otras dos inter&aces A + B3
public delegate void D (int x);
interface A
{
int PropiedadA{get;}
void Comn(int x);
}
interface B
{
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
int this [int ndice] {get; set;}
void Comn(int x);
}
interface C: A, B
{
event D EventoC;
}
4tese )ue aun)ue las inter&aces padres de C contienen un mtodo com,n no /a+
pro$lema alguno a la /ora de de&inirlas* En el siguiente ep.gra&e (eremos cmo se
resuel(en las am$igaedades )ue por esto pudiesen darse al implementar C*
!mplementacin de interfaces
Para de&inir una clase o estructura )ue implemente una o ms inter&aces $asta incluir los
nom$res de las mismas como si de una clase $ase se tratase Xseparndolas con comas si
son (arias o si la clase de&inida /ereda de otra claseX + asegurar )ue la clase cuente con
de&iniciones para todos los miem$ros de las inter&aces de las )ue /ereda Xlo )ue se
puede conseguir de&inindolos en ella o /eredndolos de su clase padre*

?as de&iniciones )ue se den de miem$ros de inter&aces /an de ser siempre p,$licas + no
pueden incluir override% pues como sus miem$ros son impl.citamente abstract se
so$reentiende* Sin em$argo% s. pueden drsele los modi&icadores como virtuaI abstract
+ usar override en rede&iniciones )ue se les den en clases /ijas de la clase )ue
implemente la inter&az*
Cuando una clase deri(a de ms de una inter&az )ue inclu+e un mismo miem$ro% la
implementacin )ue se le d ser(ir para todas las inter&aces )ue cuenten con ese
miem$ro* Sin em$argo% tam$in es posi$le dar una implementacin di&erente para cada
una usando una 7?<-1?12396782 1I<-L6739% lo )ue consiste en implementar el miem$ro
sin el modi&icador pubIic + anteponiendo a su nom$re el nom$re de la inter&az a la )ue
pertenece seguido de un punto Acarcter .B
Cuando un miem$ro se implementa e-pl.citamente no puede drsele modi&icadores
como en las implementaciones impl.citas% ni si)uiera virtuaI o abstract* Kna &orma de
simular los modi&icadores )ue se necesiten consiste en darles un cuerpo )ue lo )ue /aga
sea llamar a otra &uncin )ue s. cuente con esos modi&icadores*
El siguiente ejemplo muestra cmo de&inir una clase CL )ue implemente la inter&az C3
class CL:C
{
public int PropiedadA
{
get {return 5;}
set {Console.WriteLine(Asignado{0}a PropiedadA, value);}
}
void A.Comn(int x)
{
Console.WriteLine(Ejecutado Comn() de A);
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
}
public int this[int ndice]
{
get { return 1;}
set { Console.WriteLine(Asignado {0} a indizador, value); }
}
void B.Comn(int x)
{
Console.WriteLine(Ejecutado Comn() de B);
}
public event D EventoC;
}
Como se (e% para implementar la inter&az C /a sido necesario implementar todos sus
miem$ros% incluso los /eredados de A + B% de la siguiente manera3
Al EventoC se le /a dado la implementacin por de&ecto% aun)ue si se )uisiese se
podr.a /a$er dado una implementacin espec.&ica a sus $lo)ues add + remove*
Al mtodo Comn() se le /a dado una implementacin para cada (ersin
/eredada de una de las clases padre de C% usndose para ello la sinta-is de
implementacin e-pl.cita antes comentada* 4tese )ue no se /a incluido el
modi&icador pubIic en la implementacin de estos miem$ros*
A la PropiedadA se le /a dado una implementacin con un $lo)ue set )ue no
aparec.a en la de&inicin de PropiedadA en la inter&az A* Esto es (lido /acerlo
siempre + cuando la propiedad no se /a+a implementado e-pl.citamente% + lo
mismo ocurre con los indizadores + en los casos en )ue en (ez de set sea get el
$lo)ue e-tra implementado*
Ltra utilidad de las implementaciones e-pl.citas es )ue son la ,nica manera de
conseguir poder dar implementacin a mtodos ocultados en las de&iniciones de
inter&aces* Por ejemplo% si tenemos3
interface Padre
{
int P{get;}
}
interface Hija:Padre
{
new int P();
}
?a ,nica &orma de poder de&inir una clase donde se d una implementacin tanto para el
mtodo P() como para la propiedad P% es usando implementacin e-pl.cita as.3
class C: Hija
{
void Padre.P {}
public int P() {.}
}
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
L as.3
class C: Hija
{
public void P () {}
int Hija.P() {}
}
L as.3
class C: Hija
{
void Padre.P() {}
int Hija.P() {}
}
Pero como no se puede implementar es sin ninguna implementacin e-pl.cita% pues se
producir.a un error al tener am$os miem$ros las misma signatura* Es decir% la siguiente
de&inicin no es correcta3
class C: Hija
{
public int P() {} // ERROR: Ambos miembros tienen la misma signatura
public void P() {}
}
Es posi$le reimplementar en una clase /ija las de&iniciones )ue su clase padre diese para
los mtodos )ue /ered de una inter&az* Para /acer eso $asta /acer )ue la clase /ija
tam$in /erede de esa inter&az + dar en ella las de&iniciones e-pl.citas de miem$ros de
la inter&az )ue se estimen con(enientes% considerndose )ue las implementaciones para
los dems sern las /eredadas de su clase padre* Por ejemplo3
using System;
interface A
{
void F();
}
class C1: A
{
public void F()
{
Console.WriteLine("El F() de C1");
}
}
class C2: C1, A
{
void A.F() // Sin implementacin explcita no redefinira, sino ocultara
{
Console.WriteLine("El F() de C2");
}
public static void Main()
{
A obj = new C1();
A obj2 = new C2();
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
obj.F();
obj2.F();
}
}
>eimplementar un miem$ro de una inter&az de esta manera es parecido a rede&inir los
miem$ros reimplementados% slo )ue a/ora la rede&inicin ser.a slamente accesi$le a
tra(s de (aria$les del tipo de la inter&az As.% la salida del ejemplo anterior ser.a3
El F() de C1
El F() de C2
8a+ )ue tener en cuenta )ue de esta manera slo pueden /acerse reimplementaciones de
miem$ros si la clase donde se reimplementa /ereda directamente de la inter&az
implementada e-pl.citamente o de alguna inter&az deri(ada de sta* As.% en el ejemplo
anterior ser.a incorrecto /a$er /ec/o3

class C2:C1 //La lista de herencias e interfaces implementadas por C2 slo incluye a C1
{
void A.f(); // ERROR: Aunque C1 herede de A, A no se incluye directamente
// en la lista de interfaces implementadas por C2
}
Es importante se1alar )ue el nom$re de inter&az especi&icado en una implementacin
e-pl.cita /a de ser e-actamente el nom$re de la inter&az donde se de&ini el miem$ro
implementado% no el de alguna su$clase de la misma* Por ejemplo3
interface 1
{
void F()
}
interface 2
{}
class C1:2
{
public void 2.F(); //ERROR: habra que usar 1.F()
}
En el ejemplo anterior% la l.nea comentada contiene un error de$ido a )ue W() se de&ini
dentro de la inter&az 1% + aun)ue tam$in pertenezca a 2 por)ue sta lo /ereda de 1% a
la /ora de implementarlo e-pl.citamente /a+ )ue pre&ijar su nom$re de 1% no de 2*
4cceso a miembros de una interfaz
Se puede acceder a los miem$ros de una inter&az implementados en una clase de manera
no e-pl.cita a tra(s de (aria$les de esa clase como si de miem$ros normales de la
misma se tratase* Por ejemplo% este cdigo mostrar.a un cinco por pantalla3
CL c = new CL();
Console.WriteLine(c.PropiedadA);
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
Sin em$argo% tam$in es posi$le de&inir (aria$les cu+o tipo sea una inter&az* Aun)ue no
e-isten constructores de inter&aces% estas (aria$les pueden inicializarse gracias al
polimor&ismo asignndoles o$jetos de clases )ue implementen esa inter&az* As.% el
siguiente cdigo tam$in mostrar.a un cinco por pantalla3
A a = new CL();
Console.WriteLine(a.PropiedadA);
4tese )ue a tra(s de una (aria$le de un tipo inter&az slo se puede acceder a
miem$ros del o$jeto almacenado en ella )ue estn de&inidos en esa inter&az* Es decir%
los ,nicos miem$ros (lidos para el o$jeto a anterior ser.an PropiedadA + Comn()
En caso de )ue el miem$ro al )ue se pretenda acceder /a+a sido implementado
e-pl.citamente% slo puede accederse a l a tra(s de (aria$les del tipo inter&az al )ue
pertenece + no a tra(s de (aria$les de tipos )ue /ereden de ella% +a )ue la de&inicin de
estos miem$ros es pri(ada al no lle(ar modi&icador de acceso* Por ejemplo3
CL cl = new CL();
A a = cl;
B b = cl;
// Console.WriteLine(cl.Comn()); // Error: Comn() fue implementado explcitamente
Console.WriteLine(a.Comn());
Console.WriteLine(b.Comn());
Console.WriteLine(((A) cl).Comn());
Console.WriteLine(((B) cl).Comn());
Cada (ez )ue se llame a un mtodo implementado e-pl.citamente se llamar a la (ersin
del mismo de&inida para la inter&az a tra(s de la )ue se accede* Por ello% la salida del
cdigo anterior ser3
@7ecutado ComUn(% de ;.
@7ecutado ComUn(% de ;1
@7ecutado ComUn(% de ;.
@7ecutado ComUn(% de ;1
Se puede dar tanto una implementacin impl.cita como una e-pl.cita de cada miem$ro
de una inter&az* ?a e-pl.cita se usar cuando se acceda a un o$jeto )ue implemente esa
inter&az a tra(s de una re&erencia a la inter&az% mientras )ue la impl.cita se usar
cuando el acceso se /aga a tra(s de una re&erencia del tipo )ue implementa la inter&az*
Por ejemplo% dado el siguiente cdigo3

interface
{
object Clone();
}
class Clase:
{
public object Clone()
{
Console.WriteLine(mplementacin implcita);
}
public object Clonable.Clone()
{
Console.WriteLine(mplementacin explcita);
El lenguaje de programacin C# 5ema 1Q3 #nter&aces
}
public static void Main()
{
Clase obj = new Clase();
(() obj).Clone();
obj.Clone();
}
}
El resultado )ue por pantalla se mostrar tras ejecutarlo es3
;m5lementaciBn e$5lQcita
;m5lementaciBn im5lQcita
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
TEMA 16: Instrucciones
Concepto de instruccin
5oda accin )ue se pueda realizar en el cuerpo de un mtodo% como de&inir (aria$les
locales% llamar a mtodos% asignaciones + muc/as cosas ms )ue (eremos a lo largo de
este tema% son 72;340667.21;*
?as instrucciones se agrupan &ormando C-./01; 51 72;340667.21;% )ue son listas de
instrucciones encerradas entre lla(es )ue se ejecutan una tras otra* Es decir% la sinta-is
)ue se sigue para de&inir un $lo)ue de instrucciones es3
{
<listanstrucciones>
}
5oda (aria$le )ue se de&ina dentro de un $lo)ue de instrucciones slo e-istir dentro de
dic/o $lo)ue* 5ras l ser inaccesi$le + podr ser destruida por el recolector de $asura*
Por ejemplo% este cdigo no es (lido3
public void f();
{
{ int b; }
b = 1; // ERROR: b no existe fuera del bloque donde se declar.
}
?os $lo)ues de instrucciones pueden anidarse% aun)ue si dentro de un $lo)ue interno
de&inimos una (aria$le con el mismo nom$re )ue otra de&inida en un $lo)ue e-terno se
considerar )ue se /a producido un error% +a )ue no se podr determinar a cul de las
dos se estar /aciendo re&erencia cada (ez )ue se utilice su nom$re en el $lo)ue interno*
!nstrucciones b1sicas
Definiciones de variabIes IocaIes
En el Tema 7:Variales ! tipos de datos +a se (i )ue las A9479C-1; -.69-1; son
(aria$les )ue se de&inen en el cuerpo de los mtodos + slo son accesi$les desde dic/os
cuerpos* >ecurdese )ue la sinta-is e-plicada para de&inirlas era la siguiente3

<modi!icadores> <tipoVariable> <nombreVariable> - <valor>;
5am$in se (i )ue pod.an de&inirse (arias (aria$les en una misma instruccin
separando sus pares nom$reX(alor mediante comas* Por ejemplo3
int a=5, b, c=-1;
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Asignaciones
Kna 9;7=296782 es simplemente una instruccin mediante la )ue se indica un (alor a
almacenar en un dato* ?a sinta-is usada para ello es3
<destino> = <origen>;
En temas pre(ios +a se /an dado numerosos ejemplos de cmo /acer esto% por lo )ue no
es necesario /acer a/ora ma+or incapi en ello*
LIamadas a mtodos
En el Tema 8: Mtodos +a se e-plic )ue una --9?959 9 02 ?N3.5. consiste en
solicitar la ejecucin de sus instrucciones asociadas dando a sus parmetros ciertos
(alores* Si el mtodo a llamar es una mtodo de o$jeto% la sinta-is usada para ello es3
<objeto>.<nombreMtodo>(<valoresarmetros>);
V si el mtodo a llamar es un mtodo de tipo% entonces la llamada se realiza con3
<nombre%ipo>.<nombreMtodo>(<valoresarmetros>);
>ecurdese )ue si la llamada al mtodo de tipo se /ace dentro de la misma de&inicin de
tipo donde el mtodo &ue de&inido% la seccin 6nomreTipo7. de la sinta-is es opcional*
Instruccin nuIa
?a 72;34066782 20-9 es una instruccin )ue no realiza nada en a$soluto* Su sinta-is
consiste en escri$ir un simple punto + coma para representarla* L sea% es3
;
Suele usarse cuando se desea indicar e-pl.citamente )ue no se desea ejecutar nada*
Ksarla es ,til para &acilitar la legi$ilidad del cdigo o% como (eremos ms adelante en el
tema% por)ue otras instrucciones la necesitan para indicar cundo en algunos de sus
$lo)ues de instrucciones componentes no se /a de realizar ninguna accin*
!nstrucciones condicionales
?as 72;340667.21; 6.25767.29-1; son instrucciones )ue permiten ejecutar $lo)ues de
instrucciones slo si se da una determinada condicin* En los siguientes su$apartados de
este ep.gra&e se descri$en cules son las instrucciones condicionales disponi$les en C#
Instruccin if
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
?a 72;34066782 if permite ejecutar ciertas instrucciones slo si de da una determinada
condicin* Su sinta-is de uso es la sinta-is3
if (<condicin>)
<instruccionesf>
else
<instruccionesElse>
El signi&icado de esta instruccin es el siguiente3 se e(al,a la e-presin <condicin>% )ue
/a de de(ol(er un (alor lgico* Si es cierta Ade(uel(e trueB se ejecutan las
<instruccionesf, + si es &alsa AfaIseB se ejecutan las <instruccionesElse> ?a rama eIse es
opcional% + si se omite + la condicin es &alsa se seguir.a ejecutando a partir de la
instruccin siguiente al if* En realidad% tanto <instruccionesf> como <instruccionesElse>
pueden ser una ,nica instruccin o un $lo)ue de instrucciones*
Kn ejemplo de aplicacin de esta instruccin es esta (ariante del 8ola6undo3
using System;
class HolaMundof
{
public static void Main(String[] args)
{
if (args.Length > 0)
Console.WriteLine(Hola {0}!, args[0]);
else
Console.WriteLine(Hola mundo!);
}
}
Si ejecutamos este programa sin ning,n argumento (eremos )ue el mensaje )ue se
muestra es Hola Mundo!% mientras )ue si lo ejecutamos con alg,n argumento se
mostrar un mensaje de $ien(enida personalizado con el primer argumento indicado*
Instruccin switch
?a 72;34066782 switch permite ejecutar unos u otros $lo)ues de instrucciones seg,n el
(alor de una cierta e-presin* Su estructura es3
switch (<expresin>)
{
case <valor&>0 <blo'ue&>
<siguiente(ccin>
case <valor2>0 <blo'ue2>
<siguiente(ccin>
...
default0 <blo'ueDe!ault>
<siguiente(ccin>
}
El signi&icado de esta instruccin es el siguiente3 se e(al,a <expresin>* Si su (alor es
<valor1> se ejecuta el <bloque1>% si es <valor2> se ejecuta <bloque2>% + as. para el resto de
(alores especi&icados* Si no es igual a ninguno de esos (alores + se inclu+e la rama
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
defauIt% se ejecuta el <bloqueDefault>U pero si no se inclu+e se pasa directamente a
ejecutar la instruccin siguiente al switch*
?os (alores indicados en cada rama del switch /an de ser e-presiones constantes )ue
produzcan (alores de alg,n tipo $sico entero% de una enumeracin% de tipo char o de
tipo string* Adems% no puede /a$er ms de una rama con el mismo (alor*

En realidad% aun)ue todas las ramas de un switch son opcionales siempre se /a de
incluir al menos una* Adems% la rama defauIt no tiene por)u aparecer la ,ltima si se
usa% aun)ue es recomenda$le )ue lo /aga para &acilitar la legi$ilidad del cdigo*
El elemento marcado como <siguienteAccin> colocado tras cada $lo)ue de instrucciones
indica )u es lo )ue /a de /acerse tras ejecutar las instrucciones del $lo)ue )ue lo
preceden* Puede ser uno de estos tres tipos de instrucciones3
goto case <valori>;
goto defauIt;
break;

Si es un goto case indica )ue se /a de seguir ejecutando el $lo)ue de instrucciones
asociado en el switch a la rama del <valori> indicado% si es un goto defauIt indica )ue se
/a de seguir ejecutando el $lo)ue de instrucciones de la rama defauIt% + si es un break
indica )ue se /a de seguir ejecutando la instruccin siguiente al s=itc/*
El siguiente ejemplo muestra cmo se utiliza switch3
using System;
class HolaMundoSwitch
{
public static void Main(String[] args)
{
if (args.Length > 0)
switch(args[0])
{
case Jos: Console.WriteLine(Hola Jos. Buenos das);
break;
case Paco: Console.WriteLine(Hola Paco. Me alegro de verte);
break;
default: Console.WriteLine(Hola {0}, args[0]);
break;
}
else
Console.WriteLine(Hola Mundo);
}
}
Este programa reconoce ciertos nom$res de personas )ue se le pueden pasar como
argumentos al lanzarlo + les saluda de &orma especial* ?a rama defauIt se inclu+e para
dar un saludo por de&ecto a las personas no reconocidas*
Para los programadores /a$ituados a lenguajes como C'' es importante resaltarles el
/ec/o de )ue% a di&erencia de dic/os lenguajes% C# o$liga a incluir una sentencia break o
una sentencia goto 69;1 al &inal de cada rama del switch para e(itar errores comunes +
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
di&.ciles de detectar causados por ol(idar incluir break; al &inal de alguno de estos
$lo)ues + ello pro(ocar )ue tras ejecutarse ese $lo)ue se ejecute tam$in el siguiente*
!nstrucciones iterativas
?as 72;340667.21; 7314937A9; son instrucciones )ue permiten ejecutar repetidas (eces
una instruccin o un $lo)ue de instrucciones mientras se cumpla una condicin* Es
decir% permiten de&inir $ucles donde ciertas instrucciones se ejecuten (arias (eces* A
continuacin se descri$en cules son las instrucciones de este tipo incluidas en C#*
Instruccin whiIe
?a 72;34066782 whiIe permite ejecutar un $lo)ue de instrucciones mientras se de una
cierta instruccin* Su sinta-is de uso es3
whiIe (<condicin>)
<instrucciones>
Su signi&icado es el siguiente3 Se e(al,a la <condicin> indicada% )ue /a de producir un
(alor lgico* Si es cierta A(alor lgico trueB se ejecutan las <instrucciones> + se repite el
proceso de e(aluacin de <condicin> + ejecucin de <instrucciones> /asta )ue deje de
serlo* Cuando sea &alsa AfaIseB se pasar a ejecutar la instruccin siguiente al whiIe* En
realidad <instrucciones> puede ser una ,nica instruccin o un $lo)ue de instrucciones*
Kn ejemplo cmo utilizar esta instruccin es el siguiente3
using System;
class HolaMundoWhile
{
public static void Main(String[] args)
{
int actual = ;
i! (args"#ength $ )
%hile (actual & args"#ength)
{
'onsole"Write#ine(()Hola {*+,- args[actual]);
actual = actual . /;
*
else
'onsole"Write#ine(()Hola mundo+,);
*
*
En este caso% si se indica ms de un argumento al llamar al programa se mostrar por
pantalla un mensaje de saludo para cada uno de ellos* Para ello se usa una (aria$le
actual )ue almacena cul es el n,mero de argumento a mostrar en cada ejecucin del
whiIe* Para mantenerla siempre actualizada lo )ue se /ace es aumentar en una unidad su
(alor tras cada ejecucin de las <instrucciones> del $ucle*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Por otro lado% dentro de las <instrucciones> de un whiIe pueden usarse dos instrucciones
especiales3
break;3 #ndica )ue se /a de a$ortar la ejecucin del $ucle + continuarse
ejecutando por la instruccin siguiente al whiIe*
continue;3 #ndica )ue se /a de a$ortar la ejecucin de las <instrucciones> +
ree(aluarse la <condicin> del $ucle% (ol(indose a ejecutar la <instrucciones> si
es cierta o pasndose a ejecutar la instruccin siguiente al whiIe si es &alsa*
Instruccin do...whiIe
?a instruccin do...whiIe es una (ariante del whiIe )ue se usa as.3
do
<instrucciones>
whiIe(<condicin>);
?a ,nica di&erencia del signi&icado de do...whiIe respecto al de whiIe es )ue en (ez de
e(aluar primero la condicin + ejecutar <instrucciones> slo si es cierta% do...whiIe
primero ejecuta las <instrucciones> + luego mira la <condicin> para (er si se /a de repetir
la ejecucin de las mismas* Por lo dems am$as instrucciones son iguales% e incluso
tam$in puede incluirse break; + continue; entre las <instrucciones> del do...whiIe*
5. ... DJ7-1 est especialmente destinado para los casos en los )ue /a+a )ue ejecutar las
<instrucciones> al menos una (ez a,n cuando la condicin sea &alsa desde el principio*%
como ocurre en el siguiente ejemplo3
using System;
class HolaMundoDoWhile
{
public static void Main()
{
String ledo;
do
{
Console.WriteLine(Clave: );
ledo = Console.ReadLine();
}
while (ledo != Jos);
Console.WriteLine(Hola Jos);
}
}
Este programa pregunta al usuario una cla(e + mientras no introduzca la correcta AJosB
no continuar ejecutndose* Kna (ez )ue introducida correctamente dar un mensaje de
$ien(enida al usuario*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Instruccin for
?a 72;34066782 for es una (ariante de whiIe )ue permite reducir el cdigo necesario para
escri$ir los tipos de $ucles ms com,nmente usados en programacin* Su sinta-is es3
for (<inicializacin>; <condicin>; <modificacin>)
<instrucciones>
El signi&icado de esta instruccin es el siguiente3 se ejecutan las instrucciones de
<inicializacin>% )ue suelen usarse para de&inir e inicializar (aria$les )ue luego se usarn
en <instrucciones>* ?uego se e(al,a <condicin>% + si es &alsa se contin,a ejecutando por
la instruccin siguiente al forU mientras )ue si es cierta se ejecutan las <instrucciones>
indicadas% luego se ejecutan las instrucciones de <modificacin> X)ue como su nom$re
indica suelen usarse para modi&icar los (alores de (aria$les )ue se usen en
<instrucciones>X + luego se ree(al,a <condicin> repitindose el proceso /asta )ue sta
,ltima deje de ser cierta*
En <inicializacin> puede en realidad incluirse cual)uier n,mero de instrucciones )ue no
tienen por)u ser relati(as a inicializar (aria$les o modi&icarlas% aun)ue lo anteriro sea
su uso ms /a$itual* En caso de ser (arias se /an de separar mediante comas A,B% +a )ue
el carcter de punto + coma A;B /a$itualmente usado para estos menesteres se usa en el
for para separar los $lo)ues de <inicializacin>, <condicin> + <modificacin> Adems% la
instruccin nula no se puede usar en este caso + tampoco pueden com$inarse
de&iniciones de (aria$les con instrucciones de otros tipos*

Con <modificacin> pasa algo similar% +a )ue puede incluirse cdigo )ue nada tenga )ue
(er con modi&icaciones pero en este caso no se pueden incluir de&iniciones de (aria$les*
Como en el resto de instrucciones /asta a/ora (istas% en <instrucciones> puede ser tanto
una ,nica instruccin como un $lo)ue de instrucciones* Adems% las (aria$les )ue se
de&inan en <inicializacin> sern (isi$les slo dentro de esas <instrucciones>
?a siguiente clase es e)ui(alente a la clase HolaMundoWhile +a (ista solo )ue /ace uso
del for para compactar ms su cdigo3
using System;
class HolaMundoFor
{
public static void Main(String[] args)
{
if (args.Length > 0)
for (int actual = 0; actual < args.Length; actual++)
Console.WriteLine(Hola {0}!, args[actual]);
else
Console.WriteLine(Hola mundo!);
}
}
Al igual )ue con whiIe% dentro de las <instrucciones> del for tam$in pueden incluirse
instrucciones continue; + break; )ue puedan alterar el &uncionamiento normal del $ucle*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Instruccin foreach
?a 72;34066782 foreach es una (ariante del for pensada especialmente para compactar la
escritura de cdigos donde se realice alg,n tratamiento a todos los elementos de una
coleccin% )ue suele un uso mu+ /a$itual de for en los lenguajes de programacin )ue lo
inclu+en* ?a sinta-is )ue se sigue a la /ora de escri$ir esta instruccin foreach es3
foreach (<tipoElemento> <elemento> in <coleccin>)
<instrucciones>
El signi&icado de esta instruccin es mu+ sencillo3 se ejecutan <instrucciones> para cada
uno de los elementos de la <coleccin> indicada* <elemento> es una (aria$le de slo
lectura de tipo <tipoElemento> )ue almacenar en cada momento el elemento de la
coleccin )ue se est procesando + )ue podr ser accedida desde <instrucciones>*
Es importante se1alar )ue <coleccin> no puede (aler nuII por)ue entonces saltar.a una
e-cepcin de tipo System.NullReferenceException, + )ue <tipoElemento> /a de ser un tipo
cu+os o$jetos puedan almacenar los (alores de los elementos de <coleccin>
En tanto )ue una ta$la se considera )ue es una coleccin% el siguiente cdigo muestra
cmo usar for para compactar a,n ms el cdigo de la clase 8ola6undoWor anterior3
using System;
class HolaMundoFoeach
{
public static void Main(String[] args)
{
if (args.Length > 0)
foreach(String arg in args)
Console.WriteLine(Hola {0}!, arg);
else
Console.WriteLine(Hola mundo!);
}
}
En general% se considera )ue una coleccin es todo a)uel o$jeto )ue implemente la
inter&az System.CoIIections.IEnumerabIe. Esta inter&az est de&inida en la 0C? as.3
interface IEnumerabIe
{
IEnumerator GetEnumerator();
}
El o$jeto de inter&az System.CoIIections.IEnumerator de(uelto /a de ser un enumerador
)ue permita recorrer los elementos de la <coleccin>* Cic/a inter&az est as. prede&inida3
interface IEnumerator
{
object Current {get;}
booI MoveNext();
void Reset();
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
}
El mtodo Reset() /a de implementarse de modo )ue de(uel(a el enumerador reiniciado
a un estado inicial donde a,n no re&erencie ni si)uiera al primer elemento de la
coleccin sino )ue sea necesario llamar a MoveNext() para )ue lo /aga*
El mtodo MoveNext() se /a de implementar de modo )ue /aga )ue el enumerador pase
a apuntar al siguiente elemento de la coleccin + de(uel(a un $ooleano )ue indi)ue si
tras a(anzar se /a alcanzado el &inal de la coleccin*
?a propiedad Current se /a de implementar de modo )ue de(uel(a siempre el elemento
de la coleccin al )ue el enumerador est re&erenciando* Si se intenta leer Current
/a$indose +a recorrido toda la coleccin o /a$indose reiniciado la coleccin + no
/a$indose colocado en su primer elemento con MoveNext()% se /a de producir una
e-cepcin de tipo System.Exception.SystemException.InvaIidOperationException
Ltra &orma de conseguir )ue foreach considere )ue un o$jeto es una coleccin (lida
consiste en /acer )ue dic/o o$jeto siga el <93482 51 6.-166782* Este patrn consiste en
de&inir el tipo del o$jeto de modo )ue sus o$jetos cuenten con un mtodo p,$lico
GetEnumerator() )ue de(uel(a un o$jeto no nulo )ue cuente con una propiedad p,$lica
llamada Current )ue permita leer el elemento actual + con un mtodo p,$lico booI
MoveNext() )ue permita cam$iar el elemento actual por el siguiente + de(uel(a faIse
slo cuando se /a+a llegado al &inal de la coleccin*
El siguiente ejemplo muestra am$os tipos de implementaciones3
using System;
using System.Collections;
class Patron
{
private int actual = -1;
public Patron GetEnumerator()
{
return this;
}
public int Current
{
get {return actual;}
}
public bool MoveNext()
{
bool resultado = true;
actual++;
if (actual==10)
resultado = false;
return resultado;
}
}
class nterfaz:Enumerable,Enumerator
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
{
private int actual = -1;
public object Current
{
get {return actual;}
}
public bool MoveNext()
{
bool resultado = true;
actual++;
if (actual==10)
resultado = false;
return resultado;
}
public Enumerator GetEnumerator()
{
return this;
}
public void Reset()
{
actual = -1;
}
}
class Principal
{
public static void Main()
{
Patron obj = new Patron();
nterfaz obj2 = new nterfaz();
foreach (int elem in obj)
Console.WriteLine(elem);
foreach (int elem in obj2)
Console.WriteLine(elem);
}
}
El tipo System.Array implementa la inter&az System.CoIIectiones.IEnumerator% por lo
)ue todas las ta$las podrn ser usadas recorridas con foreach* Si la ta$la a recorrer es
multidimensional% sus elementos se recorrern en orden como muestra este ejemplo3
int[,] tabla = { {1,2}, {3,4} };
foreach (int elemento in tabla)
Console.WriteLine(elemento);
?a salida por pantalla del &ragmento de cdigo anterior ser3
C
D
(
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
V
?a utilidad de implementar el patrn coleccin en lugar de la inter&az IEnumerabIe es
)ue as. no es necesario )ue Current de(uel(a siempre un object% sino )ue puede
de(ol(er o$jetos de tipos ms concretos + gracias a ello puede detectarse al compilar si
el <tipoElemento> indicado puede o no almacenar los o$jetos de la coleccin*
Por ejemplo% si en el ejemplo anterior sustituimos en el ,ltimo foreach el <tipoElemento>
indicado por Patrn% el cdigo seguir compilando pero al ejecutarlo saltar una
e-cepcin System.InvaIidCastException* Sin em$argo% si la sustitucin se /u$iese /ec/o
en el pen,ltimo foreach% entonces el cdigo directamente no compilar.a + se nos
in&ormar.a de un error de$ido a )ue los o$jetos int no son con(erti$les en o$jetos Patrn*
5am$in /a+ )ue tener en cuenta )ue la compro$acin de tipos )ue se realiza en tiempo
de ejecucin si el o$jeto slo implement la inter&az IEnumerabIe es mu+ estricta% en el
sentido de )ue si en el ejemplo anterior sustituimos el <tipoElemento> del ,ltimo foreach
por byte tam$in se lanzar la e-cepcin al no ser los o$jetos de tipo int impl.citamente
con(erti$les en bytes sino slo a tra(s del operador () Sin em$argo% cuando se sigue el
patrn de coleccin las compro$aciones de tipo no son tan estrictas + entonces s. )ue
ser.a (lido sustituir int por byte en <tipoElemento>*
El pro$lema de slo implementar el patrn coleccin es )ue este es una caracter.stica
propia de C# + con las instrucciones foreach Ao e)ui(alentesB de lenguajes )ue no lo
soporten no se podr.a recorrer colecciones )ue slo siguiesen este patrn* Kna solucin
en estos casos puede ser /acer )ue el tipo del o$jeto coleccin implemente tanto la
inter&az IEnumerabIe como el patrn coleccin* L$(iamente esta inter&az de$er.a
implementarse e-pl.citamente para e(itarse con&lictos deri(ados de )ue sus miem$ros
tengan signaturas coincidentes con las de los miem$ros propios del patrn coleccin*
Si un o$jeto de un tipo coleccin implementa tanto la inter&az IEnumerabIe como el
patrn de coleccin% entonces en C# foreach usar el patrn coleccin para recorrerlo*
!nstrucciones de e2cepciones
Concepto de excepcin.
?as 1I61<67.21; son el mecanismo recomendado en la plata&orma *4E5 para la
propagacin de errores )ue se produzcan durante la ejecucin de las aplicaciones
Adi(isiones por cero% intentos de lectura de arc/i(os da1ados% etc*B 0sicamente una
e-cepcin es un o$jeto deri(ado de System.Exception )ue se genera cuando en tiempo
de ejecucin se produce alg,n error + )ue contiene in&ormacin so$re el mismo*

5radicionalmente% el sistema )ue en otros lenguajes + plata&ormas se /a (enido usando
para in&ormar estos errores consist.a simplemente en /acer )ue los mtodos en cu+a
ejecucin pudiesen producirse de(ol(ieran cdigos )ue in&ormasen so$re si se /an
ejecutado correctamente o% en caso contrario% so$re cul &ue el error producido* Sin
em$argo% las e-cepciones proporcionan las siguientes (entajas &rente a dic/o sistema3
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
C-947595: El uso de cdigos especiales para in&ormar de error suele di&icultar la
legi$ilidad del &uente en tanto )ue se mezclan las instrucciones propias de la lgica
del mismo con las instrucciones propias del tratamiento de los errores )ue pudiesen
producirse durante su ejecucin* Por ejemplo3
int resultado = obj.Mtodo();
if (resultado == 0) // Sin errores al ejecutar obj.Mtodo();
{...}
else if (resultado == 1) // Tratamiento de error de cdigo 1
{...}
else if (resultado == 2) // Tratamiento de error de cdigo 2
...
Como se (er% utilizando e-cepciones es posi$le escri$ir el cdigo como si nunca se
&uesen a producir errores + dejar en una zona aparte todo el cdigo de tratamiento
de errores% lo )ue contri$u+e a &acilitar la legi$ilidad de los &uentes*
MM; 72@.4?96782: A partir del (alor de un cdigo de error puede ser di&.cil deducir
las causas del mismo + conseguirlo muc/as (eces implica tenerse )ue consultar la
documentacin )ue proporcionada so$re el mtodo )ue lo pro(oc% )ue puede
incluso )ue no especi&i)ue claramente su causa*
Por el contrario% una e-cepcin es un o$jeto )ue cuenta con campos )ue descri$en
las causas del error + a cu+o tipo suele drsele un nom$re )ue resuma claramente su
causa* Por ejemplo% para in&ormar errores de di(isin por cero se suele utilizar una
e-cepcin prede&inida de tipo DivideByZeroException en cu+o campo Message se
detallan las causas del error producido
T4939?7123. 9;1=0495.: Cuando se utilizan cdigos de error nada o$liga a tratarlos
en cada llamada al mtodo )ue los pueda producir% e ignorarlos puede pro(ocar ms
adelante en el cdigo comportamientos inesperados de causas di&.ciles de descu$rir*
Cuando se usan e-cepciones siempre se asegura )ue el programador trate toda
e-cepcin )ue pueda producirse o )ue% si no lo /ace% se a$orte la ejecucin de la
aplicacin mostrndose un mensaje indicando dnde se /a producido el error*
A/ora $ien% tradicionalmente en lenguajes como C'' el uso de e-cepciones siempre /a
tenido las des(entajas respecto al uso de cdigos de error de complicar el compilador +
dar lugar a cdigos ms lentos + di&.ciles de optimizar en los )ue tras cada instruccin
)ue pudiese producir e-cepciones el compilador de$e introducir las compro$aciones
necesarias para detectarlas + tratarlas as. como para compro$ar )ue los o$jetos creados
sean correctamente destruidos si se producen*
Sin em$argo% en la plata&orma *4E5 desaparacen los pro$lemas de complicar el
compilador + di&icultar las optimizaciones +a )ue )ue es el C?> )uien se encarga de
detectar + tratar las e-cepciones + es su recolector de $asura )uien se encarga asegurar
la correcta destruccin de los o$jetos* L$(iamente el cdigo seguir siendo algo ms
lento% pero es un pe)ue1o sacri&icio )ue merece la pena /acer en tanto )ue ello asegura
)ue nunca se producirn pro$lemas di&.ciles de detectar deri(ados de errores ignorados*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
La cIase System.Exception
Como +a se /a dic/o% todas las e-cepciones deri(an de un tipo prede&inido en la 0C?
llamado System.Exception* ?os principales miem$ros )ue /eredan de ste son3

string Message {virtuaI get;}3 Contiene un mensaje descripti(o de las causas de la
e-cepcin* Por de&ecto este mensaje es una cadena (ac.a A""B
Exception InnerException {virtuaI get;}3 Si una e-cepcin &ue causada como
consecuencia de otra% esta propiedad contiene el o$jeto System.Exception )ue
representa a la e-cepcin )ue la caus* As. se pueden &ormar cadenas de
e-cepciones de cual)uier longitud* Si se desea o$tener la ,ltima e-cepcin de la
cadena es mejor usar el mtodo virtuaI Exception GetBaseException()
string StackTrace {virtuaI get;}: Contiene la pila de llamadas a mtodos )ue se
ten.a en el momento en )ue se produjo la e-cepcin* Esta pila es una cadena con
in&ormacin so$re cul es el mtodo en )ue se produjo la e-cepcin% cul es el
mtodo )ue llam a este% cul es el )ue llam a ese otro% etc*
string Source {virtuaI get; virtuaI set;}3 Almacena in&ormacin so$re cul &ue la
aplicacin u o$jeto )ue caus la e-cepcin*
MethodBase TargetSite {virtuaI get;}3 Almacena cul &ue el mtodo donde se
produjo la e-cepcin en &orma de o$jeto System.RefIection.MethodBase* Puede
consultar la documentacin del SCD si desea cmo o$tener in&ormacin so$re
las caracter.sticas del mtodo a tra(s del o$jeto MethodBase*
string HeIpLink {virtuaI get;}: Contiene una cadena con in&ormacin so$re cul es
la K># donde se puede encontrar in&ormacin so$re la e-cepcin* El (alor de
esta cadena puede esta$lecerse con virtuaI Exception SetHeIpLink (string URI)%
)ue de(uel(e la e-cepcin so$re la )ue se aplica pero con la K># +a actualizada*
Para crear o$jetos de clase System.Exception se puede usar los constructores3
Exception()
Exception(string msg)
Exception(string msg, Exception causante)
El primer constructor crea una e-cepcin cu+o (alor para 6essage ser "" + no causada
por ninguna otra e-cepcin AInnerException (aldr nuIIB El segundo la crea con el (alor
indicado para Message% + el ,ltimo la crea con adems la e-cepcin causante indicada*
En la prctica% cuando se crean nue(os tipos deri(ados de System.Exception no se suele
rede&inir sus miem$ros ni a1adirles nue(os% sino )ue slo se /ace la deri(acin para
distinguir una e-cepciones de otra por el nom$re del tipo al )ue pertenecen* A/ora $ien%
es con(eniente respetar el con(enio de darles un nom$re aca$ado en Exception +
rede&inir los tres constructores antes comentados*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Excepciones predefinidas comunes
En el espacio de nom$res System de la 0C? /a+ prede&inidas m,ltiples e-cepciones
deri(adas de System.Exception )ue se corresponden con los errores ms comunes )ue
pueden surgir durante la ejecucin de una aplicacin* En la 5a$la R se recogen algunas3
T7<. 51 -9 1I61<6782 C90;9 51 /01 ;1 <4.50K69 -9 1I61<6782
ArgumentException
Pasado argumento no (lido A$ase de e-cepciones de
argumentosB
ArgumentNuIIException
Pasado argumento nulo
ArgumentOutOfRangeException
Pasado argumento &uera de rango
ArrayTypeMistmatchException
Asignacin a ta$la de elemento )ue no es de su tipo
COMException
E-cepcin de o$jeto CL6
DivideByZeroException
Ci(isin por cero
IndexOutOfRangeException
ndice de acceso a elemento de ta$la &uera del rango
(lido Amenor )ue cero o ma+or )ue el tama1o de la
ta$laB
InvaIidCastException
Con(ersin e-pl.cita entre tipos no (lida
InvaIidOperationException
Lperacin in(lida en estado actual del o$jeto
InteropException
0ase de e-cepciones producidas en comunicacin con
cdigo inseguro
NuIIReferenceException
Acceso a miem$ro de o$jeto )ue (ale nuII
OverfIowException
Ces$ordamiento dentro de conte-to donde se /a de
compro$ar los des$ordamientos Ae-presin constante%
instruccin c/ecIed% operancin c/ecIed u opcin del
compilador Jc/ecIedB
OutOfMemoryException
Walta de memoria para crear un o$jeto con ne=
SEHException
E-cepcin S8E del AP# Hin!
StackOverfIowException
Ces$ordamiento de la pila% generalmente de$ido a un
e-cesi(o n,mero de llamadas recurrentes*
TypeIniziaIizationException
8a ocurrido alguna e-cepcin al inicializar los
campos estticos o el constructor esttico de un tipo*
En #nnerE-ception se indica cul es*
T9C-9 8: E-cepciones prede&inidas de uso &recuente

L$(iamente% es con(eniente )ue si las aplicaciones )ue escri$amos necesiten lanzar
e-cepciones relati(as a errores de los tipos especi&icados en la T9C-9 8% lancen
precisamente las e-cepciones indicadas en esa ta$la + no cual)uier otra Z +a sea
de&inida por nosotros mismos o prede&inida en la 0C? con otro signi&icado*

Lanzamiento de excepciones. Instruccin throw
Para in&ormar de un error no $asta con crear un o$jeto del tipo de e-cepcin apropiado%
sino )ue tam$in /a+ pasrselo al mecanismo de propagacin de e-cepciones del C?>*
A esto se le llama -92K94 -9 1I61<6782% + para /acerlo se usa la siguiente instruccin3
throw <objetoExcepcinALanzar>;
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Por ejemplo% para lanzar una e-cepcin de tipo DivideByZeroException se podr.a /acer3
throw new DivideByZeroException();
Si el o$jeto a lanzar (ale nuII% entonces se producir una NuIIReferenceException )ue
ser lanzada en (ez de la e-cepcin indicada en la instruccin throw*
Captura de excepciones. Instruccin try
Kna (ez lanzada una e-cepcin es posi$le escri$ir cdigo )ue es encarge de tratarla* Por
de&ecto% si este cdigo no se escri$e la e-cepcin pro(oca )ue la aplicacin a$orte
mostrando un mensaje de error en el )ue se descri$e la e-cepcin producida
Ain&ormacin de su propiedad MessageB + dnde se /a producido Ain&ormacin de su
propiedad StackTraceB As.% dado el siguiente cdigo &uente de ejemplo3
using System;
class PruebaExcepciones
{
static void Main()
{
A obj1 = new A();
obj1.F();
}
}
class A
{
public void F()
{
G();
}
static public void G()
{
int c = 0;
int d = 2/c;
}
}
Al compilarlo no se detectar ning,n error +a )ue al compilador no le merece la pena
calcular el (alor de c en tanto )ue es una (aria$le% por lo )ue no detectar )ue di(idir 2/c
no es (lido* Sin em$argo% al ejecutarlo se intentar di(idir por cero en esa instruccin +
ello pro(ocar )ue a$orte la aplicacin mostrando el siguiente mensaje3

?nJandled @$ce5tion+ System.9i2ide1yAero@$ce5tion+ .ttem5ted to di2ide
-y Eero.
at 4rue-a@$ce5ciones.Main(%
Como se (e% en este mensaje se indica )ue no se /a tratado una e-cepcin de di(isin
por cero Atipo DivideByZeroExceptionB dentro del cdigo del mtodo Main() del tipo
PruebaExcepciones* Si al compilar el &uente /u$isemos utilizado la opcin /debug% el
compilador /a$r.a creado un &ic/ero .pdb con in&ormacin e-tra so$re las instrucciones
del ejecuta$le generado )ue permitir.a )ue al ejecutarlo se mostrase un mensaje muc/o
ms detallado con in&ormacin so$re la instruccin e-acta )ue pro(oc la e-cepcin% la
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
cadena de llamadas a mtodos )ue lle(aron a su ejecucin + el n,mero de l.nea )ue cada
una ocupa en el &uente3
?nJandled @$ce5tion+ System.9i2ide1yAero@$ce5tion+ .ttem5ted to di2ide
-y Eero.
at ..W(% in @+8c68@78e7.cs+line DD
at ..G(% in @+8c68@78e7.cs+line CR
at 4rue-a@$ce5ciones.Main(% in @+8c68@78e7.cs+line I
Si se desea tratar la e-cepcin /a+ )ue encerrar la di(isin dentro de una 72;34066782 try
con la siguiente sinta-is3
try
<instrucciones>
catc7 (<e)cepcin&>
<tratamiento&>
catc7 (<e)cepcin2>
<tratamiento2>
...
finall%
<instruccionesFinall*>
El signi&icado de try es el siguiente3 si durante la ejecucin de las <instrucciones> se
lanza una e-cepcin de tipo <excepcin1> Ao alguna su$clase su+aB se ejecutan las
instrucciones <tratamiento1>% si &uese de tipo <excepcin2> se ejecutar.a <tratamiento2>% +
as. /asta )ue se encuentre una clusula catch )ue pueda tratar la e-cepcin producida*
Si no se encontrase ninguna + la instruccin try estu(iese anidada dentro de otra% se
mirar.a en los catch de su try padre + se repetir.a el proceso* Si al &inal se recorren todos
los trys padres + no se encuentra ning,n catch compati$le% entonces se $uscar.a en el
cdigo desde el )ue se llam al mtodo )ue produjo la e-cepcin* Si as. se termina
llegando al mtodo )ue inici el /ilo donde se produjo la e-cepcin + tampoco all. se
encuentra un tratamiento apropiado se a$orta dic/o /iloU + si ese /ilo es el principal Ael
)ue contiene el punto de entradaB se a$orta el programa + se muestra el mensaje de error
con in&ormacin so$re la e-cepcin lanzada +a (isto*
As.% para tratar la e-cepcin del ejemplo anterior de modo )ue una di(isin por cero
pro(o)ue )ue a d se le asigne el (alor 2% se podr.a reescri$ir G() de esta otra &orma3
static public void G()
{
try
{
int c = 0;
int d = 2/c;
}
catch (DivideByZeroException)
{ d=0; }
}
Para simpli&icar tanto el compilador como el cdigo generado + &a(orecer la legi$ilidad
del &uente% en los catchs se $usca siempre orden de aparacin te-tual% por lo )ue para
e(itar catchs a$surdos no se permite de&inir catchs )ue puedan capturar e-cepciones
captura$les por catchs posteriores a ellos en su misma instruccin try*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
5am$in /a+ )ue se1alar )ue cuando en <instrucciones> se lance una e-cepcin )ue sea
tratada por un catch de alg,n try X+a sea de la )ue contiene las <instrucciones>% de alg,n
try padre su+o o de alguno de los mtodos )ue pro(ocaron la llamada al )ue produjo la
e-cepcinX se seguir ejecutando a partir de las instrucciones siguientes a ese try*
El $lo)ue finaIIy es opcional% + si se inclu+e /a de /acerlo tras todas los $lo)ues catch*
?as <instruccionesFinally> de este $lo)ue se ejecutarn tanto si se producen e-cepciones
en <instrucciones> como si no* En el segundo caso sus instrucciones se ejecutarn tras las
<instrucciones>% mientras )ue en el primero lo /arn despus de tratar la e-cepcin pero
antes de seguirse ejecutando por la instruccin siguiente al try )ue la trat* Si en un try
no se encuentra un catch compati$le% antes de pasar a $uscar en su try padre o en su
mtodo llamante padre se ejecutarn las <instruccionesFinally>*
Slo si dentro de un $lo)ue finaIIy se lanzase una e-cepcin se a$orta la ejecucin del
mismo* Cic/a e-cepcin ser.a propagada al try padre o al mtodo llamante padre del try
)ue contu(iese el finaIIy*
Aun)ue los $lo)ues catch + finaIIy son opcionales% toda instruccin try /a de incluir al
menos un $lo)ue catch o un $lo)ue finaIIy*
El siguiente ejemplo resume cmo &unciona la propagacin de e-cepciones3
using System;
class MiException:Exception {}
class Excepciones
{
public static void Main()
{
try
{
Console.WriteLine(En el try de Main());
Mtodo();
Console.WriteLine(Al final del try de Main());
}
catch (MiException)
{
Console.WriteLine(En el catch de Main());
}
finally
{
Console.WriteLine(finally de Main());
}
}
public static void Mtodo()
{
try
{
Console.WriteLine(En el try de Mtodo());
Mtodo2();
Console.WriteLine(Al final del try de Mtodo());
}
catch (OverflowException)
{
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Console.WriteLine(En el catch de Mtodo());
}
finally
{
Console.WriteLine(finally de Mtodo());
}
}
public static void Mtodo2()
{
try
{
Console.WriteLine(En el try de Mtodo2());
throw new MiException();
Console.WriteLine(Al final del try de Mtodo2());
}
catch (DivideByZeroException)
{ Console.WriteLine(En el catch de Mtodo2()); }
finally
{ Console.WriteLine(finally de Mtodo2()); }
}
}
4tese )ue en este cdigo lo ,nico )ue se /ace es de&inir un tipo nue(o de e-cepcin
llamado MiException + llamarse en el Main() a un mtodo llamado Mtodo() )ue llama a
otro de nom$re Mtodo2() )ue lanza una e-cepcin de ese tipo* ;iendo la salida de este
cdigo es &cil (er el recorrido seguido durante la propagacin de la e-cepcin3
@n try de Main(%
@n try de MPtodo(%
@n try de MPtodoD(%
<inally de MPtodoD
<inally de MPtodo
@n catcJ de Main(%
<inally de Main(%
Como se puede o$ser(ar% /a+ muc/os WriteLine() )ue nunca se ejecutan +a )ue en
cuento se lanza una e-cepcin se sigue ejecutando tras la instruccin siguiente al try )ue
la trat Aaun)ue ejecutando antes los finaIIy pendientes% como se deduce de la salida del
ejemploB Ce /ec/o% el compilador se dar cuenta )ue la instruccin siguiente al throw
nunca se ejecutar e in&ormar de ello con un mensaje de a(iso*
?a idea de todo este mecanismo de e-cepciones es e(itar mezclar el cdigo normal con
el cdigo de tratamiento de errores* As.% en <instrucciones> se esci$ir.a el cdigo como si
no se pudiesen producir errores% en las clusulas catch se tratar.an los posi$les errores% +
en la clusula finaIIy se incluir.a cdigo a ejecutar tanto si produjesen errores como si no
Asuele usarse para li$erar recursos ocupados% como &ic/ero o cone-iones de red a$iertasB
En realidad% tam$in es posi$le escri$ir cada clusula catch de&iniendo una (aria$le )ue
se podr usar dentro del cdigo de tratamiento de la misma para /acer re&erencia a la
e-cepcin capturada* Esto se /ace con la sinta-is3
catch (<tipoExcepcin> <nombreVariable>)
{
<tratamiento>
}
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
4tese )ue en tanto )ue todas las e-cepciones deri(an de System.Exception% para
de&inir una clusula catch )ue pueda capturar cual)uier tipo de e-cepcin $asta usar3
catch(System.Exception <nombre#b+ecto>)
{
<tratamiento>
}
En realidad la sinta-is anterior slo permite capturar las e-cepciones propias de la
plata&orma *4E5% )ue deri(an de System.Exception* Sin em$argo% /a+ lenguajes como
C'' )ue permiten lanzar e-cepciones no deri(adas de dic/a clase% + para esos casos se
/a incluido en C# una (ariante de catch s. )ue realmente puede capturar e-cepciones de
cual)uier tipo% tanto si deri(an de System.Exception como si no* Su sinta-is es3
catch
{
<tratamiento>
}
Como puede deducirse de su sinta-is% el pro$lema )ue presenta esta ,ltima (ariante de
catch es )ue no proporciona in&ormacin so$re cul es la e-cepcin capturada% por lo
)ue a (eces puede resultar poco ,til + si slo se desea capturar cual)uier e-cepcin
deri(ada de System.Exception es mejor usar la sinta-is e-plicada pre(iamente a ella*
En cual)uier casos% am$os tipos de clusulas catch slo pueden ser escritas como la
,ltima clusula catch del try% +a )ue si no las clusulas catch )ue le siguiesen nunca
llegar.an a ejecutarse de$ido a )ue las primeras capturar.an antes cual)uier e-cepcin
deri(ada de System.Exception*
>especto al uso de throw% /a+ )ue se1alar )ue /a+ una &orma e-tra de usarlo )ue slo es
(lida dentro de cdigos de tratamiento de e-cepciones Acdigos <tratamientoi> de las
clusulas catchB Esta &orma de uso consiste en seguir simplemente esta sinta-is3
throw;
En este caso lo )ue se /ace es relanzar la misma e-cepcin )ue se captur en el $lo)ue
catch dentro de cu+o de cdigo de tratamiento se usa el throw; 8a+ )ue precisar )ue la
e-cepcin relanzada es precisamente la capturada% + aun)ue en el $lo)ue catch se la
modi&i)ue a tra(s de la (aria$le )ue la repreesnta% la (ersin relanzada ser la (ersin
original de la misma + no la modi&icada*
Adems% cuando se relance una e-cepcin en un try con clusula finaIIy% antes de pasar a
reprocesar la e-cepcin en el try padre del )ue la relanz se ejecutar dic/a clusula*

!nstrucciones de salto
?as 72;340667.21; 51 ;9-3. permiten ejecutar (ariar el orden normal en )ue se ejecutan
las instrucciones de un programa% )ue consiste en ejecutarlas una tras otra en el mismo
orden en )ue se /u$iesen escrito en el &uente* En los su$apartados de este ep.gra&e se
descri$irn cules son las instrucciones de salto incluidas en C#3
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Instruccin break
Va se /a (isto )ue la 72;34066782 break slo puede incluirse dentro de $lo)ues de
instrucciones asociados a instrucciones iterati(as o instrucciones switch e indica )ue se
desea a$ortar la ejecucin de las mismas + seguir ejecutando a partir de la instruccin
siguiente a ellas* Se usa as.3
break;
Cuando esta sentencia se usa dentro de un try con clusula finaIIy% antes de a$ortarse la
ejecucin de la instruccin iterati(a o del switch )ue la contiene + seguirse ejecutando
por la instruccin )ue le siga% se ejecutarn las instrucciones de la clusula finaIIy del
try* Esto se /ace para asegurar )ue el $lo)ue finaIIy se ejecute a,n en caso de salto*
Adems% si dentro una clusula finaIIy incluida en de un switch o de una instruccin
iterati(a se usa break% no se permite )ue como resultado del break se salga del finaIIy*
Instruccin continue
Va se /a (isto )ue la 72;34066782 continue slo puede usarse dentro del $lo)ue de
instrucciones de una instruccin iterati(a e indica )ue se desea pasar a ree(aluar
directamente la condicin de la misma sin ejecutar el resto de instrucciones )ue
contu(iese* ?a e(aluacin de la condicin se /ar.a de la &orma /a$itual3 si es cierta se
repite el $ucle + si es &alsa se contin,a ejecutando por la instruccin )ue le sigue* Su
sinta-is de uso es as. de sencilla3
continue;
En cuanto a sus usos dentro de sentencias try% tiene las mismas restricciones )ue break3
antes de salir de un try se ejecutar siempre su $lo)ue finaIIy + no es posi$le salir de un
finaIIy incluido dentro de una instruccin iterati(a como consecuencia de un continue*
Instruccin return
Esta instruccin se usa para indicar cul es el o$jeto )ue /a de de(ol(er un mtodo% + se
usa as.3
return <objetoRetorno>;
?a ejecucin de esta instruccin pro(oca )ue se a$orte la ejecucin del mtodo dentro
del )ue aparece + )ue se de(uel(a el <objetoRetorno> al mtodo )ue lo llam* Como es
lgico% este o$jeto /a de ser del tipo de retorno del mtodo en )ue aparece el return o de
alguno compati$le con l% por lo )ue esta instruccin slo podr incluirse en mtodos
cu+o tipo de retorno no sea void% o en los $lo)ues get de las propiedades o indizadores*
Ce /ec/o% es o$ligatorio )ue todo mtodo con tipo de retorno termine por un return*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
?os mtodos )ue de(uel(an void pueden tener un return con una sinta-is espacial en la
)ue no se indica ning,n (alor a de(ol(er sino )ue simplemente se usa return para
indicar )ue se desea terminar la ejecucin del mtodo3
return;
4ue(amente% como con el resto de instrucciones de salto /asta a/ora (istas% si se
inclu+ese un return dentro de un $lo)ue try con clusula finaIIy% antes de de(ol(erse el
o$jeto especi&icado se ejecutar.an las instrucciones de la clusula finaIIy* Si /u$iesen
(arios $lo)ues finaIIy anidados% las instrucciones de cada uno es ejecutar.an de manera
ordenada Ao sea% del ms interno al ms e-ternoB A/ora $ien% lo )ue no es posi$le es
incluir un return dentro de una clusula finaIIy*
Instruccin goto
?a 72;34066782 goto permite pasar a ejecutar el cdigo a partir de una instruccin cu+a
eti)ueta se indica en el goto* ?a sinta-is de uso de esta instruccin es3
goto <etiqueta>;
Como en la ma+or.a de los lenguajes% goto es una 72;34066782 ?9-5739 cu+o uso no se
recomienda por)ue di&iculta innecesariamente la legi$ilidad del cdigo + suele ser &cil
simularla usando instrucciones iterati(as + selecti(as con las condiciones apropiadas*
Sin em$argo% en C# se inclu+e por)ue puede ser e&iciente usarla si se anidan muc/as
instrucciones + para reducir sus e&ectos negati(os se le /an impuesto unas restricciones3
Slo se pueden eti)uetar instrucciones% + no a directi(as using, directi(as de
preprocesado% de&iniciones de miem$ros% de tipos o de espacios de nom$res*
?a eti)ueta indicada no pueda pertenecer a un $lo)ue de instrucciones anidado
dentro del $lo)ue desde el )ue se usa el goto ni )ue eti)uete a instrucciones de otro
mtodo di&erente a a)ul en el cual se encuentra el goto )ue la re&erencia*
Para eti)uetar una instruccin de modo )ue pueda ser destino de un salto con goto $asta
precederla del nom$re con el )ue se la )uiera eti)uetar seguido de dos puntos A:B Por
ejemplo% el siguiente cdigo demuestra cmo usar goto + de&inir una eti)ueta3
using System;
class HolaMundoGoto
{
public static void Main(string[] args)
{
for (int i=0; i<args.Length; i++)
{
if (args[i] != salir)
Console.WriteLine(args[i]);
else
goto fin:
}
fin: ;
}
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
}
Este programa de ejemplo lo )ue /ace es mostrar por pantalla todos los argumentos )ue
se le pasen como parmetros% aun)ue si alguno de &uese salir entonces se dejar.a de
mostrar argumentos + se a$orta la ejecucin de la aplicacin* ;ase adems )ue este
ejemplo pone de mani&iesto una de las utilidades de la instruccin nula% +a )ue si no se
/u$iese escrito tras la eti)ueta fin el programa no compilar.a en tanto )ue toda eti)ueta
/a de preceder a alguna instruccin Aaun)ue sea la instruccin nulaB
4tese )ue al &in + al ca$o los usos de goto dentro de instrucciones switch )ue se (ieron
al estudiar dic/a instruccin no son ms )ue (ariantes del uso general de goto% +a )ue
defauIt: no es ms )ue una eti)ueta + case <valor>: puede (erse como una eti)ueta un
tanto especial cu+o nom$re es case seguido de espacios en $lanco + un (alor* En am$os
casos% la eti)ueta indicada /a de pertenecer al mismo s=itc/ )ue el goto usado + no (ale
)ue ste no la contenga pero la contenga alg,n switch )ue contenga al switch del goto*
El uso de goto dentro de sentencias try% tiene las mismas restricciones )ue break%
continue + return3 antes de salir con un goto de un try se ejecutar siempre su $lo)ue
finaIIy + no es posi$le &orzar a saltar &uera de un finaIIy*
Instruccin throw
?a instruccin throw +a se /a (isto )ue se usa para lanzar e-cepciones de este modo3
throw <ob+etoE)cepcin(,an-ar>;
En caso de )ue no se indi)ue ning,n <objetoExcepcinALanzar> se relanzar el )ue se
estu(iese tratando en ese moment% aun)ue esto slo es posi$le si el throw se /a escrito
dentro del cdigo de tratamiento asociado a alguna clusula catch*
Como +a se /a e-plicado a &ondo esta instruccin en este mismo tema% para ms
in&ormacin so$re $asta remitirse al ep.gra&e E/$ep$iones de este tema*
&tras instrucciones
?as instrucciones (istas /asta a/ora son comunes a muc/os lenguajes de programacin*
Sin em$argo% en C# tam$in se /a incluido un $uen n,mero de nue(as instrucciones
propias de este lenguaje* Estas instrucciones se descri$en en los siguientes apartados3
Instrucciones checked y unchecked
?as instrucciones c/ecIed + unc/ecIed permiten controlar la &orma en )ue tratarn los
des$ordamientos )ue ocurran durante la realizacin de operaciones aritmticas con tipos
$sico enteros* Wuncionan de &orma similar a los operadores checked + unchecked +a
(istos en el Tema *: .spe$tos l/i$os% aun)ue a di&erencia de stos son aplica$les a
$lo)ues enteros de instrucciones + no a una ,nica e-presin* As.% la instruccin checked
se usa de este modo3
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
checked
<instrucciones>
5odo des$ordamiento )ue se produzca al realizar operaciones aritmticas con enteros en
<instrucciones> pro(ocar )ue se lance una e-cepcin System.OverfIowException* Por su
parte% la 72;34066782 unchecked se usa as.3
unchecked
<instrucciones>
En este caso% todo des$ordamiento )ue se produzca al realizar operaciones aritmticas
con tipos $sicos enteros en <instrucciones> ser ignorado + lo )ue se /ar ser tomar el
(alor resultante de )uedarse con los $its menos signi&icati(os necesarios*
Por de&ecto% en ausencia de estas instrucciones las e-presiones constantes se e(al,an
como si se inclu+esen dentro de una instruccin checked + las )ue no constantes como
si se inclu+esen dentro de una instruccin unchecked* Sin em$argo% a tra(s de la
opcin /chec@ed del compilador es posi$le tanto /acer )ue por de&ecto se comprue$en
los des$ordamiento en todos los casos para as. siempre poder detectarlos + tratarlos
Cesde ;isual Studio*4E5% la &orma de controlar el tipo de compro$aciones )ue por
de&ecto se /arn es a tra(s de V71D P4.<13: P9=1; C.2@7=04937.2 S13372=;
B07-5 CJ16E @.4 .A14@-.D 02514@-.D*
El siguiente cdigo muestra un ejemplo de cmo usar am$as instrucciones3
using System;
class Unchecked
{
static short x = 32767; // Valor maximo del tipo short
public static void Main()
{
unchecked
{
Console.WriteLine((short) (x+1)); // (1)
Console.WriteLine((short) 32768); // (2)
}
}
}
En un principio este cdigo compilar.a% pero los des$ordamientos producidos por el
/ec/o de )ue ![TR no es un (alor )ue se pueda representar con un short A1T $its con
signoB pro(ocar.a )ue apareciese por pantalla dic/o (alor truncado% mostrndose3
'(DXRI
'(DRXI
Sin em$argo% si sustitu+semos la instruccin unchecked por checked% el cdigo
anterior ni si)uiera compilar.a +a )ue el compilador detectar.a )ue se (a a producir un
des$ordamiento en (2) de$ido a )ue ![TR es constante + no representa$le con un short*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Si eliminamos la instruccin (2) el cdigo compilar.a +a )ue (x+1) no es una e-presin
constante + por tanto el compilador no podr.a detectar des$ordamiento al compilar* Sin
em$argo% cuando se ejecutase la aplicacin se lanzar.a una System.OverfIowException*
Instruccin Iock
?a 72;34066782 Iock es ,til en aplicaciones concurrentes donde m,ltiples /ilos pueden
estar accediendo simultneamente a un mismo recurso% +a )ue lo )ue /ace es garantizar
)ue un /ilo no pueda acceder a un recurso mientras otro tam$in lo est /aciendo* Su
sinta-is es la siguiente3
Iock (<objeto>)
<instrucciones>
Su signi&icado es el siguiente3 ning,n /ilo puede ejecutar las <instrucciones> del $lo)ue
indicado si otro las est ejecutando% + si alguno lo intenta se )uedar esperando /asta
)ue aca$e el primero* Esto tam$in a&ecta a $lo)ues de <instrucciones> de cual)uier otro
Iock cu+o <objeto> sea el mismo* Este <objeto> /a de ser de alg,n tipo re&erencia*
En realidad% la instruccin anterior es e)ui(alente a /acer3
System.Threading.Monitor.Enter(<objeto>);
try
<instrucciones>
finaIIy
{
System.Threading.Monitor.Exit(<objeto>);
}
Sin em$argo% usar Iock tiene dos (entajas3 es ms compacto + e&iciente A<objeto> slo se
e(al,a una (ezB

Kna $uena &orma de garantizar la e-clusin mutua durante la ejecucin de un mtodo de
un cierto o$jeto es usando this como <objeto> En el caso de )ue se tratase de un mtodo
de tipo% en tanto )ue this no tiene sentido dentro de estos mtodos estticos una $uena
alternati(a ser.a usar el o$jeto System.Type )ue representase a ese tipo* Por ejemplo3
class C
{
public static void F()
{
lock(typeof(C))
{
// ... Cdigo al que se accede exclusivamente
}
}
}
Instruccin using
?a 72;34066782 using &acilita el tra$ajo con o$jetos )ue tengan )ue ejecutar alguna tarea
de limpieza o li$eracin de recursos una (ez )ue termine de ser ,tiles* Aun)ue para
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
estos menesteres +a estn los destructores% dado su carcter indeterminista puede )ue en
determinadas ocasiones no sea con(eniente con&iar en ellos para realizar este tipo de
tareas* ?a sinta-is de uso de esta instruccin es la siguiente3

using (<tipo> <declaraciones>)
<instrucciones>
En <declaraciones> se puede indicar uno o (arios o$jetos de tipo <tipo> separados por
comas* Estos o$jetos sern de slo lectura + slo sern accesi$les desde <instrucciones> *
Adems% /an de implementar la inter&az System.IDisposabIe de&inida como sigue3
interface IDisposabIe
{
void Dispose()
}
En la implementacin de Dispose() se escri$ir.a el cdigo de limpieza necesario% pues el
signi&icado de using consiste en )ue al aca$ar la ejecucin de <instrucciones>% se llama
automticamente al mtodo Dispose() de los o$jetos de&inidos en <declaraciones>
8a+ )ue tener en cuenta )ue la llamada a Dispose() se /ace sea cual sea la razn de )ue
se deje de ejecutar las <instrucciones> Es decir% tanto si se /a producido una e-cepcin
como si se /a aca$ado su ejecucin normalmente o con una instruccin de salto%
Dispose() es siempre llamado* En realidad una instruccin using como3
using (R1 r1 = new R1())
{
r1.F();
}
Es tratada por el compilador como3
{
R1 r1 = new R1()
try
{
r1.F();
}
finally
{
if (r1!=null)
((Disposable) r1).Dispose();
}
}
Si se declarasen (arios o$jetos en <declaraciones>% a Dispose() se le llamar.a en el orden
in(erso a como &ueron declarados* ?o mismo ocurre si se anidasen (arias instrucciones
using3 primero se llamar.a al Dispose() de las (aria$les declaradas en los using internos
+ luego a las de los e-ternos* As.% estas dos instrucciones son e)ui(alentes3
using (Recurso obj = new Recurso(), obj2= new Recurso())
{
r1.F();
r2.F();
}
using (Recurso obj = new Recurso())
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
{
using (Recurso obj2= new Recurso())
{
r1.F();
r2.F();
}
}
El siguiente ejemplo resume cmo &unciona la sentencia using3
using System;
class A:Disposable
{
public void Dispose()
{
Console.WriteLine("Llamado a Dispose() de {0}", Nombre);
}
public A(string nombre)
{
Nombre = nombre;
}
string Nombre;
}
class Using
{
public static void Main()
{
A objk = new A("objk");
using (A obj1 = new A("obj1"), obj2 = new A("objy"))
{
Console.WriteLine("Dentro del using");
}
Console.WriteLine("Fuera del using");
}
}
?a salida por pantalla resultante de ejecutar este ejemplo ser3
Dentro del using
Llamando a Dispose() de objy
Llamando a Dispose() de obj1
Fuera del using
Como se deduce de los mensajes de salida o$tenidos% justo antes de salirse del using se
llama a los mtodos Dispose() de los o$jetos declarados en la seccin <decIaraciones>
de dic/a instruccin + en el mismo orden en )ue &ueron declarados*
Instruccin fixed
?a 72;34066782 fixed se utiliza para &ijar o$jetos en memoria de modo )ue el recolector
de $asura no pueda mo(erlos durante la ejecucin de un cierto $lo)ue de instrucciones*
El lenguaje de programacin C# 5ema 1T3 #nstrucciones
Esta instruccin slo tiene sentido dentro de regiones de cdigo inseguro% concepto )ue
se trata en el Tema %8: C)di(o inse(#ro% por lo )ue ser all. es donde se e-pli)ue a
&ondo cmo utilizarla* A)u. slo diremos )ue su sinta-is de uso es3
fixed(<tipoPunteros> <declaracionesPunterosAFijar>)
<instrucciones >
El lenguaje de programacin C# 5ema 1[3 Atri$utos
TEMA 17: ATRIBUTOS
Concepto de atributo
Kn 9347C03. es in&ormacin )ue se puede a1adir a los metadatos de un mdulo de
cdigo* Esta in&ormacin puede ser re&erente tanto al propio mdulo o el ensam$lado al
)ue peretenezca como a los tipos de datos en de&inidos en l% sus miem$ros% los
parmetros de sus mtodos% los $lo)ues set + get de sus propiedades e indizadores o los
$lo)ues add + remove de sus e(entos*
En C# se inclu+en numerosos modi&icadores )ue nos permiten asociar in&ormacin a los
metadatos de un mdulo* Por ejemplo% con los modi&icadores pubIic% protected% private%
internaI o protected internaI podemos a1adir in&ormacin so$re la (isi$ilidad de los
tipos del mdulo + de sus miem$ros* Pues $ien% los atri$utos pueden (erse como un
mecanismo mediante el cual el programador puede crear sus propios modi&icadores*
Kn ejemplo de atri$uto podr.a ser uno llamado Ayuda )ue pudiese pre&ijar las
de&iniciones de miem$ros de tipos e indicase cul es la K>? donde se pudiese encontrar
in&ormacin detallada con a+uda so$re el signi&icado del miem$ro pre&ijado*
5tilizacin de atributos
Para colocar un atri$uto a un elemento $asta pre&ijar la de&inicin de dic/o elemento
con una estructura de esta &orma3
[<nombreAtributo>(<parmetros>]
Esta estructura /a de colocarse incluso antes )ue cual)uier modi&icador )ue pudiese
acompa1ar la de&inicin del elemento a atri$uir*
?os parmetros de una atri$uto pueden ser opcionales% + si se usa sin especi&icar (alores
para sus parmetros no /a+ por)u )ue usar parntesis (ac.os como en las llamadas a
mtodos% sino )ue $asta usar el atri$uto indicando slo la sinta-is [<nombreAtributo>]
?os parmetros de un atri$uto pueden ser de dos tipos3
P94M?134.; ;72 2.?C41: Se usan de &orma similar a los parmetros de los
mtodos% slo )ue no pueden contar con modi&icadores ref u out*
P94M?134.; 6.2 2.?C41: Son opcionales + pueden colocarse en cual)uier
posicin en la lista de <parmetros> del atri$uto* ?o ,ltimo se de$e a )ue a la
/ora de darles (alor se usa la sinta-is <nombreParmetro>=<valor>% por lo )ue el
compilador no depender de su posicin a la /ora de determinar a )u parmetro
se le est dando cada (alor*
El lenguaje de programacin C# 5ema 1[3 Atri$utos
Para e(itar con&lictos entre parmetros con nom$re + parmetros sin nom$re% los
primeros siempre se /an de incluir despus de los segundos% no siendo posi$le
mezclarlos indiscriminadamente*
Si se desean especi&icar (arios atri$utos para un mismo elemento se pueden indicar
todos ellos entre unos mismos corc/etes serapados por comas* Es decir% de la &orma3
[<atributo1>(<parametros&>, <atributo2>(<parmetros>, ...]
Aun)ue tam$in ser.a posi$le especi&icarlos por separado* L sea% de esta otra &orma3
[<atributo1>(<parametros&>] [<atributo2>(parmetros>] ...
8a+ casos en los )ue por la u$icacin del atri$uto no se puede determinar de manera
un.(oca a cul elemento se le desea aplicar% +a )ue podr.a ser aplica$le a (arios* En esos
casos% para e(itar am$igaedades lo )ue se /ace es usar el atri$uto pre&ijando su nom$re
de un 7257695.4 51 37<. 51 1-1?123.% )uedando as. la sinta-is a usar3
[<indicadorElemento>0<nombreAtributo>(<parmetros>]
Aun)ue cada implementacin de C# puede incluir sus propios indicadores de tipo de
elemento% todas ellas incluirn al menos los siguientes3
assembIy: #ndica )ue el atri$uto se aplica al ensam$lado en )ue se compile el
cdigo &uente )ue lo contenga* Al de&inir atri$utos de ensam$lado es o$ligatorio
incluir este indicador% +a )ue estos atri$utos se colocan precediendo cual)uier
de&inicin de clase o espacio de nom$res + si no se inclu+esen se con&undir.a
con atri$utos de tipo% )ue se colocan en el mismo sitio*
moduIe: #ndica )ue el atri$uto se aplica al mdulo en )ue se compile el cdigo
&uente )ue lo contenga* Al igual )ue el indicador assembIy% /a+ )ue incluirlo
siempre para de&inir este tipo de atri$utos por)ue si no se con&undir.an con
atri$utos de tipo% +a )ue tam$in se /an de u$icar precediendo las de&iniciones
de clases + espacios de nom$res*
type: #ndica )ue el atri$uto se aplica al tipo cu+a de&inicin precede* En realidad
no /ace &alta utilizarlo% pues es lo )ue por de&ecto se considera para todo atri$uto
)ue preceda a una de&inicin de tipo* Sin em$argo% se /a incluido por
consistencia con el resto de indicadores de tipo de atri$uto + por)ue puede
resultar con(eniente incluirlo +a )ue e-plicitarlo &acilita la lectura del cdigo*
return: #ndica )ue el atri$uto se aplica a un (alor de retorno de un mtodo%
operador% $lo)ue get% o de&inicin de delegado* Si no se inclu+ese se
considerar.a )ue se aplica a la de&inicin del mtodo% operador% $lo)ue get o
delegado% +a )ue estos atri$utos se colocan antes de la misma al igual )ue los
atri$utos de (alores de retorno*
param: #ndica )ue el atri$uto se aplica a un parmetro de un mtodo* Si no se
inclu+ese al de&inir $lo)ues set% add o remove se considerar.a )ue el atri$uto se
re&iere a los $lo)ues en s. + no al parmetro vaIue en ellos impl.cito*
El lenguaje de programacin C# 5ema 1[3 Atri$utos
method: #ndica )ue el atri$uto se aplica al mtodo al )ue precede* En realidad no
es necesario usarlo por)ue% como se dice en la e-plicacin de los indicadores
param + return% es lo )ue se considera por de&ecto* Sin em$rago% + como pasa$a
con type% se inclu+e por consistencia + por)ue puede ser $uena idea incluirlo
para &acilitar la legi$ilidad del cdigo con su e-plicitacin*
event: #ndica )ue el atri$uto se aplica al e(ento a cu+a de&inicin precede* En
realidad no es necesario incluirlo por)ue es lo )ue se considera por de&ecto% pero
nue(amente se /a incluido por consistencia + para &acilitar la lectura del cdigo*
property: #ndica )ue el atri$uto se aplica a la propiedad a cu+a de&inicin
precede* <ste tam$in es es un indicador innecesario e incluido tan slo por
consistencia + para &acilitar la legi$ilidad del cdigo*
fieId: #ndica )ue el atri$uto se aplica al cu+a de&inicin precede* Como otros
indicadores% slo se inclu+e por consistencia + para /acer ms legi$le el cdigo*
)efinicin de nuevos atributos
Especificacin deI nombre deI atributo
Se considera )ue un atri$uto es toda a)uella clase )ue deri(e de System.Attribute* Por
tanto% para de&inir un nue(o tipo de atri$uto /a+ )ue crear una clase )ue deri(e de ella*
Por con(enio% a este tipo de clases suele drseles nom$res aca$ados en Attribute% aun)ue
a la /ora de usarlas desde C# es posi$le o$(iar dic/o su&ijo* Kn ejemplo de cmo de&inir
una atri$uto llamado Ayuda es3
using System;
class AyudaAttribute:Attribute
{}
V ejemplos de cmo usarlo pre&ijando la de&inicin de clases son3
[Ayuda] class A
{}
[AyudaAttribute] class B
{}
Puede darse la circunstancia de )ue se /a+a de&inido un atri$uto con un cierto nom$re
sin su&ijo Attribute + otro )ue si lo tenga* Como es lgico% en ese caso cuando se use el
atri$uto sin especi&icar el su&ijo se /ar re&erencia a la (ersin sin su&ijo + cuando se use
con su&ijo se /ar re&erencia a la (ersin con su&ijo*
Especificacin deI uso de un atributo
Por de&ecto cual)uier atri$uto )ue se de&ina puede preceder la de&inicin de cual)uier
elemento del lenguaje* Si se desea limitar a )u de&iniciones puede preceder es
El lenguaje de programacin C# 5ema 1[3 Atri$utos
necesario pre&ijar la clase )ue lo de&ine con un atri$uto especial llamado
System.AttributeUsage* Este atri$uto consta de los siguientes parmetros con nom$re3
AIIowMuItipIe: Por de&ecto cada atri$uto slo puede aparecer una (ez pre&ijando
a cada elemento* Cndole el (alor true a este parmetro se considerar )ue
puede aparecer m,ltiples (eces*
Inherited: Por de&ecto los atri$utos aplicados a una clase no son /eredados en sus
clases /ijas* Cndole el (alor true a este parmetros se consigue )ue s. lo sean*
Aparte de estos dos parmetros% AttributeUsage tam$in puede contar con un parmetro
opcional sin nom$re )ue indi)ue a )u tipos de de&iniciones puede preceder* Por de&ecto
se considera )ue un atri$uto puede preceder a cual)uier elemento% lo )ue es e)ui(alente
a darle el (alor AttributeTargets.AII a este parmetro* Sin em$rago es posi$le especi&icar
otras posi$ilidades dndole (alores de la enumeracin System.AttributeTargets% )ue son
los )ue se recogen en la 5a$la :3
V9-.4 51 AttributeTargets S7=27@769 /01 1- 9347C03. <0151 <4161514 9...
AII
Cual)uier de&inicin
AssembIy
Ce&iniciones de espacio de nom$res% considerndose
)ue el atri$uto se re&iere al ensam$lado en general*
ModuIe
Ce&iniciones de espacio de nom$res% considerndose
)ue el atri$uto se re&iere al mdulo en su conjunto*
CIass
Ce&iniciones de clases
DeIegate
Ce&iniciones de delegados
Interface
Ce&iniciones de inter&aces
Struct
Ce&iniciones de estructuras
Enum
Ce&iniciones de enumeraciones
FieId
Ce&iniciones de campos
Method
Ce&iniciones de mtodos
Constructor
Ce&iniciones de constructores
Property
Ce&iniciones de propiedades o indizadores
Event
Ce&iniciones de e(entos
Parameter
Ce&iniciones de parmetros de mtodos
ReturnVaIue
Ce&iniciones de (alores de retorno de mtodos
T9C-9 +: ;alores de AttributeTargets
Es posi$le com$inar (arios de estos (alores mediante operaciones lgicas NorO Acarcter
| B Por ejemplo% si )ueremos de&inir el atri$uto Ayuda anterior de modo )ue slo pueda
ser usado para pre&ijar de&iniciones de enumeraciones o de clases se /ar.a3
[AttributeUsage(AttributeTargets.Class | AttributeTargetes.Enum)]
class Ayuda:Attribute
{}
Es importante resaltar )ue AttributeUsage slo puede incluirse precediendo de&iniciones
de otros atri$utos Ao sea% de clases deri(adas de System.AttributeB
El lenguaje de programacin C# 5ema 1[3 Atri$utos
Especificacin de parmetros vIidos
Se considera )ue los parmetros sin nom$re )ue puede tomar un atri$uto son a)uellos
)ue se especi&i)uen como parmetros en el constructor del tipo )ue lo de&ine% + )ue sus
parmetros con nom$re sern las propiedades + campos p,$licos% no estticos + de
lecturaJescritura de&inidos en dic/o tipo*

Kn ejemplo de cmo de&inir el atri$uto Ayuda anterior de modo )ue tome un parmetro
sin nom$re con la K>? )ue indi)ue dnde encontrar la a+uda so$re el miem$ro o clase
al )ue precede + un parmetro con nom$re llamado Autor )ue indi)ue )uin es el autor
de esa documentacin es3
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum)]
class Ayuda:Attribute
{
private string autor;
private string url;
public Ayuda(string URL)
{ url=URL; }
public string Autor
{
set {autor = value;}
get {return autor;}
}
}
Ejemplos de usos (lidos de este atri$uto son3
[Ayuda(http://www.josan.com/Clases/A.html)]
class A {}
[Ayuda(http://www.josan.com/Clases/B.html, Autor=Jos Antonio Gonzlez Seco)]
class B {}
?os tipos (lidos de parmetros% tanto con nom$re como sin l% )ue puede tomar un
atri$uto son3 cual)uier tipo $sico e-cepto decimaI + los tipos enteros sin signo%
cual)uier enumeracin p,$lica% System.Type o ta$las unidimensionales de elementos de
cual)uiera de los anteriores tipos (lidos*
Lectura de atributos en tiempo de e'ecucin
Para acceder a los metadatos de cual)uier ensam$lado se utilizan las clases del espacio
de nom$res System.RefIection* Este espacio de nom$res es inmenso + e-plicar cmo
utilizarlo )ueda &uera del alcance de este li$ro% aun)ue de todos modos a continuacin
se darn unas ideas $sicas so$re cmo acceder a tra(s de sus tipos a los atri$utos
incluidos en los ensam$lados*
?a cla(e para acceder a los atri$utos se encuentra en el mtodo esttico de la clase
System.Attribute llamado Attribute[] GetCustomAttributes(<x> objetoRefIexivo)% donde
<x> es el tipo de System.RefIection )ue representa a los elementos cu+os atri$utos se
desea o$tener* ?os posi$les tipos son3 AssembIy% )ue representa ensam$lados% ModuIe
El lenguaje de programacin C# 5ema 1[3 Atri$utos
)ue representa mdulos% MemberInfo )ue representa miem$ros Aincluidos tipos% )ue al
&in + al ca$o son miem$ros de espacios de nom$resB% + ParameterInfo )ue representa
parmetros* El parmetros tomado por este mtodo ser el o$jeto )ue represente al
elemento en concreto cu+os metadatos se )uieren o$tener*
Como se (e% GetCustomAttributes() de(uel(e una ta$la con los atri$utos en &orma de
o$jetos Attribute% )ue es la clase $ase de todos los atri$utos% por lo )ue si a partir de
ellos se desease acceder a caracter.sticas espec.&ica de cada tipo de atri$uto /a$r.a )ue
aplicar do=ncasting como se coment en el Tema 5: Clases Apara asegurase de )ue las
con(ersiones se realicen con -ito recurdese )ue se puede usar el operador is para
determinar cul es el (erdadero tipo de cada atri$uto de esta ta$laB
Para o$tener el o$jeto AssembIy )ue representa al ensam$lado al )ue pertenezca el
cdigo )ue se est ejecutando se usa el mtodo AssembIy GetExecutingAssembIy() de la
clase AssembIy% )ue se usa tal + como se muestra3
Assembly ensamblado = Assembly.GetExecutingAssembly();
Ltra posi$ilidad ser.a o$tener ese o$jeto AssembIy a partir del nom$re del &ic/ero
donde se encuentre almacenado el ensam$lado* Para ello se usa el mtodo AssembIy
LoadFrom(string rutaEnsambIado) de la clase AssembIy como se muestra3

Assembly ensamblado = Assembly.LoadFrom(josan.dll);
Kna (ez o$tenido el o$jeto )ue representa a un ensam$lado pueden o$tenerse los
o$jetos ModuIe )ue representan a los mdulos )ue lo &orman a tra(s de su mtodo
ModuIe[] GetModuIes()*
A partir del o$jeto ModuIe )ue representa a un mdulo puede o$tenerse los o$jetos Type
)ue representan a sus tipos a tra(s de su mtodo Type[] GetTypes() Ltra posi$ilidad
ser.a usar el operador typeof +a (isto para o$tener el Type )ue representa a un tipo en
concreto sin necesidad de crear o$jetos ModuIe o AssembIy*
En cual)uier caso% una (ez o$tenido un o$jeto Type% a tra(s de sus mtodos FieIdInfo[]
GetFieIds()% MethodInfo[] GetMethods()% ConstructorInfo[] GetConstructors()% EventInfo[]
GetEvents[] + PropertyInfo[] GetProperties() pueden o$tenerse los o$jetos re&le-i(os )ue
representan% de manera respecti(a% a sus campos% mtodos% constructores% e(entos +
propiedades o indizadores* 5anto todos estos o$jetos como los o$jetos Type deri(an de
MemberInfo% por lo )ue pueden ser pasados como parmetros de GetCustomAttributes()
para o$tener los atri$utos de los elementos )ue representan*

Por otro lado% a tra(s de los o$jetos MethodInfo + ConstructorInfo% es posi$le o$tener
los tipos re&le-i(os )ue representan a los parmetros de mtodos + constructores
llamando a su mtodo ParameterInfo[] GetParameters() Admems% en el caso de los
o$jetos MethodInfo tam$in es posi$le o$tener el o$jeto )ue representa al tipo de retorno
del mtodo )ue representan mediante su propiedad Type ReturnType {get;}*
En lo re&erente a las propiedades% es posi$le o$tener los o$jetos MethodInfo )ue
representan a sus $lo)ues get + set a tra(s de los mtodos MethodInfo GetSetMethod() +
MethodInfo GetSetMethod() de los o$jetos PropertyInfo )ue las representan* Adems%
El lenguaje de programacin C# 5ema 1[3 Atri$utos
para o$tener los o$jetos re&le-i(os )ue representen a los .ndices de los indizadores
tam$in se dispone de un mtodo ParamterInfo[] GetIndexParameters()
V en cuanto a los e(entos% los o$jetos EventInfo disponen de mtodos MethodInfo
GetAddMethod() + MethodInfo GetRemoveMethod() mediante los )ue es posi$le o$tener
los o$jetos re&le-i(os )ue representan a sus $lo)ues add + remove*
A continuacin se muestra un programa de ejemplo )ue lo )ue /ace es mostrar por
pantalla el nom$re de todos los atri$utos )ue en l se /a+an de&inido3
using System.Reflection;
using System;
[assembly: EjemploEnsamblado]
[module: EjemploModulo]
[AttributeUsage(AttributeTargets.Method)]
class EjemploMtodo:Attribute
{}
[AttributeUsage(AttributeTargets.Assembly)]
class EjemploEnsamblado:Attribute
{}
[AttributeUsage(AttributeTargets.Module)]
class EjemploModulo:Attribute
{}
[AttributeUsage(AttributeTargets.Class)]
class EjemploTipo:Attribute
{}
[AttributeUsage(AttributeTargets.Field)]
class EjemploCampo:Attribute
{}
[EjemploTipo]
class A
{
public static void Main()
{
Assembly ensamblado = Assembly.GetExecutingAssembly();
foreach (Attribute atributo in Attribute.GetCustomAttributes(ensamblado))
Console.WriteLine("ENSAMBLADO: {0}",atributo);
foreach (Module modulo in ensamblado.GetModules())
{
foreach(Attribute atributo in Attribute.GetCustomAttributes(modulo))
Console.WriteLine("MODULO: {0}", atributo);
foreach (Type tipo in modulo.GetTypes())
{
foreach(Attribute atributo in Attribute.GetCustomAttributes(tipo))
Console.WriteLine("TPO: {0}", atributo);

foreach (Fieldnfo campo in tipo.GetFields())
muestra("CAMPO", campo);
El lenguaje de programacin C# 5ema 1[3 Atri$utos
f oreach (Methodnfo metodo in tipo.GetMethods())
muestra("METODO", metodo);
foreach (Eventnfo evento in tipo.GetEvents())
muestra("EVENTO", evento);
f oreach (Propertynfo propiedad in tipo.GetProperties())
muestra("PROPEDAD", propiedad);
foreach (Constructornfo constructor in tipo.GetConstructors())
muestra("CONSTRUCTOR",constructor);
}
}
}
static private void muestra(string nombre, Membernfo miembro)
{
foreach (Attribute atributo in Attribute.GetCustomAttributes(miembro))
Console.WriteLine("{0}: {1}", nombre, atributo);
}
}
?o ,nico )ue /ace el Main() de este programa es o$tener el AssembIy )ue representa el
ensam$lado actual + mostrar todos sus atri$utos de ensam$lado* ?uego o$tiene todos
los ModuIes )ue representa a los mdulos de dic/o ensam$lado + muestra todos los
atri$utos de mdulo de cada uno* Adems% de cada mdulo se o$tienen todos los Types
)ue representan a los tipos en l de&inidos + se muestran todos sus atri$utosU + de cada
tipo se o$tienen los o$jetos re&le-i(os )ue representan a sus di&erentes tipos de
miem$ros + se muestran los atri$utos atri$utos de cada miem$ro*
Aparte del mtodo Main() en el ejemplo se /an incluido de&iniciones de numerosos
atri$utos de ejemplo aplica$les a di&erentes tipos de elemento + se /an diseminado a lo
largo del &uente (arios usos de estos atri$utos* Por ello% la salida del programa es3
@YS.M1L.9/+ @7em5lo@nsam-lado
@YS.M1L.9/+ System.9iagnostics.9e-ugga-le.ttri-ute
M/9?L/ @7em5loModulo
T;4/+ System..ttri-ute?sage.ttri-ute
T;4/+ System..ttri-ute?sage.ttri-ute
T;4/+ System..ttri-ute?sage.ttri-ute
T;4/+ System..ttri-ute?sage.ttri-ute
T;4/+ System..ttri-ute?sage.ttri-ute
T;4/+ @7em5loTi5o
M@T/9/+ @7em5loMPtodo
4tese )ue aparte de los atri$utos utilizados en el cdigo &uente% la salida del programa
muestra )ue el compilador /a asociado a ni(el de ensam$lado un atri$uto e-tra llamado
DebuggabIe* Este atri$uto inclu+e in&ormacin so$re si pueden aplicarse optimizaciones
al compilar J#5 el ensam$lado o si se /a de realizar una traza de su ejecucin* Sin
em$argo% no con(iene &iarse de su implementacin +a )ue no est documentado por
6icroso&t + puede cam$iar en &uturas (ersiones de la plata&orma *4E5*
El lenguaje de programacin C# 5ema 1[3 Atri$utos
4tributos de compilacin
Aun)ue la ma+or.a de los atri$utos son interpretados en tiempo de ejecucin por el C?>
u otras aplicaciones% /a+ una serie de atri$utos )ue tienen un signi&icado especial en C#
+ condicionan el proceso de compilacin* Estos son los )ue se e-plican a continuacin*
Atributo System.AttributeUsage
Va /emos (isto en este mismo tema )ue se utiliza para indicar dnde se pueden colocar
los nue(os atri$utos )ue el programador de&ina% por lo )ue no se /ar ms incapi en l*
Atributo System.ObsoIete
Se puede usar pre&ijando cual)uier elemento de un &ic/ero de cdigo &uente para indicar
)ue el elemento precedido est o$soleto* Puede tomar dos parmetros sin nom$re3
Kn primer parmetro de tipo string )ue contenga una cadena con un mensaje a
mostrar cuando al compilar se detecte )ue se /a usado el elemento o$soleto*
Kn segundo parmetro de tipo booI )ue indi)ue si se /a de producir un a(iso o
un error cuando se detecte el uso del elemento o$soleto* Por de&ecto se muestra
un a(iso% pero si se le da el (alor true a este parmetro se producir un error*
El siguiente ejemplo muestra como usar este atri$uto3
using System;
class Obsoleta
{
[Obsolete(No usar f(), que est obsoleto., true)]
public static void f()
{}
public static void Main()
{
f();
}
}
Cuando se compile este programa el compilador producir el siguiente mensaje de error3
obsolete.cs(11,17): error CS0619: 'Obsoleta.f()' is obsolete: no usr f(), que est obsoleto.
Si se /u$iese usado ObsoIete sin segundo parmetros% entonces se mostrar.a el a(iso3

obsolete.cs(11,17): warning CS0618: 'Obsoleta.f()' is obsolete: no usr f(), que est obsoleto.
Atributo System.Diagnostics.ConditionaI
El lenguaje de programacin C# 5ema 1[3 Atri$utos
Este atri$uto slo puede pre&ijar de&iniciones de mtodos% + permite de&inir si las
llamadas al mtodo pre&ijado se /an de compilar o no* Puede usarse m,ltiples (eces
pre&ijando a un mismo mtodo + toma un parmetro sin nom$re de tipo string* Slo se
compilarn a)uellas llamadas al mtodo tales )ue en el momento de /acerlas est
de&inida alguna directi(a de preprocesado con el mismo nom$re )ue el parmetro de
alguno de los atri$utos ConditionaI )ue pre&ijen la de&inicin de ese mtodo*
Como se (e% este atri$uto es una $uena &orma de simpli&icar la escritura de cdigo )ue
se de$a compilar condicionalmente% +a )ue e(ita tener (arias directi(as #if )ue encierren
cada llamada al mtodo cu+a ejecucin se desea controlar* Sin em$argo% ConditionaI no
controla la compilacin de ese mtodo% sino slo las llamadas al mismo*
El siguiente ejemplo muestra cmo usar ConditionaI3
using System;
using System.Diagnostics;
class Condicional
{
[Conditional(DEBUG)]
public static void F()
{ Console.WriteLine(Ff()); }
public static void Main()
{
F();
}
}
Slo si compilamos el este cdigo de&iniendo la constante de preprocesado DEBUG se
mostrar por pantalla el mensaje F() En caso contrario% nunca se /ar la llamada a F()
8a+ )ue precisar )ue en realidad ConditionaI no puede preceder a cual)uier de&inicin
de mtodo% sino )ue en su colocacin /a+ impuestas ciertas restricciones especiales3
El mtodo /a de tener un tipo de retorno void* Esto se de$e a )ue si tu(iese otro
se podr.a usar su (alor de retorno como operando en e-presiones% + cuando no
&uesen compiladas sus llamadas esas e-presiones podr.an no tener sentido +
producir errores de compilacin*
Si se aplica a un mtodo (irtual todas sus rede&iniciones lo /eredan% siendo
errneo aplicrselo e-pl.citamente a una de ellas* Esto de$e a )ue en tiempo de
compilacin puede no sa$erse cul es el (erdadero tipo de un o$jeto% + si unas
rede&iniciones pudiesen ser condicionales + otras no% no podr.a determinarse al
compilar si es condicional la (ersin del mtodo a la )ue en cada caso se llame*
4o puede atri$uirse a mtodos de&inidos en inter&aces ni a implementaciones de
mtodos de inter&aces% pues son tam$in (irtuales + podr.an reimplementarse*
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
TEMA 18: Cdigo inseguro
Concepto de cdigo inseguro
C857=. 72;1=04. es todo a)ul &ragmento de cdigo en C# dentro del cual es posi$le
/acer uso de punteros*
Kn <02314. en C# es una (aria$le )ue es capaz de almacenar direcciones de memoria*
Generalmente suele usarse para almacenar direcciones )ue almacenen o$jetos% por lo en
esos casos su signi&icado es similar al de (aria$les normales de tipos re&erencia* Sin
em$argo% los punteros no cuentan con muc/as de las restricciones de stas a la /ora de
acceder al o$jeto* Por ejemplo% al accederse a los elementos de una ta$la mediante un
puntero no se pierde tiempo en compro$ar )ue el .ndice especi&icado se encuentre
dentro de los l.mites de la ta$la% lo )ue permite )ue el acceso se /aga ms rpidamente*
Aparte de su ma+or e&iciencia% tam$in /a+ ciertos casos en )ue es necesario disponer
del cdigo inseguro% como cuando se desea /acer llamadas a &unciones escritas en
lenguajes no gestionados cu+os parmetros tengan )ue ser punteros*
Es importante se1alar )ue los punteros son una e-cepcin en el sistema de tipos de
*4E5% +a )ue no deri(an de la clase primigenia System.Object% por lo )ue no dispondrn
de los mtodos comunes a todos los o$jetos + una (aria$le object no podr almacenarlos
Atampoco e-isten procesos similares al $o-ing + un$o-ing )ue permitan simularloB
Compilacin de cdigos inseguros
El uso de punteros /ace el cdigo ms procli(e a &allos en tanto )ue se salta muc/as de
las medidas incluidas en el acceso normal a o$jetos% por lo )ue es necesario incluir
ciertas medidas de seguridad )ue e(iente la instroduccin accidental de esta inseguridad
?a primera medida tomada consiste en )ue e-pl.citamente /a+ )ue indicar al
compilador )ue deseamos compilar cdigo inseguro* Para ello% al compilador de l.nea
de comandos /emos de pasarle la opcin /unsa+e% como se muestra el ejemplo3
csc cBdigo;nseguro.cs *unsa<e
Si no se indica la opcin unsa<e% cuando el compilador detecte alg,n &uente con cdigo
inseguro producir un mensaje de error como el siguiente3
cdigonseguro(5,23): error CS0277: unsafe code may only appear if compiling with /unsafe
En caso de )ue la compilacin se (a+a a realizar a tra(s de ;isual Studio*4E5% la
&orma de indicar )ue se desea compilar cdigo inseguro es acti(ando la casilla V71D
P4.<143: P9=1; C.2@7=04937.2 P4.<14371; B07-5 A--.D 02;9@1 6.51 C-.6E;
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
Marcacin de cdigos inseguros
Aparte de &orzarse a indicar e-pl.citamente )ue se desea compilar cdigo inseguro% C#
tam$in o$liga a )ue todo uso de cdigo inseguro )ue se /aga en un &ic/ero &uente
tenga )ue ser e-pl.citamente indicado como tal* A las zonas de cdigo donde se usa
cdigo inseguro se les denomina 6.231I3.; 72;1=04.;% + C# o&rece (arios mecanismos
para marcar este tipo de conte-tos*
Kna primera posi$ilidad consiste en preceder un $lo)ue de instrucciones de la pala$ra
reser(ada unsafe siguiendo la siguiente sinta-is3
unsafe <instrucciones>
En el cdigo incluido en <instrucciones> podr de&inirse (aria$les de tipos puntero +
podr /acerse uso de las mismas* Por ejemplo3
public void f()
{
unsafe
{
int *x;
}
}
Ltra &orma de de&inir conte-tos inseguros consiste en a1adir el modi&icador unsafe a la
de&inicin de un miem$ro% caso en )ue dentro de su de&inicin se podr /acer uso de
punteros* As. es posi$le de&inir campos de tipo puntero% mtodos con parmetros de
tipos puntero% etc* El siguiente ejemplo muestra cmo de&inir dos campos de tipo
puntero* 4tese sin em$argo )ue no es posi$le de&inir los dos en una misma l.nea3
struct Puntonseguro
{
public unsafe int *X; // No es vlido hacer public unsafe int *X, Y;
public unsafe int *Y; // Tampoco lo es hacer public unsafe int *X, *Y;
}
L$(iamente% en un mtodo )ue inclu+a el modi&icador unsafe no es necesario preceder
con dic/a pala$ra sus $lo)ues de instrucciones inseguros*
8a+ )ue tener en cuenta )ue el a1adido de modi&icadores unsa&e es completamente
inocuo* Es decir% no in&lu+e para nada en cmo se /a+a de rede&inir + si un mtodo
Main() lo tiene sigue siendo un punto de entrada (lido*

Kna tercera &orma consiste en a1adir el modi&icador unsafe en el de&inicin de un tipo%
caso en )ue todas las de&iniciones de miem$ros del mismo podrn incluir cdigo
inseguro sin necesidad de a1adir a cada una el modi&icador unsafe o preceder sus
$lo)ues de instrucciones inseguras de la pala$ra reser(ada unsafe* Por ejemplo3
unsafe struct Puntonseguro
{
public int * X, *Y;
}
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
)efinicin de punteros
Para de&inir una (aria$le puntero de un determinado tipo se sigue una sinta-is parecida a
la usada para de&inir (aria$les normales slo )ue al nom$re del tipo se le postpone un
s.m$olo de asterisco A*B L sea% un puntero se de&ine as.3
<tipo> * <nombrePuntero>;
Por ejemplo% una (aria$le puntero llamada a )ue pueda almacenar re&erencias a
posiciones de memoria donde se almacenen o$jetos de tipo int se declara as.3
int * a;
En caso de )uererse declarar una ta$la de punteros% entonces el asterisco /a+ )ue
incluirlo tras el nom$re del tipo pero antes de los corc/etes* Por ejemplo% una ta$la de
nom$re t )ue pueda almacenar punteros a o$jetos de tipo int se declara as.3
int*[] t;
8a+ un tipo especial de puntero )ue es capaz de almacenar re&erencias a o$jetos de
cual)uier tipo* <stos punteros de declara indicando void como <tipo>* Por ejemplo3
void * punteroACualquierCosa;
8a+ )ue tener en cuenta )ue en realidad lo )ue indica el tipo )ue se d a un puntero es
cul es el tipo de o$jetos )ue se /a de considerar )ue se almacenan en la direccin de
memoria almacenada por el puntero* Si se le da el (alor void lo )ue se est diciendo es
)ue no se desea )ue se considere )ue el puntero apunta a ning,n tipo espec.&ico de
o$jeto* Es decir% no se est dando in&ormacin so$re el tipo apuntado*
Se pueden declarar m,ltiples (aria$les locales de tipo puntero en una misma l.nea* En
ese caso el asterisco slo /a+ )ue incluirlo antes del nom$re de la primera* Por ejemplo3
int * a, b; // a y b son de tipo int * No sera vlido haberlas definido como int *a, *b;
8a+ )ue tener en cuenta )ue esta sinta-is especial para de&inir en una misma de&inicin
(arios punteros de un mismo tipo slo es (lida en de&iniciones de (aria$les locales* Al
de&inir campos no sir(e + /a+ )ue dar para cada campo una de&inicin independiente*
El recolector de $asura no tiene en cuenta los datos a los )ue se re&erencie con punteros%
pues /a de conocer cul es el o$jeto al re&erenciado por cada (aria$le + un puntero en
realidad no tiene por)u almacenar re&erencias a o$jetos de ning,n tipo en concreto* Por
ejemplo% pueden tenerse punteros int * )ue en realidad apunten a o$jeto char% o punteros
void * )ue no almacenen in&ormacin so$re el tipo de o$jeto al )ue de$er.a considerarse
)ue apuntan% o punteros )ue apunte a direcciones donde no /a+an o$jetos% etc*
Como el recolector de $asura no tra$aja con punteros% no es posi$le de&inir punteros de
tipos )ue se almacenen en memoria dinmica o contengan miem$ros )ue se almacenen
en memoria dinmica% +a )ue entonces podr.a ocurrir )ue un o$jeto slo re&erenciado a
tra(s de punteros sea destruido por considear el recolector )ue nadie le re&erencia$a*
Por ello% slo es (lido de&inir punteros de tipos cu+os o$jetos se puedan almacenar
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
completamente en pila% pues la (ida de estos o$jetos no est controlada por el recolector
de $asura sino )ue se destru+en cuando se a$andona el m$ito donde &ueron de&inidos*
En concreto% los ,nicos punteros (lidos son a)uellos cu+o tipos sean tipos (alor
$sicos% enumeraciones o estructuras )ue no contengan campos de tipos re&erencias*
5am$in pueden de&inirse punteros de tipos puntero% como muestra este ejemplo de
declaracin de un puntero a puntero de tipo int llamando punteroApuntero3
int ** punteroApuntero;
L$(iamente la anidacin puede /acerse a cual)uier ni(el de pro&undidad% pudindose
de&inir punteros a punteros a punteros% o punteros a punteros a punteros a punteros% etc*
Manipulacin de punteros
Obtencin de direccin de memoria. Operador &
Para almacenar una re&erencia a un o$jeto en un puntero se puede aplicar al o$jeto el
operador pre&ijo &% )ue lo )ue /ace es de(uel(er la direccin )ue en memoria ocupa el
o$jeto so$re el )ue se aplica* Kn ejemplo de su uso para inicializar un puntero es3
int x =10;
int * px = &x;
Este operador no es aplica$le a e-presiones constantes% pues stas no se almacenan en
ninguna direccin de memoria espec.&ica sino )ue se incrustan en las instrucciones* Por
ello% no es (lido /acer directamente3
int px = &10; // Error 10 no es una variable con direccin propia
5ampoco es (lido aplicar & a campos readonIy% pues si estos pudiesen ser apuntados
por punteros se correr.a el riesgo de poderlos modi&icar +a )ue a tra(s de un puntero se
accede a memoria directamente% sin tenerse en cuenta si en la posicin accedida /a+
alg,n o$jeto% por lo )ue muc/o menos se considerar si ste es de slo lectura*
?o )ue es s. (lido almacenar en un puntero es la direccin de memoria apuntada por
otro puntero* En ese caso am$os punteros apuntar.an al mismo o$jeto + las
modi&icaciones a ste realizadas a tra(s de un puntero tam$in a&ectar.an al o$jeto
(isto por el otro% de &orma similar a como ocurre con las (aria$les normales de tipos
re&erencia* Es ms% los operadores relacionales t.picos A==% !=% <% >% <= + >=B se /an
rede&inido para )ue cuando se apli)uen entre dos punteros de cuales)uiera dos tipos lo
)ue se compare sean las direcciones de memoria )ue estos almacenan* Por ejemplo3
int x = 10;
int px = &x;
int px2 = px; // px y px2 apuntan al objeto almacenado en x
Console.WriteLine( px == px2); // mprime por pantalla True
En realidad las (aria$les so$re las )ue se apli)ue & no tienen por)u estar inicializadas*
Por ejemplo% es (lido /acer3
private void f()
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
{
int x;
unsafe
{ int px = &x;}
}
Esto se de$e a )ue uno de los principales usos de los punteros en C# es poderlos pasar
como parmetros de &unciones no gestionadas )ue esperen reci$ir punteros* Como
muc/as de esas &unciones /an sido programadas para inicializar los contenidos de los
punteros )ue se les pasan% pasarles punteros inicializados implicar.a perder tiempo
innecesariamente en inicializarlos*
Acceso a contenido de puntero. Operador *
Kn puntero no almacena directamente un o$jeto sino )ue suele almacenar la direccin
de memoria de un o$jeto Ao sea% apunta a un o$jetoB Para o$tener a partir de un puntero
el o$jeto al )ue apunta /a+ )ue aplicarle al mismo el operador pre&ijo *% )ue de(uel(e el
o$jeto apuntado* Por ejemplo% el siguiente cdigo imprime en pantalla un 123
int x = 10;
int * px= &x;
Console.WriteLine(*px);
Es posi$le en un puntero almacenar nuII para indicar )ue no apunta a ninguna direccin
(lida* Sin em$argo% si luego se intenta acceder al contenido del mismo a tra(s del
operador * se producir generalmente una e-cepcin de tipo 4ull>e&erenceE-ception
Aaun)ue realmente esto depende de la implementacin del lenguajeB Por ejemplo3
int * px = null;
Console.WriteLine(*px); // Produce una NullReferenceException
4o tiene sentido aplicar * a un puntero de tipo void * +a )ue estos punteros no
almacenan in&ormacin so$re el tipo de o$jetos a los )ue apuntan + por tanto no es
posi$le recurperarlos a tra(s de los mismos +a )ue no se sa$e cuanto espacio en
memoria a partir de la direccin almacenada en el puntero ocupa el o$jeto apuntado +%
por tanto% no se sa$e cuanta memoria /a+ )ue leer para o$tenerlo*
Acceso a miembro de contenido de puntero. Operador ->
Si un puntero apunta a un o$jeto estructura )ue tiene un mtodo F() ser.a posi$le
llamarlo a tra(s del puntero con3
(*objeto).F();
Sin em$argo% como llamar a o$jetos apuntados por punteros es algo $astante /a$itual%
para &acilitar la sinta-is con la )ue /acer esto se /a incluido en C# el operador ->% con el
)ue la instruccin anterior se escri$ir.a as.3
objeto->f();
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
Es decir% del mismo modo )ue el operador . permite acceder a los miem$ros de un
o$jeto re&erenciado por una (aria$le normal% -> permite acceder a los miem$ros de un
o$jeto re&erenciado por un puntero* En general% un acceso de la &orma O -> M es
e)ui(alente a /acer (*O).M. Por tanto% al igual )ue es incorrecto aplicar * so$re punteros
de tipo void *% tam$in lo es aplicar ->
Conversiones de punteros
Ce todo lo (isto /asta a/ora parece )ue no tiene muc/o sentido el uso de punteros de
tipo void * Pues $ien% una utilidad de este tipo de punteros es )ue pueden usarse como
almacn de punteros de cual)uier otro tipo )ue luego podrn ser recuperados a su tipo
original usando el operador de con(ersin e-pl.cita* Es decir% igual )ue los o$jetos de
tipo object pueden almacenar impl.citamente o$jetos de cual)uier tipo% los punteros void
* pueden almacenar punteros de cual)uier tipo + son ,tiles para la escritura de mtodos
)ue puedan aceptar parmetros de cual)uier tipo de puntero*
A di&erencia de lo )ue ocurre entre (aria$les normales% las con(ersiones entre punteros
siempre se permiten% al realizarlas nunca no se comprue$a si son (lidas* Por ejemplo%
el siguiente cdigo es (lido3
char c = 'A';
char* pc = &c;
void* pv = pc;
int* pi = (int*)pv;
int i = *pi; // Almacena en 16 bits del char de pv + otros 16 indeterminados
Console.WriteLine(i);
*pi = 123456; // Machaca los 32 bits apuntados por pi
En este cdigo pi es un puntero a un o$jeto de tipo int A! $itsB% pero en realidad el
o$jeto al )ue apunta es de tipo char A1T $itsB% )ue es ms pe)ue1o* El (alor )ue se
almacene en i es en principio inde&inido% pues depende de lo )ue /u$iese en los 1T $its
e-tras resultantes de tratar pv como puntero a int cuando en realidad apunta$a a un char*

Cel mismo modo% con(ersiones entre punteros pueden terminar produciendo )ue un
puntero apunte a un o$jeto de ma+or tama1o )ue los o$jetos del tipo del puntero* En
estos casos% el puntero apuntar.a a los $its menos signi&icati(os del o$jeto apuntado*

5am$in es posi$le realizar con(ersiones entre punteros + tipos $sicos enteros* ?a
con(ersin de un puntero en un tipo entero de(uel(e la direccin de memoria apuntada
por el mismo* Por ejemplo% el siguiente cdigo muestra por pantalla la direccin de
memoria apuntada por px3
int x = 10;
int *px = &10;
Console.WriteLine((int) px);
Por su parte% con(ertir cual)uier (alor entero en un puntero tiene el e&ecto de de(ol(er
un puntero )ue apunte a la direccin de memoria indicada por ese n,mero* Por
ejemplo% el siguiente cdigo /ace )ue px apunte a la direccin 12: + luego imprime
por pantalla la direccin de memoria apuntada por px A)ue ser 12:B3
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
int *px = (int *) 10;
Console.WriteLine((int) px);
4tese )ue aun)ue en un principio es posi$le /acer )ue un puntero almacene cual)uier
direccin de memoria% si dic/a direccin no pertenece al mismo proceso )ue el cdigo
en )ue se use el puntero se producir un error al leer el contenido de dic/a direccin* El
tipo de error /a producir no se indica en principio en la especi&ricacin del lenguaje%
pero la implementacin de 6icroso&t lanza una re&erencia NuIIReferenceException* Por
ejemplo% el siguiente cdigo produce una e-cepcin de dic/o tipo al ejecturase3
using System;
class Accesonvlido
{
public unsafe static void Main()
{
int * px = (int *) 100;
Console.Write(*px); // Se lanza NullReferenceException
}
}
Aritmtica de punteros
?os punteros se suelen usar para recorrer ta$las de elementos sin necesidad de tener )ue
compro$arse )ue el .ndice al )ue se accede en cada momento se encuentra dentro de los
l.mites de la ta$la* Por ello% los operadores aritmticos de&inidos para los punteros estn
orientados a &acilitar este tipo de recorridos*
8a+ )ue tener en cuenta )ue todos los operadores aritmticos aplica$les a punteros
dependen del tama1o del tipo de dato apuntado% por lo )ue no son aplica$les a punteros
void * +a )ue estos no almacenan in&ormacin so$re dic/o tipo* Esos operadores son3
++ + --3 El operador ++ no suma uno a la direccin almacenada en un puntero%
sino )ue le suma el tama1o del tipo de dato al )ue apunta* As.% si el puntero
apunta$a a un elemento de una ta$la pasar a apuntar al siguiente Alos elementos
de las ta$las se almacenan en memoria consecuti(amenteB Cel mismo modo% --
resta a la direccin almacenada en el puntero el tama1o de su tipo de dato* Por
ejemplo% una ta$la de 122 elementos a cu+o primer elemento inicialmente
apuntase pt podr.a recorrerse as.3
for (int i=0; i<100; i++)
Console.WriteLine(Elemento{0}={1}, i, (*p)++);
El pro$lema )ue puede plantear en ciertos casos el uso de ++ + -- es )ue /acen
)ue al &inal del recorrido el puntero deje de apuntar al primer elemento de la
ta$la* Ello podr.a solucionarse almacenando su direccin en otro puntero antes
de iniciar el recorrido + restaurndola a partir de l tras &inalizarlo*
+ + -3 Permiten solucionar el pro$lema de ++ + -- antes comentado de una &orma
ms cmoda $asada en sumar o restar un cierto entero a los punteros* + de(uel(e
la direccin resultante de sumar a la direccin almacenada en el puntero so$re el
)ue se aplica el tama1o del tipo de dic/o puntero tantas (eces como indi)ue el
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
entero sumado* - tiene el mismo signi&icado pero restando dic/a cantidad en (ez
de sumarla* Por ejemplo% usando + el $ucle anterior podr.a reescri$rise as.3
for (int i=0; i<100; i++)
Console.WriteLine(Elemento{0}={1}, i, *(p+i));
El operador - tam$in puede aplicarse entre dos punteros de un mismo tipo% caso
en )ue de(uel(e un Iong )ue indica cuntos elementos del tipo del puntero
pueden almacenarse entre las direcciones de los punteros indicados*
[]3 Cado )ue es &recuente usar + para acceder a elementos de ta$las% tam$in se
/a rede&inido el operador [] para )ue cuando se apli)ue a una ta$la /aga lo
mismo + de(uel(a el o$jeto contenido en la direccin resultante* L sea *(p+i) es
e)ui(alente a p[i]% con lo )ue el cdigo anterior e)ui(ale a3
for (int i=0; i<100; i++)
Console.WriteLine(Elemento{0}={1}, i, p[i]);
4o /a+ )ue con&undir el acceso a los elementos de una ta$la aplicando [] so$re
una (aria$le de tipo ta$la normal con el acceso a tra(s de un puntero )ue apunte
a su primer elemento* En el segundo caso no se comprue$a si el .ndice indicado
se encuentra dentro del rango de la ta$la% con lo )ue el acceso es ms rpido pero
tam$in ms procli(e a errores di&.ciles de detectar*
Winalmente% respecto a la aritmtica de punteros% /a+ )ue tener en cuenta )ue por
e&iciencia% en las operaciones con punteros nunca se comprue$a si se producen
des$ordamientos% + en caso de producirse se truncan los resultados sin a(isarse de ello
mediante e-cepciones* Por eso /a+ )ue tener especial cuidado al operar con punteros no
sea )ue un des$ordamiento no detectado cause errores de causas di&.ciles de encontrar*
&peradores relacionados con cdigo inseguro
Operador sizeof. Obtencin de tamao de tipo
El operador unario + pre&ijo sizeof de(uel(e un o$jeto int con el tama1o en $+tes del
tipo de dato so$re el )ue se aplica* Slo puede aplicarse en conte-tos inseguros + slo a
tipos de datos para los )ue sea posi$le de&inir punteros% siendo su sinta-is de uso3
sizeof(<tipo>)
Cuando se aplica a tipos de datos $sicos su resultado es siempre constante* Por ello% el
compilador optimiza dic/os usos de sizeof sustitu+ndolos internamente por su (alor
AinliningB + considerando )ue el uso del operador es una e-presin constante* Estas
constantes correspondientes a los tipos $sicos son las indicadas en la 5a$la 123
T7<.; R1;0-395.
sbyte, byte, bool 1
short, ushort, char 2
int, uint, float 4
long, ulong, double 8
Tabla ABC >esultados de si1eo+ 5ara ti5os -0sicos
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
Para el resto de tipos a los )ue se les puede aplicar% sizeof no tiene por)u de(uel(er un
resultado constante sino )ue los compiladores pueden alinear en memoria las estructuras
inclu+endo $its de relleno cu+o n,mero + (alores sean en principio indeterminado* Sin
em$argo% el (alor de(uelto por sizeof siempre de(ol(er el tama1o en memoria e-acto
del tipo de dato so$re el )ue se apli)ue% inclu+endo $its de relleno si los tu(iese*
4tese )ue es &cil implementar los operadores de aritmtica de punteros usando sizeof*
Para ello% ++ se de&inir.a como a1adir a la direccin almacenada en el puntero el
resultado de aplicar sizeof a su tipo de dato% + -- consistir.a en restarle dic/o (alor* Por
su parte% el operador + usado de la &orma P + N AP es un puntero de tipo T + N un enteroB
lo )ue de(uel(e es el resultado de a1adir al puntero sizeof(T)*N% + P N de(uel(e el
resultado de restarle sizeof(T)*N* Por ,ltimo% si se usa - para restar dos punteros P1 + P2
de tipo T% ello es e)ui(alente a calcular A((long)P1) - ((long)P2)))/sizeof(T)
Operador stackaIIoc. Creacin de tabIas en piIa.
Cuando se tra$aja con punteros puede resultar interesante reser(ar una zona de memoria
en la pila donde posteriormente se puedan ir almacenando o$jetos* Precisamente para
eso est el operador stackaIIoc% )ue se usa siguindose la siguiente sinta-is3
stackaIIoc <tipo>[<nmero>]
stackaIIoc reser(a en pila el espacio necesario para almacenar contiguamente el n,mero
de o$jetos de tipo <tipo> indicado en <nmero> Areser(a sizeof(<tipo>)*<nmero> $+tesB +
de(uel(e un puntero a la direccin de inicio de ese espacio* Si no )uedase memoria li$re
su&iciente para reser(arlo se producir.a una e-cepcin System.StackOverfIowException.
stackaIIoc slo puede usarse para inicializar punteros declarados como (aria$les locales
+ slo en el momento de su declaracin** Por ejemplo% un puntero pt )ue apuntase al
principio de una regin con capacidad para 122 o$jetos de tipo int se declarar.a con3
int * pt = stackalloc int[100];
Sin em$argo% no ser.a (lido /acer3
int * pt;
pt = stackalloc int[100]; // ERROR: Slo puede usarse stackalloc en declaraciones
Aun)ue pueda parecer )ue stacIalloc se usa como sustituto de new para crear ta$las en
pila en lugar de en memoria dinmica% no /a+ )ue con&undirse3 stackaIIoc slo reser(a
un espacio contiguo en pila para o$jetos de un cierto tipo% pero ello no signi&ica )ue se
cree una ta$la en pila* ?as ta$las son o$jetos )ue /eredan de System.Array + cuentan
con los miem$ros /eredados de esta clase + de object% pero regiones de memoria en pila
reser(adas por stackaIIoc no* Por ejemplo% el siguiente cdigo es in(lido*
int[] tabla;
int * pt = stackalloc int[100];
tabla = *pt; // ERROR: El contenido de pt es un int, no una tabla (int[])
Console.WriteLine(pt->Length); // ERROR: pt no apunta a una tabla
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
Sin em$argo% gracias a )ue como +a se /a comentado en este tema el operador [] est
rede&inido para tra$ajar con punteros% podemos usarlo para acceder a los di&erentes
o$jetos almacenados en las regiones reser(adas con stackaIIoc como si &uesen ta$las*
Por ejemplo% este cdigo guarda en pila los 122 primeros enteros + luego los imprime3
class Stackalloc
{
public unsafe static void Main()
{
int * pt = stackalloc int[100];
for (int i=0; i<100; i++)
pt[i] = i;
for(int i=0; i<100; i++)
System.Console.WriteLine(pt[i]);
}
}
4tese )ue% a di&erencia de lo )ue ocurrir.a si pt &uese una ta$la% en los accesos con pt[i]
no se comprue$a )ue i no supere el n,mero de o$jetos para los )ue se /a reser(ado
memoria* Como contrapartida% se tiene el incon(eniente de )ue al no ser pt una ta$la no
cuenta con los mtodos t.picos de stas + no puede usarse foreach para recorrerla*
Ltra (entaja de la simulacin de ta$las con stackaIIoc es )ue se reser(a la memoria
muc/o ms rpido )ue el tiempo )ue se tardar.a en crear una ta$la* Esto se de$e a )ue
reser(ar la memoria necesaria en pila tan sencillo como incrementar el puntero de pila
en la cantidad correspondiente al tama1o a reser(ar% + no /a+ )ue perder tiempo en
solicitar memoria dinmica* Adems% stackaIIoc no pierde tiempo en inicializar con
alg,n (alor el contenido de la memoria% por lo )ue la Nta$laO se crea antes pero a costa
de )ue luego sea ms inseguro usarla +a )ue /a+ )ue tener cuidado con no leer trozos de
ella antes de asignarles (alores (lidos*
8i'acin de variables apuntadas
Aun)ue un puntero slo puede apuntar a datos de tipos )ue puedan almacenarse
completamente en pila Ao sea% )ue no sean ni o$jetos de tipos re&erencia ni estructuras
con miem$ros de tipos re&erenciaB% nada garantiza )ue los o$jetos apuntado en cada
momento estn almacenados en pila* Por ejemplo% las (aria$les estticas de tipo int o los
elementos de una ta$la de tipo int se almacenan en memoria dinmica a,n cuando son
o$jetos a los )ue se les puede apuntar con punteros*
Si un puntero almacena la direccin de un o$jeto almacenado en memoria dinmica + el
recolector de $asura cam$ia al o$jeto de posicin tras una compactacin de memoria
resultante de una recoleccin% el (alor almacenado en el puntero dejar de ser (lido*
Para e(itar )ue esto ocurra se puede usar la instruccin fixed% cu+a sinta-is de uso es3
fixed(<tipo> <declaraciones>)
<instrucciones>
El signi&icado de esta instruccin es el siguiente3 se asegura )ue durante la ejecucin del
$lo)ue de <instrucciones> indicado el recolector de $asura nunca cam$ie la direccin de
ninguno de los o$jetos apuntados por los punteros de tipo <tipo> declarados* Estas
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
<declaraciones> siempre /an de incluir una especi&icacin de (alor inicial para cada
puntero declarado% + si se declaran (arios se /an de separar con comas*
?os punteros declarados en <declaraciones> slo e-istirn dentro de <instrucciones>% + al
salir de dic/o $lo)ue se destruirn* Adems% si se les indica como (alor inicial una ta$la
o cadena )ue (alga nuII saltar una NuIIReferenceException* 5am$in /a+ )ue se1alar
)ue aun)ue slo pueden declarase punteros de un mismo tipo en cada fixed% se puede
simular &acilmente la declaracin de punteros de distintos tipos anidando (arios fixed*
Por otro lado% los punteros declarados en <declaraciones> son de slo lectura% +a )ue si
no podr.a cam$irseles su (alor por el de una direccin de memoria no &ijada + conducir
ello a errores di&.ciles de detectar*

Kn uso &recuente de fixed consiste en apuntar a o$jetos de tipos para los )ue se puedan
declarar punteros pero )ue estn almacenados en ta$las% +a )ue ello no se puede /acer
directamente de$ido a )ue las ta$las se almacenan en memoria dinmica* Por ejemplo%
copiar usando punteros una ta$la de 122 elementos de tipo int en otra se /ar.a as.3
class Copiansegura
{
public unsafe static void Main()
{
int[] tOrigen = new int[100];
int[] tDestino = new int[100];
fixed (int * pOrigen=tOrigen, pDestino=tDestino)
{
for (int i=0; i<100; i++)
pOrigen[i] = pDestino[i];
}
}
}
Como puede deducirse del ejemplo% cuando se inicializa un puntero con una ta$la% la
direccin almacenada en el puntero en la zona <declaraciones> del fixed es la del primer
elemento de la ta$la Atam$in podr.a /a$erse /ec/o pOrigen = &tOrigen[0]B% + luego es
posi$le usar la aritmtica de punteros para acceder al resto de elementos a partir de la
direccin del primero +a )ue stos se almacenan consecuti(amente*
Al igual )ue ta$las% tam$in puede usarse fixed para recorrer cadenas* En este caso lo
)ue /a+ )ue /acer es inicializar un puntero de tipo char * con la direccin del primer
carcter de la cadena a la )ue se desee )ue apunte tal + como muestra este ejemplo en el
)ue se cam$ia el contenido de una cadena Hola por XXXX3
class Cadenansegura
{
public unsafe static void Main()
{
string s=Hola;
Console.WriteLine(Cadena inicial: {0}, s);
fixed (char * ps=s)
{
for (int i=0;i<s.Length;i++)
ps[i] = 'A';
El lenguaje de programacin C# 5ema 1R3 Cdigo inseguro
}
Console.WriteLine(Cadena final: {0}, s);
}
}
?a salida por pantalla de este ,ltimo programa es3
Hola
....
?a (entaja de modi&icar la cadena mediante punteros es sin ellos no ser.a posi$le
/acerlo +a )ue el indizador de&inido para los o$jetos string es de slo lectura*
Cuando se modi&i)uen cadenas mediante punteros /a+ )ue tener en cuenta )ue% aun)ue
para &acilitar la comunicacin con cdigo no gestionado escrito en C o C'' las cadenas
en C# tam$in aca$an en el carcter '\0'% no se recomienda con&iar en ello al recorrerlas
con punteros por)ue '\0' tam$in puede usarse como carcter de la cadena* Por ello% es
mejor /acer como en el ejemplo + detectar su &inal a tra(s de su propiedad Length*
8a+ )ue se1alar )ue como &i-ed pro(oca )ue no pueda cam$iarse de direccin a ciertos
o$jetos almacenados en memoria dinmica% ello puede producir la generacin de /uecos
en memoria dinmica% lo )ue tiene dos e&ectos mu+ negati(os3
El recolector de $asura est optimizado para tra$ajar con memoria compactada%
pues si todos los o$jetos se almacenan consecuti(amente en memoria dinmica
crear uno nue(o es tan sencillo como a1adirlo tras el ,ltimo* Sin em$argo% fixed
rompe esta consecuti(idad + la creacin de o$jetos en memoria dinmica dentro
de este tipo de instrucciones es ms lenta por)ue /a+ )ue $uscar /uecos li$res*
Por de&ecto% al eliminarse o$jetos de memoria durante una recoleccin de $asura
se compacta la memoria )ue )ueda ocupada para )ue todos los o$jetos se
almacenen en memoria dinmica* 8acer esto dentro de sentencias fixed es ms
lento por)ue /a+ )ue tener en cuenta si cada o$jeto se puede o no mo(er*
Por estas razones es con(eniente )ue el contenido del $lo)ue de instrucciones de una
sentencia fixed sea el m.nimo posi$le% para )ue as. el fixed se ejecute lo antes posi$le*
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
Tema 19: Documentacin XML
Concepto % utilidad de la documentacin 9ML
?a documentacin de los tipos de datos creados siempre /a sido una de las tareas ms
pesadas + a$urridas a las )ue un programador se /a tenido )ue en&rentar durante un
pro+ecto% lo )ue /a /ec/o )ue muc/as (eces se escri$a de manera descuidada + poco
concisa o )ue incluso )ue no se escri$a en a$soluto* Sin em$argo% escri$irla es una tarea
mu+ importante so$re todo en un en&o)ue de programacin orientada a componentes en
tanto )ue los componentes desarrollados muc/as (eces (an a reutilizados por otros* E
incluso para el propio creador del componente puede resultar de inestima$le a+uda si en
el &uturo tiene )ue modi&icarlo o usarlo + no recuerda e-ctamente cmo lo implement*
Para &acilitar la pesada tarea de escri$ir la documentacin% el compilador de C# es capaz
de generarla automticamente a partir de los comentarios )ue el progamador escri$a en
los &ic/eros de cdigo &uente*
El /ec/o de )ue la documentacin se genere a partir de los &uentes permite e(itar )ue se
tenga )ue tra$ajar con dos tipos de documentos por separado A&uentes + documentacinB
)ue de$an actualizarse simultneamente para e(itar incosistencias entre ellos deri(adas
de )ue e(olucionen de manera separada +a sea por pereza o por error*
El compilador genera la documentacin en S6? con la idea de )ue sea &cilmente
legi$le para cual)uier aplicacin* Para &acilitar su legi$ilidad a /umanos $astar.a
a1aderle una /oja de estilo SS? o usar alguna aplicacin espec.&ica encargada de leerla
+ mostrarla de una &orma ms cmoda para /umanos*
Aun)ue e-plicar S6? + SS? )ueda &uera del alcance del li$ro% en este tema se
resumirn $re(emente tanto S6? como la &orma de aplicar /ojas SS? a &ic/eros S6?*
!ntroduccin a 9ML
Antes de continuar es necesario /acer una pe)ue1a introduccin a S6? +a )ue )ue es
el lenguaje en )ue se /an de escri$ir los comentarios especiales de documentacin* Si +a
conoce este lenguaje puede saltarse este ep.gra&e*
(ML AE-tensi$le 6arIup ?anguageB es un ?139-12=09>1 51 137/0139;% lo )ue signi&ica
)ue es un lenguaje )ue se utiliza para de&inir lenguajes de eti)uetas* A cada lenguaje
creado con S6? se le denomina A.69C0-947. (ML% + la documentacin generada por
el compilador de C# est escrita en un (oca$ulario de este tipo*
?os comentarios a partir de los )ue el compilador generar la documentacin /an de
escri$irse en S6?% por lo )ue /an de respetar las siguientes reglas comunes a todo
documento S6? $ien &ormado3

1* ?a in&ormacin /a de incluirse dentro de 137/0139;% )ue son estructuras de la &orma3
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
<<etiqueta>> <contenido> </<etiqueta>
En <etiqueta> se indica cul es el nom$re de la eti)ueta a usar* Por ejemplo3
<EtiquetaEjemplo> Esto es una etiqueta de ejemplo </EtiquetaEjemplo>
Como <contenido> de una eti)ueta puede incluirse tanto te-to plano Aes el caso del
ejemploB como otras eti)uetas* ?o )ue es importante es )ue toda eti)ueta cu+o uso
comience dentro de otra tam$in /a de terminar dentro de ella* L sea% no es (lido3
<Etiqueta1> <Etiqueta2> </Etiqueta1></Eetiqueta2>
Pero lo )ue s. ser.a (lido es3
<Etiqueta1> <Etiqueta2> </Etiqueta2></Etiqueta1>
5am$in es posi$le mezclar te-to + otras eti)uetas en <contenido>* Por ejemplo3
<Etiqueta1> Hola <Etiqueta2> a </Etiqueta2> todos </Etiqueta1>
* S6? es un lenguaje sensi$le a ma+,sculas% por lo )ue si una eti)ueta se a$re con
una cierta capitalizacin% a la /ora de cerrarla /a$r )ue usar e-actamente la misma*
!* Es posi$le usar la siguiente sinta-is a$re(iada para escri$ir eti)uetas sin <contenido>3
<<etiqueta>/>
Por ejemplo3
<<EtiquetaSinContenidoDeEjemplo>/>
"* En realidad en la <etiqueta> inicial no tiene por)u indicarse slo un identi&icador
)ue sir(a de nom$re para la eti)ueta usada% sino )ue tam$in pueden indicarse
9347C03.; )ue permitan con&igurar su signi&icado* Estos atri$utos se escri$en de la
&orma <nombreAtributo> = "<valor>" + separados mediante espacios* Por ejemplo3
<EtiquetaConAtributo AtributoEjemplo=valor1 >
Etiqueta de ejemplo que incluye un atributo
</EtiquetaConAtributo>
<EtiquetaSinContenidoYConAtributo AtributoEjemplo=valor2 />
Q* Slo puede utilizarse caracteres ASC##% + los caracteres no ASC## Aacentos% e1es% ***B
o caracteres con alg,n signi&icado especial en S6? /an de ser sustituidos por
secuencias de escape de la &orma &#<cdigoUnicode>; Para los caracteres ms
/a$ituales tam$in se /an de&inido las siguientes secuencias de escape especiales3
C94M6314 S16012679 51 1;69<1 U276.51 S16012679 51 1;69<1 1;<1679-
< &#60; &lt;
> &#62; &gt;
& &#38; &amp;
' &#39; &apos;
&#34; &quot;
T9C-9 11: Secuencias de espace S6? de uso &recuente
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
Comentarios de documentacin 9ML
Sintaxis generaI
?os comentarios de documentacin S6? se escri$en como comentarios normales de
una l.nea pero con las peculiaridades de )ue su primer carcter /a de ser siempre / + de
)ue su contenido /a de estar escrito en S6? +a )ue ser insertado por el compilador en
el &ic/ero S6? de documentacin )ue genera* Por tanto% son comentarios de la &orma3
/// <textoXML>
Estos comentarios /an preceder las de&iniciones de los elementos a documentar* Estos
elementos slo pueden ser de&iniciones de miem$ros% +a sean tipos de datos A)ue son
miem$ros de espacios de nom$resB o miem$ros de tipos datos% + /an de colocarse
incluso incluso antes )ue sus atri$utos*
En <textoXML> el programador puede incluir cuales)uiera eti)uetas con el signi&icado%
contenido + atri$utos )ue considere oportunos% +a )ue en principio el compilador no las
procesa sino )ue las inclu+e tal cual en la documentacin )ue genera dejndo en manos
de las /erramientas encargadas de procesar dic/a documentacin la determinacin de si
se /an usado correctamente*
Sin em$argo% el compilador comprue$a )ue los comentarios de documentacin se
colo)uen donde de$er.an + )ue contegan S6? $ien &ormado* Si no &uese as. generar.a
un mensaje de a(iso + en la documentacin generada los sustituir.a por un comentario
S6? )ue e-plicase el tipo de error cometido*
EI atributo cref
Aun)ue en principio los atri$utos de las eti)uetas no tienen ning,n signi&icado
predeterminado para el compilador% /a+ una e-cepcin3 el atri$uto cref siempre (a a
tener un signi&icado concreto consistente en &orzarlo a compro$ar cuando (a+a a generar
la documentacin si e-iste el elemento cu+o nom$re indi)ue +% si no es as.% /acerle
producir un mensaje de a(iso Asu nom$re (iene de Nc/ecI re&erenceOB
?os elementos especi&icados en cref suelen indicarse mediante cali&icacin completa% +
pueden ser tanto nom$res de miem$ros como de espacios de nom$res* En el Tema 2:
Espa$ios de Nomres +a se e-plic como indicar as. nom$res de tipos + de espacios de
nom$res% mientras )ue para indicar el de miem$ros de tipos $asta escri$ir el nom$re
completo del tipo donde estn de&inidos seguido de un punto tras el cual% dependiendo
del tipo de miem$ro del )ue se trate% se escri$ir.a 3
Si es un 69?<.% <4.<71595P 1A123. o 37<. interno% su nom$re*
Si es un ?N3.5.% su nom$re seguido de los nom$res completos de los tipos de sus
parmetros separados mediante comas + entre parntesis* Estos nom$res de tipos de
parmetros lle(an un carcter @ concatendo al &inal en los parmetros ref u out% un
carcter * al &inal en los )ue sean de tipos punteros% un s.m$olo [] por cada ni(el de
anidacin al &inal de los )ue sean ta$las unidimensionales% + una estructura de la
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
&orma [0:,0:] al &inal de los )ue sean ta$las $idimensionales Apara ta$las de ms
dimensiones simplemente se ir.an a1adiendo los $lo)ues ,0: apropiadosB
1"
Si es un 7257K95.4% el identi&icador Item seguido de la lista de tipos de sus .ndices
como si de los parmetros de un mtodo se tratase
Si es un 6.2;34063.4 de o$jeto% el identi&icador #ctor seguido de la lista de tipos de
sus parmetros como si de un mtodo normal se tratase* Si el constructor &uese de
tipos entonces el identi&icador usado ser.a #cctor
Si es un 51;34063.4% el identi&icador FinaIize*
Si es un .<1495.4% el identi&icador )ue represente a ese operador segudio de la lista
de los tipos de sus operandos como si &uesen los parmetros de un mtodo normal*
En la 5a$la 1 se resumen los identi&icador )ue se dan a cada operador3
O<1495.4 I51237@7695.4 O<1495.4 I5123@7695.4
+ op_Addition & op_BitwiseAnd
- op_Substraction | op_BitwiseOr
* op_MuItipIy ^ op_ExcIusiveOr
/ op_Division ~ op_OnesCompIement
% op_ModuIus << op_LeftShift
< op_LessThan >> op_RightShift
> op_GreaterThan true op_True
>= op_GreaterThanOrEquaI faIse op_FaIse
<= op_LowerThanOrEquaI ++ op_Increment
== op_EquaIity -- op_Decrement
!= op_InequaIity
Con(ersin e-pl.cita
Op_ExpIict
! op_LogicaINot
Con(ersin
impl.cita
Op_ImpIicit
T9C-9 1#: 4om$res dados a operadores en documentacin S6?
En el caso de los operadores de con(ersin% tras la lista de parmetros se inclu+e
adicionalmente un carcter ~ seguido del tipo de retorno del operador*
Para )ue se entienda mejor la &orma en )ue se /an de dar (alores a cref% a continuacin
se muestra un &ragmento de cdigo de ejemplo en el )ue junto a cada de&inicin se /a
escrito un comentario con el (alor )ue /a$r.a )ue darle a cref para re&erenciarla3
// cref=Espacio
namespace Espacio
{
// cref=Espacio.Clase
class Clase
{
// cref=Espacio.Clase.Campo
int Campo;
// cref=Espacio.Clase.Propiedad
int Propiedad
{ set {} }
1"
En general la sinta-is )ue se sigue es <ndicenferior>:<.ndice/uperior>% pero en C# se genera
siempre 0: por)ue las ta$las slo pueden indizarse desde 2 + su l.mite superior es (aria$le%
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
// cref=Espacio.Clase.Estructuranterna
struct Estructuranterna {}
// cref=Espacio.Clase.Delegadonterno
public delegate int Delegadonterno(string s, float f);
// cref =Espacio.Clase.Evento
public event Delegadonterno Evento;
// cref=Espacio.Clase.Metodo(System.nt32, System.nt32@,
// System.nt32*, System.nt32@,
// System.nt32[][], System.nt32[0:, 0:, 0:])
int Metodo(int a, out int b, int * c, ref d, int[][] e, int[,,] f)
{return 1;}
// cref=Espacio.Clase.tem(System.String)
int this[string s]
{ set {} }
// cref=Espacio.Clase.#ctor
Clase(int a)
{}
// cref=Espacio.Clase.#cctor
static Clase(int a)
{}
// cref=Espacio.Clase.Finalize
~X()
{}
// cref=Espacio.Clase.op_Addition(Espacio.Clase, Espacio.Clase)
public static int operator +(Clase operando1, Clase operando2)
{ return 1; }
// cref=Espacio.Clase.op_Explicit (Espacio.Clase)~System.nt32
public static explicit operator int(Clase fuente)
{ return 1; }
}
}
En realidad no es siempre necesario usar cali&iacin completa en el (alor de cref* Si se
re&erencia a un tipo desde la misma de&inicin de espacio de nom$res desde donde se le
de&ini o )ue importa su espacio de nom$res% no es necesario incluir dic/o espacio en la
re&erenciaU + si se re&erencia a un miem$ro desde el el mismo tipo donde se de&ini% no
es necesario incluir ni el nom$re del tipo ni el de su espacio de nom$res*
Etiquetas recomendadas para documentacin 9ML
Aun)ue el programador puede utilizar las eti)uetas estime oportunas en sus comentarios
de documentacin + darles el signi&icado )ue )uiera% 6icroso&t recomienda usar un
juego de eti)uetas concreto con signi&icados concretos para escri$ir ciertos tipos de
in&ormacin com,n* Con ello se o$tendr.a un conjunto $sico de eti)uetas )ue cual)uier
/erramienta )ue tra$aje con documentacin S6? pueda estar preparada para procesar
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
Acomo (eremos ms adelante% el propio ;isual Studio*4E5 da ciertos usos espec.&icos a
la in&ormacin as. documentadaB

En los siguientes ep.gra&es se e-plican estas eti)uetas recomendadas agrupndolas
seg,n su utilidad* 5odas son opcionales% + no incluirlas slo tiene el e&ecto de )ue no en
la documentacin resultante no se generar.an las secciones correspondientes a ellas*
Etiquetas de uso genrico
8a+ una serie de eti)uetas prede&inidas )ue pueden colocarse% en cual)uier orden%
precediendo las de&iniciones de miem$ros en los &ic/eros &uente* Estas eti)uetas% junto
al signi&icado recomendado para su contenido% son las e-plicadas a continuacin3
<summary>3 Su contenido se utiliza para indicar un resumen so$re el signi&icado del
elemento al )ue precede* Cada (ez )ue en ;S*4E5 se use el operador . para acceder
a alg,n miem$ro de un o$jeto o tipo se usar esta in&ormacin para mostrar so$re la
pantalla del editor de te-to un resumen acerca de su utilidad*
<remarks>3 Su contenido indica una e-plicacin detallada so$re el elemento al )ue
precede* Se recomienda usar <remarks> para dar una e-plicacin detallada de los
tipos de datos + <summary> para dar una resumida de cada uno de sus miem$ros*
<exampIe>3 Su contenido es un ejemplo so$re cmo usar el elemento al )ue precede*
<seeaIso>3 Se usa para indicar un elemento cu+a documentacin guarda alguna
relacin con la del elemento al )ue precede* 4o tiene contenido + el nom$re del
elemento al )ue se remite se indic en su atri$uto cref% por lo )ue el compilador
compro$ar si e-iste* Para indicar m,ltiples documentaciones relati(as a un cierto
elemento $asta usar una eti)ueta <seeaIso> por cada una*
<permission>3 Se utiliza para indicar )u permiso necesita un elemento para poder
&uncionar* En su contenido se indica una descripcin del mismo% + su atri$uto cref
suele usarse para indicar el tipo )ue representa a ese permiso Por ejemplo3
/// <permission cref=System.Security.Permissions.FileOPermission>
/// Necesita permiso de lectura/escritura en el directorio C:\Datos
/// </permission>
Como con <seeaIso>% si un miem$ro /a de disponer (arios tipos de permisos puede
documentarse su de&inicin con tantas eti)uetas <permission> como sea necesario*
Etiquetas reIativas a mtodos
Adems de las eti)uetas uso general +a (istas% en las de&iniciones de mtodos se pueden
usar las siguientes eti)uetas recomendadas adicionales para descri$ir sus parmetros +
(alor de retorno3
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
<param>3 Permite documentar el signi&icado de un parmetro de un mtodo* En su
propiedad name se indica el nom$re del parmetro a documentar + en su contenido
se descri$e su utilidad* Por ejemplo3
/// <summary> Mtodo que muestra un texto por pantalla </summary>
/// <param name=texto> Texto a mostrar </param>
bool MuestraTexto(string texto)
{...}
Al generarse la documentacin se comprue$a si el mtodo documentado dispone de
alg,n parmetro con el nom$re indicado en name +% como ocurre con cref% si no
&uese as. se generar.a un mensaje de a(iso in&ormando de ello*
<paramref>3 Se usa para re&erenciar a parmetros de mtodos* 4o tiene contendio +
el nom$re del parmetro re&erenciado se indica en su atri$uto name* Por ejemplo3
/// <summary>
/// Mtodo que muestra por pantalla un texto con un determinado color
/// </summary>
/// <param name=texto> Texto a mostrar </param>
/// <param name=color>
/// Color con el que mostrar el <paramref name=texto/> indicado
/// </param>
bool MuestraTexto(string texto, Color color)
{...}
4ue(amente% al generarse la documentacin se compro$ar si realmente el
parmetro re&erenciado e-iste en la de&inicin del mtodo documentado + si no es
as. se gener un mensaje de a(iso in&ormando de ello*
<returns>3 Permite documentar el signi&icado del (alor de retorno de un mtodo%
indicando como contenido su+o una descripcin so$re el mismo* Por ejemplo3
/// <summary>
/// Mtodo que muestra por pantalla un texto con un determinado color
/// </summary>
/// <param name=texto> Texto a mostrar </param>
/// <param name=color>
/// Color con el que mostrar el <paramref name=texto/> indicado
/// </param>
/// <returns> ndica si el mtodo se ha ejecutado con xito o no </summary>
bool MuestraTexto(string texto, Color color)
{...}
Etiquetas reIativas a propiedades
El uso ms /a$itual de una propiedad consiste en controlar la &orma en )ue se accede a
un campo pri(ado% por lo )ue esta se comporta como si almacenase un (alor* 6ediante
el contenido de la eti)ueta <vaIue> es posi$le descri$ir el signi&icado de ese (alor3
private int edad;
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
/// <summary>
/// Almacena la edad de una persona. Si se le asigna una edad menor que 0 la
/// sustituye por 0.
/// </summary>
/// <value> Edad de la persona representada </value>
public int Edad
{
set { edad = (value<0)? 0:value }
get { return edad; }
}
Etiquetas reIativas a excepciones
Para documentar el signi&icado de un tipo de&indo como e-cepcin puede incluirse un
resumen so$re el mismo como contenido de una eti)ueta de documentacin <exception>
)ue preceda a su de&inicin* El atri$uto cref de sta suele usarse para indicar la clase de
la )ue deri(a la e-cepcin de&inida* Por ejemplo3
/// <exception cref=System.Exception>
/// Excepcin de ejemplo creada por Josan
/// </exception>
class JosanExcepcin: Exception
{}
Etiquetas reIativas a formato
Para mejorarla &orma de e-presar el contenido de las eti)uetas de documentacin )ue se
utilicen es posi$le incluir en ellas las siguientes eti)uetas de &ormato3

<see>3 Se utiliza para indicar /iper(.nculos a otros elementos de la documentacin
generada* Es una eti)ueta sin contenido en la )ue el destino del enlace es la
documentacin del miem$ro cu+o nom$re completo se indica en su atri$uto cref*
Ese nom$re es tam$in el te-to )ue las /ojas de estilo sueln mostrar para representar
por pantalla el enlace% por lo )ue los usos de esta eti)ueta suelen ser de la &orma3
/// <summary>
/// Muestra por la salida estndar el mensaje Hola!.
/// Si no sabe como se escribe en pantalla puede consultar la documentacin
del /// mtodo <see cref=System.Console.WriteLine/>.
/// </summary>
public static void Saluda()
{
Console.WriteLine(Hola!);
}
4tese )ue la di&erencia de <see> + <seeaIso> es )ue la primera se usa para indicar
enlaces en medio de te-tos mientras )ue la otra se usa para indicar enlaces )ue se
deseen incluir en una seccin aparte tipo N;ase tam$inO*
<code> + <c>3 Am$as eti)uetas se usan para delimitar te-tos /an de ser considerarse
&ragmentos de cdigo &uente* ?a di&erencia entre ellas es )ue <code> se recomienda
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
usar para &ragmentos multil.nea + <c> para los de una ,nica l.neaU + )ue las /ojas de
estilo mostrarn el contenido de las eti)uetas <code> respetando su espaciado + el de
las eti)uetas <c> sin respetarlo + trantando cual)uier aparicin consecuti(a de (arios
caracteres de espaciado como si &uesen un ,nico espacio en $lanco*
En general% <code> suele usarse dentro de eti)uetas <exampIe> para mostrar
&ragmentos de cdigos de ejemplo% mientras )ue <c> suele usarse para /acer
re&erencia a elementos puntales de los cdigos &uente* Por ejemplo3
/// <example>
/// Este ejemplo muestra cmo llamar al mtodo <c>Cumple()</c> de esta clase:
/// <code>
/// Persona p = new Persona(...);
/// p.Cumple();
/// </code>
/// </example>
<para>3 Se usa para delimitar prra&os dentro del te-to contenido en otras eti)uetas%
considerndose )ue el contenido de cada eti)ueta <para> &orma parte de un prra&o
distinto* Generalmente se usa dentro de eti)uetas <remarks>% +a )ue son las )ue
suelen necesitar prra&os al tener un contenido ms largo* Por ejemplo3
/// <remarks>
/// <para>
/// Primer prrafo de la descripcin del miembro...
/// </para>
/// <para>
/// Segundo prrafo de la descripcin del miembro...
/// </para>
/// </remarks>
<Iist>3 Se utiliza para incluir listas + ta$las como contenido de otras eti)uetas* 5odo
uso de esta eti)ueta de$er.a incluir un atri$uto type )ue indi)ue el tipo de estructura
se desea de&inir seg,n tome uno de los siguientes (alores3
buIIet3 #ndica )ue se trata de una lista no numerada
number3 #ndica )ue se trata de una lista numerada
tabIe3 #ndica )ue se trata de una ta$la
El contenido de <Iist> depender del tipo de estructura representado en cada caso3
Si se trata de una lista normal Z+a sea numerada o no numeradaX su contenido
ser una eti)ueta <item> por cada elemento de la lista% + cada eti)ueta de este
tipo contendr una eti)ueta <description> con el te-to correspondiente a ese
elemento* Por ejemplo3
/// <list type=bullet>
/// <item>
/// <description>
/// Elemento 1
/// </description>
/// </item>
/// <item>
/// <description>
/// Elemento 2
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
/// </description>
/// </item>
/// </list>
Si tratase de una ta$la% su contenido ser.a similar al de las listas normales slo
)ue por cada &ila se incluir.a una eti)ueta <item> + dentro de sta se inclir.a una
eti)ueta <description> por cada columna de esa &ila*
Adems% opcionalmente se podr.a incluir una eti)ueta <Iistheader> antes de las
eti)uetas <item> donde se indicar.a cul /a de ser el te-to de la ca$ecera de la
ta$la* Esta eti)ueta se usa igual )ue las eti)uetas <item>3 incluir una eti)ueta
<description> por cada columna*
Por ,ltimo% si &uese una lista de de&iniciones cada <item> contendr.a una primera
eti)ueta <term> con el nom$re del elemento a de&inir + otra segunda eti)ueta
<description> con su de&inicin* Lpcionalmente tam$in podria incluirse una
eti)ueta <Iistheader> con la ca$ecera de la lista* Por ejemplo3
/// <list type=bullet>
/// <item>
/// <term>
/// Trmino 1
/// </term>
/// <description>
/// Descripcin de trmino 1
/// </description>
/// </item>
/// <item>
/// <term>
/// Trmino 2
/// </term>
/// <description>
/// Descripcin de trmino 2
/// </description>
/// </item>
/// </list>
:eneracin de documentacin 9ML
Generacin a travs deI compiIador en Inea de comandos
Ksando el compilador en l.nea de comandos puede generarse documentacin so$re los
tipos de&inidos en los &uentes a compilar usando la opcin de compilacin
/doc:<fichero>* Por ejemplo% para compilar un &ic/ero de cdigo &uente Persona.cs +
generar su documentacin en Persona.xml% /a$r.a )ue llamar al compilador con3
csc 5ersona.cs *doc+5ersona.$ml
Si se a$re con #nternet E-plorer el &ic/ero S6? as. generado se (er un conjunto de
eti)uetas )ue recogen toda la in&ormacin u$icada en los comentarios de documentacin
de los &uentes compilados* Aun)ue para una persona pueda resultar di&.cil leer esta
in&ormacin% para una aplicacin /acerlo es mu+ sencillo a tra(s de un analizador
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
S6?* Si se dese )ue tam$in sea legi$le para /umanos $asta a$rirlo con cual)uier
editor de te-tos + a1adirle una primera l.nea de la &orma3
<?xmI:styIesheet href="<ficheroXSL>" type="text/xsI"?>
Con esta l.nea se indica )ue se desea utilizar el &ic/ero indicado en <ficheroXSL> como
/oja de estilo SS? con la )ue con(ertir la documentacin S6? a alg,n lenguaje ms
&cilmente legi$le por /umanos Ageneralmente% 856?B* Por ejemplo% si doc.$sl es el
nom$re de dic/o &ic/ero SS?% $astar.a escri$ir3
<?xml:stylesheet href="doc.xsl" type="text/xsl"?>
Para /acerse una idea de las di&erencias e-istentes entre a$rir con #nternet E-plorer un
&ic/ero de documentacin sin /oja SS? asociada + a$rir ese mismo &ic/ero pero
asocindole una /oja SS?% puede o$ser(ar en la #lustracin T + la #lustracin [3
I-0;3496782 *: Cocumentacin S6? sin /oja de estilo
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
I-0;3496782 !: Cocumentacin S6? con /oja de estilo SS?
4o se preocupe si no sa$e escri$ir /ojas de estilo% pues como se e-plica en el siguiente
ep.gra&e% ;isual Studio*4E5 inclu+e una /erramienta )ue puede generar directamente la
documentacin en un 856? &cilmente legi$le para /umanos*
Generacin a travs de VisuaI Studio.NET
Si pre&iere usar ;isual Studio*4E5% entonces para la generacin de la documentacin
$asta se1alar el pro+ecto a documentar en el $olution 'xplorer + escri$ir el nom$re
del &ic/ero S6? a generar en el cuadro de te-to (iew Property Pages
Con+iguration Properties Build D7L #ocumentation !ile
Cuando se compile el pro+ecto% la documentacin S6? so$re el mismo se guardar en
el &ic/ero indicado en el cuadro de te-to anterior* Este &ic/ero se almacenar dentro de
la su$carpeta 1in del directorio del pro+ecto% + si se desea poder (isualizarla desde el
$olution 'xplorer /a+ )ue acti(ar en ste el $otn $how &ll !iles*
En principio% para conseguir (isualizar esta documentacin en un &ormato ms legi$le
para /umanos podr.a asocirsele una /oja SS? como se e-plic para el caso del
compilador en l.nea de comandos* Sin em$argo% ;isual Studio*4E5 proporciona una
&orma ms sencilla de /acerlo a tra(s de la /erramienta u$icada en Tools Build
Comments %eb Pages Esta utilidad a partir de la in&ormacin incluida en las eti)uetas
recomendadas de los comentarios del &uente genera pginas 856? )ue muestran la
documentacin del pro+ecto de una &orma (istosa e intuiti(a A(er #lustracin RB
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
I-0;3496782 8: Cocumentacin 856? generada por ;isual Studio*4E5
Estructura de la documentacin 9ML
A/ora )ue +a sa$emos cmo escri$ir comentarios de documentacin + generar a partir
de ellos un &ic/ero S6? con la documentacin de los tipos de datos de un &ic/ero% slo
)ueda estudiar cul es concretamente la estructura de dic/o &ic/ero generado +a )ue
entenderla es &undamental para la escritura de aplicaciones encargadas de procesarlo*
En principio% si compilamos como mdulo un &uente sin comentarios de documentacin
pero solicitando la generacin de documentacin% se o$tendr el siguiente &ic/ero S6?3
<?xml version="1.0"?>
<doc>
<members>
</members>
</doc>
Como se (e% la primera l.nea del &ic/ero es la ca$ecera t.pica de todo &ic/ero S6? en la
)ue se indica cul es la (ersin del lenguaje )ue utiliza* 5ras ella se coloca una eti)ueta
<doc> )ue contendr toda la documentacin generada% + los comentarios de
documentacin de los miem$ros del &uente compilado se ir.an inclu+endo dentro de la
eti)ueta <members> )ue contiene Aen este caso dic/a eti)ueta est (ac.a +a )ue el &uente
compilado carec.a de comentarios de documentacinB
Si /u$isemos compilado el &uente como li$rer.a o como ejecuta$le se /a$r.a generado
un ensam$lado% + a la estructura anterior se le a1adir.a una eti)ueta adicional dentro de
<doc> con in&ormacin so$re el mismo% )uedando3
<?xml version="1.0"?>
<doc>
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
<assembly>
<name>Persona</name>
</assembly>
<members>
</members>
</doc>
Como se (e% dentro de la eti)ueta <assembIy> contenida en <doc> se indican las
caracter.sticas del ensam$lado generado* En concreto% su nom$re se indica en la eti)ueta
<name> )ue contiene Ase supone )ue el ensam$lado se compil con el nom$re 4ersonaB
Si a/ora le a1adimos comentarios de documentacin (eremos )ue el contenido de estos
se inserta dentro de la eti)ueta <members>% en una eti)ueta <member> espec.&ica para
cada miem$ro con comentarios de documentacin* Por ejemplo% dado el &uente3
/// <summary>
/// Clase de ejemplo de cmo escribir documentacion XML
/// </summary>
class A
{
/// <summary>
/// Mtodo principal de ejemplo perteneciente a clase <see cref="A"/>
/// </summary>
/// <remarks>
/// No hace nada
/// </remarks>
static void Main()
{}
}
?a documentacin S6? )ue generara compilarlo con la opcin /doc es3
<?xml version="1.0"?>
<doc>
<assembly>
<name>A</name>
</assembly>
<members>
<member name="T:A">
<summary>
Clase de ejemplo de cmo escribir documentacion XML
</summary>
</member>
<member name="M:A.Main">
<summary>
Mtodo principal de ejemplo perteneciente a clase <see cref="T:A"/>
</summary>
<remarks>
No hace nada
</remarks>
</member>
</members>
</doc>
Como puede (erse% dentro de la eti)ueta <members> no se sigue ninguna estructura
jerr)uica a la /ora de descri$ir los elementos del &uente% sino )ue todos se descri$en al
mismo ni(el + de la misma &orma3 se inclu+e una eti)ueta <member> por cada miem$ro
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
documentado en cu+o atri$uto name se indica su nom$re + en cu+o contenido se inserta
el te-to de sus comentarios de documentacin*
4tese )ue a cada elemento se le da en el atri$uto name de su eti)ueta <member>
correspondiente un identi&icador )ue lo distingue un.(ocamente del resto de miem$ros
documentados + )ue sigue la siguiente sinta-is3
<indicadorElemento>:<nombreCompletamenteCalificado>
El <indicadorElemento> es simplemente un carcter )ue indica )u tipo de elemento se
documenta dentro de la eti)ueta <member>* Puede tomar estos (alores3
I257695.4 51 37<. 51 1-1?123. T7<. 51 1-1?123. 7257695.
T
5ipo de dato
F
Campo
P
Propiedad o indizador
M
6todo Aincluidos operadores + contructoresB
E
E(ento
T9C-9 13: #ndicadores de tipos de elementos en documentaciones S6?
Como se (e en el ejemplo% en la documentacin generada se usa tam$in la sinta-is de
los (alores del atri$uto name de las eti)uetas <member> para representar las re&erencias
mediante atri$utos cref* Adems% cuando dic/a sinta-is se usa para e-presar (alores de
cref pueden usarse dos tipos de indicadores ms3
I257695.4 51 37<. 51 1-1?123.
T7<. 51 1-1?123. 7257695.
N
Espacio de nom$res
!
4inguno* Se genera cuando el miem$ro indicado
en cref no e-iste*
T9C-9 143 #ndicadores de tipos de elementos para atri$utos cref
?a idea )ue /a+ detrs de usar la sinta-is (ista para representar elementos del &uente es
proporcinar un mecanismo sencillo mediante el )ue las /erramientas encargadas de
procesar las documentaciones S6? puedan determinar cules son los miem$ros
documentados o re&erenciados + acceder% con a+uda de los tipos de System.RefIection% a
sus metadatos asociados.
"eparacin entre documentacin 9ML % cdigo fuente
A (eces puede )ue interesar incrustar toda la documentacin en el mismo &ic/ero )ue el
cdigo &uente% por ejemplo si se desea reusarla en m,ltiples &uentes o si es mu+
(oluminosa e incluirla en el &uente di&icultar.a su legi$ilidad* Para estos casos se da la
posi$lidad de dejar la documentacin en un &ic/ero S6? aparte + re&erenciarla en el
cdigo &uente a tra(s de la eti)ueta de documentacin <incIude>% )ue su usa as.3
<incIude fiIe="<nombreFichero>" path="<rutaDocumentacin>"/>
El lenguaje de programacin C# 5ema 1:3 Cocumentacin S6?
Cuando el compilador encuentre esta eti)ueta al generar la documentacin lo )ue /ar
ser tratarla como si &uese la eti)ueta del &ic/ero <nombreFichero> indicada por la
e-presin (P93J
15
<rutaDocumentacin> Por ejemplo% si se tiene el cdigo3
/// <include file=otro.xml path=Miembros/Miembro[@nombre=A]/*/>
class A
{}
En este uso de <incIude> se est indicando )ue se /a de insertar todo el contenido de la
eti)ueta <Miembro> contenida en <Miembros> cu+o atri$uto nombre (alga A* ?uego% si el
contenido del &ic/ero otro.$ml es de la &orma3
<Miembros>
...
<Miembro name=A>
<remarks>
Ejemplo de inclusin de documentacin XML externa
</remarks>
<example>
Para crear un objeto de esta clase usar:
<code>
A obj = new A();
</code>
</example>
</Miembro>
...
</Miembros>
Entonces% el compilador generar documentacin como si el &uente contu(iese33
/// <remarks>
/// Ejemplo de inclusin de documentacin XML externa
/// </remarks>
/// <example>
/// Para crear un objeto de esta clase usar:
/// <code>
/// A obj = new A();
/// </code>
/// </example>
class A
{}
1Q
(P93J es un lenguaje )ue se utiliza para especi&icar rutas en &ic/eros S6? )ue permitan seleccionar
ciertas eti)uetas de los mismos* Si no lo conoce puede encontrar su especi&icacin en \SPat/]
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
TEMA 20: EI compiIador de C# de Microsoft
!ntroduccin
A lo largo de los temas anteriores se /an e-plicando muc/os aspectos so$re cmo usar
el compilador de C# de 6icroso&t incluido en el *4E5 Wrame=orI SCD* Sin em$argo%
una (ez descrito el lenguaje por completo es el momento adecuado para e-plicar
pormenorizadamente cmo utilizarlo + )u opciones de compilacin admite% pues
muc/as de ellas se $asan en conceptos relacionados con caracter.sticas del lenguaje*
Por otro lado% las di&erentes e-plicaciones dadas so$re l se /an ido desperdigando a lo
largo de muc/os de los temas pre(ios% por lo )ue es tam$in con(iene agruparlas todas
en un mismo sitio de modo )ue sea ms &cil localizarlas*
Aun)ue en un principio lo )ue se (a es a e-plicar cmo usar el compilador en l.nea de
comandos% dado )ue ;isual Studio*4E5 tam$in /ace uso interno de l para compilar%
al &inal del tema se incluir un ep.gra&e dedicado a e-plicar cmo controlar desde dic/a
/erramienta (isual las opciones )ue se utilizarn al llamarlo*
"inta2is general de uso del compilador
El nom$re del ejecuta$le del compilador de C# incluido en el *4E5 Wrame=orI SCD es
csc.exe + podr encontrarlo en la carpeta Microso<t.Y@T8Grame,orK82C..DFCV
incluida dentro del directorio de instalacin de su (ersin de Hindo=s
1T
* Ce todas
&ormas% el programa de instalacin del SCD lo a1ade automticamente al pat/% por lo
)ue en principio puede llamrsele sin pro$lemas desde cual)uier directorio*
?a &orma ms $sica de llamar al compilador consiste en pasarle como argumentos los
nom$re de los &uentes a compilar% caso en )ue intentar.a generar en el directorio desde
el )ue se le llame un ejecuta$le a partir de ellos con el mismo nom$re )ue el primero de
los &uentes indicados + e-tensin .exe Por ejemplo% ante una llamada como3
csc Guente..cs Guente1.cs GuenteC.cs
El compilador intentar generar un &uente Guente..e$e en el directorio desde el )ue se
lo llam cu+o cdigo sea el resultante de compilar WuenteA*cs% Wuente0*cs + WuenteC*cs
L$(iamente% para )ue ello sea posi$le el compilador /a$r de disponer de permiso de
escritura + espacio su&iciente en dic/o directorio + adems alguno de los &uentes
indicados tendr )ue disponer de un punto de entrada (lido*
Este comportamiento por de&ecto puede (ariarse especi&icando en la llamada a csc
opciones de compilacin adicionales )ue sigan la sinta-is3
:indicador/5ciBn=:o5ciBn=
1T
El nom$re de la carpeta 2C..DFCV (ariar si utiliza una (ersin del SCD di&erente a la de la 0eta *
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
El :indicador/5ciBn= puede ser el carcter / o el carcter 8% aun)ue en adelante slo
/aremos uso de /* >especto a :o5ciBn=% pueden indicarse dos tipos de opciones3
F-9=;: Son opciones cu+a aparicin o ausencia tienen un determinado signi&icado
para el compilador* Se indican de esta manera3
:nom-reGlag=<activado?>
:acti2ado= es opcional e indica si se desea acti(ar el signi&icado del &lag* Puede
ser el carcter para indicar )ue s. o el carcter - para indicar )ue no% aun)ue en
realidad darle el (alor es innecesario por)ue es lo )ue se toma por de&ecto*
5am$in /a+ algunos &lags )ue no admiten ninguno de los dos caracteres% pues se
considera )ue siempre )ue aparezcan en la llamada al compilador es por)ue se desea
acti(ar su signi&icado + si no apareciesen se considerar.a )ue se desea desacti(arlo*
A continuacin se muestran algunos ejemplos de uso de un &lag llamado /optimi1e
al compilar * 4o se preocupe por sa$er a/ora para )ue sir(e% sino simplemente &.jese
en cmose se usa + note )ue los dos primeros ejemplos son e)ui(alentes3
csc *o5timiEe Guente.cs
csc *o5timiEeZ Guente.cs
csc *o5timiEe' Guente.cs
O<67.21; 6.2 A9-.41;: A di&erencia de los &lags% son opciones cu+a aparicin no es
(lida por s. misma sino )ue siempre )ue se usen /an de incluir la especi&icacin de
uno o (arios (alores* ?a &orma en )ue se especi&ican es3
:nom-reGlag=C:2alores=
?os :2alores= indicados pueden ser cuales)uiera% aun)ue si se desea especi&icar
(arios /a+ )ue separarlos entre s. con caracteres de coma AEB punto + coma AFB
Como es lgico% en principio los :2alores= indicados no pueden incluir caracteres
de espacio +a )ue stos se interpretar.an como separadores de argumentos en la
llamada a csc* Sin em$argo% lo )ue s. se permite es incluirlos si pre(iamente se les
encierra entre comillas do$les AGB
L$(iamente% como las comillas do$les tam$in tiene un signi&icado especial en los
argumentos de csc tampoco ser posi$le incluirlas directamente como carcter en
:2alores=* En este caso% para sol(entar esto lo )ue se /ace es interpretarlas como
caracteres normales si (an precedidas de H + con su signi&icado especial si no*
Ce nue(o% esto lle(a al pro$lema de )ue el signi&icado de H si precede a G tam$in
puede ser especial% + para solucionarlo lo a/ora )ue se /ace es incluirlo duplicado
AHHB si aparece precediendo a un G pero no se desea )ue tome su signi&icado especial*
Ejemplos e)ui(alentes de cmo compilar dando (alores a una opcin /r son3
csc *r+Li-.dll *r+Li-D.dll Guente.cs
csc *r+Li-C.dll#Li-D.dll Guente.cs
csc *r+Li-C.dll&Li-(.dll Guente.cs
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
Aun)ue en los ejemplos mostrados siempre se /an incluido las opciones antes )ue los
nom$res de los &uentes a compilar% en realidad ello no tiene por)u ser as. + se pueden
mezclar li$remente + en cual)uier orden opciones + nom$res de &uentes a compilar
Asal(o e-cepciones )ue en su momento se e-plicarnB
&pciones de compilacin
Kna (ez e-plicado cmo utilizar el compilador en l.neas generales es el momento
propicio para pasar a e-plicar cules son en concreto las opciones )ue admite* Esto se
/ar desglosndolas en di&erentes categor.as seg,n su utilidad*
Antes de empezar es preciso comentar )ue la ma+or.a de estas opciones disponen de dos
nom$res di&erentes3 un nom$re largo )ue permite deducir con &acilidad su utilidad + un
nom$re corto menos claro pero )ue permite especi&icarlas ms a$re(iadamente* Cuando
se /aga re&erencia por primera (ez a cada opcin se utilizar su nom$re largo + entre
parntesis se indicar su nom$re corto justo a continuacin* El resto de re&erencias a
cada opcin se /arn usando indistintamente uno u otro de sus nom$res*
Opciones bsicas
En este ep.gra&e se e-plicarn todas a)uellas opciones )ue suelen usarse con ma+or
&recuencia a la /ora de compilar aplicaciones* Como la ma+or.a +a se e-plicaron en
detalle en el Tema 8: "ntrod#$$i)n a C9% dic/as opciones a)u. simplemente se resumen3
/recurse3 Si en (ez de indicar el nom$re de cada &ic/ero a compilar como se /a
dic/o se indica como (alor de esta opcin se consigue )ue si el compilador no lo
encuentra en la ruta indicada lo $us)ue en los su$directorios de la misma*
Por ejemplo% la siguiente llamada indica )ue se desea compilar el &ic/ero <uente.cs
u$icado dentro del directorio c+8Mis 9ocumentos o alg,n su$directorio su+o3
csc *recurse+"Mis 9ocumentos"8<uente.cs
/target A/tB3 Por de&ecto al compilar se genera un ejecuta$le cu+a ejecucin
pro(oca la apertura de una (entana de consola si al lanzarlo no /u$iese ninguna
a$ierta* Esto puede cam$iarse dando uno de los (alores indicados en la 5a$la 1Q a
esta opcin3
V9-.4 T7<. 51 @76J14. 9 =121494
exe ninguno Ejecuta$le con (entana de consola A(alor por de&ectoB
winexe
Ejecuta$le sin (entana de consola* etil para escri$ir
aplicaciones de (entanas o sin inter&az
Iibrary
?i$rer.a
moduIe
6dulo de cdigo no perteneciente a ning,n ensam$lado
T9C-9 15: ;alores admitidos por la opcin /t de csc
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
5anto las li$rer.as como los ejecuta$les son simples colecciones de tipos de datos
compilados* ?a ,nica di&erencia entre ellos es )ue los segundos disponen de un
mtodo especial AMain()B )ue sir(e de punto de entrada a partir del )ue puede
ejecutarse cdigo usando los mecanismo o&recidos por el sistema operati(o
Aescri$iendo su nom$re en la l.nea de comandos% seleccionndolo gr&icamente% etc*B
?a di&erencia de un mdulo con los anteriores tipos de &ic/eros es )ue ste no &orma
parte de ning,n ensam$lado mientras )ue los primeros s.* El C?> no puede tra$ajar
con mdulos por)ue estos carecen de mani&iesto% pero crearlos permite disponer de
cdigo compilado )ue pueda a1adirse a ensam$lados )ue se generen posteriormente
+ )ue podrn acceder a sus miem$ros internaI*
/main3 Si al compilar un ejecuta$le /u$iese ms de un punto de entrada (lido entre
los tipos de&inidos en los &uentes a compilar se /a de indicar como (alor de esta
opcin cul es el nom$re del tipo )ue inclu+e la de&inicin del Main() a utilizar% pues
si no el compilador no sa$r.a con c,al de todas )uedarse*
Como es lgico% lo )ue nunca puede /acerse es de&inir ms de un punto de entrada
en un mismo tipo de dato% pues entonces ni si)uiera a tra(s de la opcin /main
podr.a resol(erse la am$igaedad*
/out A/oB3 Por de&ecto el resultado de la compilacin de un ejecuta$le es un &ic/ero
.exe con el nom$re del &uente compilado )ue contenga el punto de entrada% + el de
la compilacin de un mdulo o li$rer.a es un &ic/ero con el nom$re del primero de
los &uentes a compilar indicados + e-tensin dependiente del tipo de &ic/ero
generado A.netmodule para mdulos + .dll para li$rer.asB Si se desea darle otro
nom$re $asta indicarlo como (alor de esta opcin*
El (alor )ue se le d /a de incluir la e-tensin del &ic/ero a generar% lo )ue permite
compilar &ic/eros con e-tensiones di&erentes a las de su tipo* Por ejemplo% para crear
un mdulo ..e$e a partir de un &uente ..cs puede /acerse3
csc *out+..e$e *t+module ..cs
L$(iamente% aun)ue tenga e-tensin .exe el &ic/ero generado ser un mdulo + no
un ejecuta$le% por lo )ue si se intenta ejecutarlo se producir un error in&ormando de
)ue no es un ejecuta$le (lido* Como puede deducirse% cam$iar la e-tensin de los
&ic/eros generados no suele ser ,til + slo podr.a (enir $ien para di&icultar aposta la
comprensin del &uncionamiento de una aplicacin o para identi&icar ensam$lados
con alg,n signi&icado o contenido especial*
/re+erence A/rB3 Por de&ecto slo se $uscan de&iniciones de tipos de datos
e-ternas a los &uentes a compilar en la li$rer.a mscorlib.dll )ue &orma parte de la
0C?* Si alguno de los &uentes a compilar /ace uso de tipos p,$licos de&inidos en
otros ensam$lados /a+ )ue indicar como (alores de /r cules son esos ensam$lados
para )ue tam$in se $us)ue en ellos*
En mscorlib.dll se encuentran los tipos de uso ms &recuentos incluidos en la
0C?* En el poco &recuente caso de )ue /a+a de&inido su propia (ersin de ellos + no
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
desee )ue se use la de la 0C?% puede puede pasar al compilador el &lag /nostdlib
para indicarle )ue no desea )ue $us)ue impl.citamente en mscorlib.dll*
Puede )ue termine descu$riendo )ue en realidad tampoco /ace &alta re&erenciar a la
ma+or.a de las restantes li$rer.as )ue &orman la 0C?* Pues $ien% esto no se de$e a
)ue tam$in las re&erencie impl.citamente el compilador% sino a )ue se inclu+en en
un &ic/ero de respuesta Ams adelante se e-plica lo )ue son este tipo de &ic/erosB
usado por de&ecto por el compilador* Si no desea )ue utilice este &ic/ero puede
pasarle el &lag /nocon+ig*
Cuando se den (alores a /r /a+ )ue tener en cuenta )ue por de&ecto el compilador
interpretar cada ruta as. indicada de manera relati(a respecto al directorio desde el
)ue se le llame* Si no lo encuentra all. lo /ar relati(amente respecto al directorio
donde est instalado el C?>% )ue en los sistemas operati(os Hindo=s es el
su$directorio 7icroso+t.N'TH!ramewor@H2A.B.IJAK del directorio de instalacin
de Hindo=s
1[
* V si tampoco lo encuentra all. la interpretar respecto a los
directorios indicados por la (aria$le de entorno LLB de su sistema operati(o
1R
*
Esta pol.tica de $,s)ueda puede modi&icarse inclu+endo opciones /lib al llamar al
compilador cu+os (alores le indi)uen en )u directorios /a de $uscar antes de pasar
a $uscar en los indicados por la (aria$le de entorno LLB*
/addmodule3 Wunciona de &orma parecida a /r pero se utiliza cuando lo )ue usan los
&uentes son tipos de&inidos e-ternamente en mdulos en (ez de en ensam$lados*
#ncluso a la /ora de $uscar mdulos se sigue la misma pol.tica )ue al $uscar
ensam$lados + se admite el uso de /lib para modi&icarla*
Se inclu+en opciones /r + /addmodule separadas por)ue a1adir un mdulo a una
compilacin implica decir )ue se desea )ue los tipos )ue inclu+e &ormen parte del
ensam$lado a generar% por lo )ue los &uentes a compilar podrn acceder a sus
miem$ros internaI* Sin em$argo% cuando se re&erencia a otros ensam$lados con /r
esto no ocurre + los &uentes compilados no podrn acceder a sus miem$ros internaI*
Es importante se1alar )ue el C?> espera )ue todos los mdulos )ue se a1adan a un
ensam$lado se distri$u+an dentro del mismo directorio )ue la li$rer.a o ejecuta$le
correspondiente al mismo* Si no se /aciese as. no los podr.a localizar + en tiempo de
ejecucin se producir.a una System.TypeLoadException si se intentase acceder a los
tipos de&inidos en ellos*
Aun)ue en principio se /a dic/o )ue no importa cmo se intercalen opciones +
nom$res de &uentes entre los argumentos pasados a csc% /a+ una e-cepcin )ue consiste
en )ue /out + /r siempre /an de indicarse antes de alg,n &uente* Esto permite )ue en
una misma llamada al compilador sea posi$le solicitar la generacin de un ensam$lado
+ m,ltiples mdulos de cdigo% pues se considera )ue cada aparicin de las opciones
anteriores /ace re&erencia slo a los &uentes )ue le siguen* Por ejemplo% dada3
1[
Si utiliza otra (ersin del C?> di&erente a la incluida en la 0eta del *4E5 Wrame=orI SCD /a de
sustituir el n,mero de 2A.B.IJAK por el correspondiente a dic/a (ersin*
1R
Por de&ecto% en la 0eta estos directorios son &rchi2os de programaH7icroso+t.N'TH!ramewor@$#M
HLib + &rchi2os de ProgramaH7icroso+t (isual $tudioH(CJNHbin
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
csc *t+li-rary *out+Li-..dll ..cs *t+module *out+Mod1.netmodule 1.cs
Esta llamada pro(ocar la compilacin de ..cs como li$rer.a de nom$re Li-..dll + la
de 1.cs como mdulo llamado Mod1.netmodule.
Sin em$argo% al /acer as. compilaciones m,ltiples /a+ )ue tener en cuenta )ue slo es
(lido solicitar )ue el primer grupo de &ic/eros indicado se compile como ensam$lado*
Por tanto% ser.a incorrecto /acer3
csc *t+module *out+Mod1.netmodule 1.cs *t+li-rary *out+Li-..dll ..cs
Esta llamada es incorrecta por)ue indica )ue se desea )ue el segundo grupo de &ic/eros
d lugar a un ensam$lado + ello slo puede /acerse con el primero*
Por otro lado% tam$in /a+ )ue tener en cuenta )ue no es (lido )ue un mismo tipo de
dato se de&ina en (arios de los grupos de &ic/eros indicados* Por ejemplo% si se )uisiese
compilar ..cs como ejecuta$le + como mdulo podr.a pensarse en /acer3
csc ..cs *t+li-rary ..cs
Sin em$argo% esta llamada no es (lida por)ue los dos grupos de &ic/eros indicados
contienen el mismo &ic/ero + por tanto de&iniciones comunes de tipos de datos* ?a ,nica
solucin posi$le ser.a /acer dos llamadas por separado al compilador como3
csc ..cs
csc *t+li-ary ..cs
ManipuIacin de recursos
?os @76J14.; 51 41604;.; son arc/i(os )ue no contienen cdigo sino slo datos tales
como como cadenas de te-tos% imgenes% (.deos o sonidos* Su utilidad es &acilitar el
desacople entre las aplicaciones + los datos concretos )ue usen% de modo )ue sea &cil
reutilizarlos en m,ltiples aplicaciones% modi&icarlos sin tener )ue recompilar los &uentes
+ desarrollar di&erentes (ersiones de cada aplicacin en las )ue slo (ar.en dic/os datos*
Estos &ic/eros son especialmente ,tiles al /ora de internacionalizar aplicaciones% pues si
se dejan todos los datos )ue se utilicen en &ic/eros de recursos independiente del
cdigo% a la /ora de crear nue(as (ersiones en otros idiomas slo ser necesario cam$iar
los &ic/eros de recursos + /a$r )ue tocar para nada el cdigo*
El o$jeti(o de este tema no es e-plicar cmo crear + acceder a &ic/eros de recursos% sino
e-plicar el signi&icado de las opciones de compilacin relacionadas con ellos* Si desea
aprender ms so$re recursos puede comenzar $uscando en el apartado (isual
$tudio.N'T .N'T !ramewor@ .N'T !ramewor@ Tutorials Resources
and Locali1ation Osing the .N'T !ramewor@ $#M de la a+uda del SCD*
?o )ue s. es importante es se1alar )ue aun)ue en la plata&orma *4E5 pueden crearse
&ic/eros de recursos tanto en &ormato .txt como .resx% el compilador de C# slo los
admite si estn compilados en &ormato *resources* Para ello% en el SCD se inclu+e una
utilidad llamad resgen.exe )ue permite compilar en dic/o &ormato &ic/eros de recursos
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
escritos en cual)uiera de los &ormatos anteriores con slo pasrselos como argumentos*
Por ejemplo% si se le llama as.3

resgen misrecursos.res$
Suponiendo )ue el contenido de misrecursos.res$ sea el de un &ic/ero .resx (lido%
tras esta llamada se /a$r generado en el directorio desde el )ue se le llam un &ic/ero
misrecursos.resources con el contenido de misrecursos.res$*
Para a1adir este &ic/ero al ensam$lado resultante de una compilacin se puede utilizar la
opcin /lin@resource A/lin@resB As. por ejemplo% para crear un ensam$lado
<uenteC.dll &ormado por el cdigo resultante de compilar <uenteC.cs + los recursos
de misrecursos.resources podr.a compilarse con3
csc *t+li-rary <uenteC.cs *linKres+misrescursos.resources
Ce este modo el &ic/ero de recursos &ormar parte del ensam$lado generado pero
permanecer en un &ic/ero separado de +uenteA.dll* Si se desease incrustarlo en l
/a$r.a )ue /a$er compilado con la opcin /resource A/resB en (ez de /lin@res tal +
como se muestra a continuacin3
csc *t+li-rary <uenteC.cs *res+misrescursos.resources
Como un tipo especial de recurso )ue com,mente suele incrustarase en los ejecuta$les
de los programas es el icono A&ic/ero gr&ico en &ormato .icoB con el )ue desde las
inter&aces gr&icas de los sistemas operati(os se les representar% csc o&rece una opcin
espec.&ica llamada /winPIicon en cu+o (alor puede indicrsele el icono a incrustar3

csc 5rograma.cs *,in(Dicon+5rograma.ico
En realidad /a+ )ue recordar el uso de &ic/eros de recursos no es un aspecto introducido
en la plata&orma *4E5 sino disponi$le desde /ace tiempo en en la plata&orma Hindo=s
en &orma de &ic/eros .res* Por compati$ilidad con este antiguo &ormato de recursos%
csc incorpora una opcin /winPIres )ue permite incrustarlos de igual &orma a como
/res incrusta los no(edosos &ic/eros .resources*
En cual)uier caso% /a+ )ue se1alar )ue siempre )ue se a1ada un &ic/ero de recursos a un
ensam$lado la (isi$ilidad )ue se considerar para los recursos )ue inclu+a es pubIic*
Configuracin de mensajes de avisos y errores
Cada (ez )ue el compilador detecta alg,n error en uno de los &uentes a compilar genera
un mensaje in&ormando de ello en el )ue indica en )u &ic/ero de cdigo &uente + en
)u posicin e-acta del mismo Al.nea + columnaB lo /a detectado* Por ejemplo% si en la
columna ! de la l.nea [ de un &uente llamado e7.cs se llama a un mtodo con nom$re
completo ..[(% ine-istente% se mostrar un mensaje como3
e7.cs(X#(%+ error CSCCX+ M.M does not contain a de<inition <or M[M
4tese )ue del &ic/ero slo se da su nom$re + ello podr.a no identi&icarlo un.(ocamente
si se compilaron a la (ez (arios con el mismo nom$re pero pertencientes a directorios
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
di&erentes* Para solucionar esto puede usarse la opcin /+ullpaths% con lo )ue de los
mensajes de error incluir.an siempre la ruta completa de los &ic/eros de&ectuosos* Por
ejemplo% si el &ic/ero del ejemplo anterior se encontra$a en C+8@7em5lo% al compilarlo
con esta opcin se mostrar.a el mensaje de error as.3
C+8@7em5lo8e7.cs(X#(%+ error CSCCX+ M.M does not contain a de<inition
<or M[M
8a+ (eces )ue el compilador detecta )ue se /an escrito en el &uente ciertas secciones de
tal manera )ue sin ser errneas son cuanto menos sospec/osas A+a sea por ser a$surdas%
por prestarse a con&usin% etcB% + en esos casos lo )ue /ace es emitir mensajes de a(iso*
Por ejemplo% si en la de&inicin del tipo A del &uente 5rue-a.cs se /u$iese incluido3

static void Main(int x)
{}
En principio es una de&inicin de mtodo per&ectamente (lida* Sin em$argo% como se
parece muc/o a una de&inicin de punto de entrada pero no es (lida como tal% el
compilador generar el mensaje de a(iso )ue sigue para in&ormar de ello al usuario por
si acaso ste lo )ue )uer.a /acer era de&inir un punto de entrada + se e)ui(oc3
5rue-a.cs(X#CV%+ ,arning CSDI+ M..Main(int%M Jas tJe ,rong signature
to -e an entry 5oint
Como se (e% la estructura de los mensajes de a(iso es mu+ similar a la de los mensajes
de error + slo se di&erencia de sta en )ue inclu+e ,arning en (ez de error tras el
indicador de posicin en el &uente* #ncluso como a estos% la opcin /+ullpaths
tam$in les a&ecta + pro(oca )ue se muestren las rutas de los &uentes al completo*
Kna di&erencia importante entre a(isos + errores es )ue la aparicin de mensajes de los
segundos durante la compilacin a$orta la generacin del $inario% mientras )ue la
aparicin de los primeros no Aaun)ue en am$os casos nunca se a$orta la compilacin
sino )ue tras mostrarlos se sigue analizando los &uentes por si pudiesen detectarse ms
errores + a(isosB A/ora $ien% tam$in puede &orzarse a )ue ello ocurra con los de a(iso
pasando al compilador el &lag /warnaserror% con lo )ue se conseguir.a )ue todo
mensaje de a(iso se muestrase como error* Ello puede resultar ,til por)ue &uerza a
escri$ir los &uentes de la manera ms &ia$le e inteligentemente posi$le*
En el laod opuesto% puede )ue /a+a ciertos tipos de mensajes de a(iso de los )ue no se
desea si)uiera )ue se in&orme en tanto )ue la in&ormacin )ue aportan +a se conoce + se
sa$e )ue no a&ectar negati(amente al programa* En esos casos puede usarse la opcin
/nowarn indicando como (alores su+os los cdigos asociados a los mensaje de a(iso
)ue no se desea )ue se reporten* El cdigo asociado a cada tipo de mensaje de a(iso se
es la pala$ra de la &orma C$:cBdigo= )ue se muestra tras ,arning en el mensaje de
a(iso* As.% para compilar el 5rue-a.cs del ejemplo anterior sin )ue se genere el
mensaje de a(iso arri$a mostrado puede /acerse3
csc 5rue-a.cs *no,arn+DI
En realidad los ceros incluidos a la iz)uierda del cdigo del a(iso en los mensajes de
a(iso son opcionales% por lo )ue la compilacin anterior es e)ui(alente a3
csc 5rue-a.cs *no,arn+DI
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
Si desea o$tener la lista completa de todos los tipos de mensaje de a(iso + error con sus
respecti(os cdigos puede consultar dentro de la documentacin del *4E5 Wrame=orI
SCD en (isual $tudio.N'T (isual Basic and (isual CQ (isual CQ
Language CQ Compiler *ptions Compiler 'rrors C$BBBA to C$JJJJ
Si en lugar de desacti(ar ciertos tipos de a(isos uno por uno desea desacti(arlos por
grupos seg,n su se(eridad% entonces puede /acerlo a tra(s de la opcin /warn* Esta
opcin toma como (alor un n,mero comprendido entre 2 + " )ue indica cul es el ni(el
de a(isos con el )ue se desea tra$ajar* Por de&ecto ste (ale "% lo )ue signi&ica )ue se
mostrarn todos los a(isos% pero puede drsele cual)uiera de los de la 5a$la 1T3
N7A1- 51 9A7;. AA7;.; ?.;3495.;
B
4inguno
A
Slo los ms gra(es
I
?os ms gra(es + algunos menos gra(es como por ejemplo los
relati(os a ocultaciones de miem$ros
P
?os de ni(el ms algunos poco gra(es como los relati(os al uso
de e-presiones a$surdas )ue siempre produzcan el mismo resultado
K
5odos
T9C-9 1*: 4i(eles de mensajes de a(iso
Si est interesado en conocer en concreto el ni(el de alg,n tipo de a(iso puede remitirse
a la descripcin so$re el mismo incluida en la documentacin del SCD antes comentada
Ficheros de respuesta
?a l.nea de comandos no es la ,nica &orma de pasar in&ormacin al compilador Atanto
&ic/eros a compilar como opciones de compilacinB% sino )ue tam$in es posi$le
almacenar in&ormacin de este tipo en un &ic/ero + pasrsele al compilador como
argumento solamente dic/o &ic/ero + no toda la in&ormacin en l contenida* Ce este
modo se &acilitar.a la la$or de pasar como parmetros las opciones de uso ms &recuente
+a )ue $astar.a slo indicar cul es el nom$re de un &ic/ero )ue las especi&ica*
A este &ic/eros se les llama @76J14.; 51 41;<01;39% +a )ue al pasrselos al compilador
su contenido puede (erse como la respuesta a cules son los argumentos a usar durante
la compilacin* ?a e-tensin de estos &ic/eros suele ser .rsp% + aun)ue nada o$liga a
drsela es con(eniente /acerlo como ocurre con todo con(enio*
Al compilar% por de&ecto el compilador siempre lee un &ic/ero de respuesta llamado
csc.rsp u$icado en el directorio del C?>% por lo )ue para entender cul es la sinta-is a
seguir para escri$ir estos &ic/eros nada mejor )ue (er cul es su contenido + as. de paso
sa$er cules son las opciones )ue por de&ecto se a1adiran a toda compilacin3
# This file contains command-line options that the C#
# command line compiler (CSC) will process as part
# of every compilation, unless the "/noconfig" option
# is specified.
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
# Reference the common Framework libraries
/r:Accessibility.dll
/r:Microsoft.Vsa.dll
/r:System.Configuration.nstall.dll
/r:System.Data.dll
/r:System.Design.dll
/r:System.DirectoryServices.dll
/r:System.dll
/r:System.Drawing.Design.dll
/r:System.Drawing.dll
/r:System.EnterpriseServices.dll
/r:System.Management.dll
/r:System.Messaging.dll
/r:System.Runtime.Remoting.dll
/r:System.Runtime.Serialization.Formatters.Soap.dll
/r:System.Security.dll
/r:System.ServiceProcess.dll
/r:System.Web.dll
/r:System.Web.RegularExpressions.dll
/r:System.Web.Services.dll
/r:System.Windows.Forms.Dll
/r:System.XML.dll
Cel contenido de este &ic/ero es &cil deducir )ue la estructura de los &ic/eros de
respuesta es sencilla3 cada opcin se inclu+e en una l.nea aparte + pueden intercalarse
entre ellas comentarios de una l.nea )ue comiencen con #* Adems% como puede (erse
este &ic/ero de respuesta usado por de&ecto a1ade re&erencias a las li$rer.as de la 0C?
de uso ms com,n% lo )ue e(ita tener )ue incluirlas constantemente al compilar*
5ras tomar las opciones de este &ic/ero% el compilador mira si en el directorio desde el
)ue se le llama /a+ otro csc.rsp + si es as. toma sus opciones* Si por alguna razn no
nos interesase )ue se tomasen las opciones de dic/os &ic/eros Apor ejemplo% para usar
nue(as (ersiones de tipos incluidos en las li$rer.as )ue re&erencianB $astar.a pasar el
&lag /nocon+ig al compilar para desacti(ar esta $,s)ueda por de&ecto en ellos% aun)ue
/a+ )ue se1alar )ue este &lag no admite los su&ijos + . admitidos por el resto de &lags*
En realidad% la estructura del &ic/ero de respuesta csc.rsp no es la ,nica posi$le% pues
adems de opciones tam$in es (lido incluir nom$res de &uentes a compilar e incluso
puede mezclarse m,ltiples opciones + nom$res de &uentes en cada l.nea del &ic/ero*
A/ora $ien% al escri$ir &ic/eros de respuesta /a+ )ue tener cuidado con dos cosas3 no es
posi$le cortar las opciones o nom$res de &ic/ero con retornos de carro )ue pro(o)uen
)ue ocupen (arias l.neasU + las opciones son pasadas al compilador en el mismo orden
en )ue aparezcan en el &uente% por lo )ue /a+ )ue tener cuidado con cmo se colo)uen
las opciones /out + /t por lo +a comentado so$re la importacia de su colocacin*
Kna (ez escrito un &ic/ero de respuesta% para indicar al compilador )ue /a de usarlo
$asta pasrselo como un nom$re de &uente ms pero precediendo su nom$re del su&ijo
-* Por ejemplo% para compilar ..cs usando las opciones almacenadas en o5c.rs5
/a$r.a )ue llamar al compilador con3
csc fopc*rsp A*rsp
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
5am$in ser.a posi$le indicar m,ltiples &ic/eros de respuesta% caso en )ue se tomar.an
las opciones de cada uno en el mismo orden en )ue apareciesen en la llamada a csc* Por
ejemplo% para compilar ..rs5 tomando las opciones de o5cC.rs5 + luego las de
o5cD.rs5 podr.a llamarse al compilador con3
csc Ho5cC.rs5 Ho5cD.rs5 ..rs5
Puede ocurrir )ue las opciones indicadas en un &ic/ero de respuesta contradigan a
opciones indicadas en otro &ic/ero de respuesta indicado a continuacin o a opciones
dadas al compilador en la l.nea de comandos* Para resol(er estas am$igaedades el
compilador siempre (a procesando los argumentos )ue se le pasen de iz)uierda a
derec/a + se )ueda con la ,ltima especi&icacin dada a cada opcin* As.% en el ejemplo
anterior las opciones del csc.rsp del directorio desde el )ue se le llam Zsi e-istieseX
tendr.a pre&erencia so$re las del csc.rsp del directorio del C?>% las de o5cD.rs5
tendr.an pre&erencia so$re las de ste% + las de o5cC.rs5 so$re las de o5cD.rs5*
5am$in pueden incluirse en los &ic/eros de respuesta opciones - )ue inclu+an a otros
&ic/eros de respuesta% con lo )ue se tomar.a sus opciones antes de continuar tomando las
siguientes del &ic/ero )ue lo inclu+% aun)ue o$(iamente nunca se admitir )ue un
&ic/ero incluido sea el mismo )ue el )ue lo inclu+e o )ue alguno )ue inclu+a a ste%
pues entonces se &ormar.an ciclos + nunca aca$ar.a la $,s)ueda de opciones*

Opciones de depuracin
Sin duda la opcin de depuracin ms importante es el &lag /debug% cu+a inclusin
indica al compilador )ue /a de generar un &ic/ero .pdb con in&ormacin so$re la
relacin entre el &ic/ero $inario generado + las l.neas de los &uentes a partir de los )ue
se gener* Esta in&ormacin es mu+ ,til para depurar aplicaciones% pues permite mostrar
la instruccin de cdigo &uente )ue produjo las e-cepciones en lugar de mostrar las
instrucciones de cdigo nati(o en )ue &ue traducida*
Para entender mejor la utilidad de este &ic/ero .pdb puede escri$ir el programa3
class A
{
public static void Main()
{throw new System.Exception();}
}
Si lo compila con3
csc ..cs
Al ejecutarlo se producir una e-cepcin + surgir una (entana de seleccin de
depurador* Si pulsa No en ella (er en la consola un mensaje como el siguiente3

Unhandled Exception: System.Exception: Exception of type System.Exception was thrown.
at A.Main()
Sin em$argo% si lo compila con3
csc ..cs *de-ug
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
Al ejecutarlo se o$tendr un mensaje muc/o ms detallado en el )ue se indicar cul es
la l.nea e-cta del cdigo &uente durante cu+a ejecucin se produjo la e-cepcin3
Unhandled Exception: System.Exception: Exception of type System.Exception was thrown
at A.Main() in E:\c#\Ej\A.cs:line 5
Como es &cil deducir% a partir de esta in&ormacin es &cil crear /erramientas de
depuracin Xcomo el depurador de ;isual Studio*4E5 o el C?> Ce$ugger del SCDX
)ue muestren la l.nea e-cta del cdigo &uente donde se produjo la e-cepcin lanzadaU +
o$(iamente estos datos tam$in pueden tener muc/os otros usos% como permitir ejecutar
paso a paso los programas mostrando en cada momento cul es la l.nea del &uente )ue se
ejecutar a continuacin + cosas similares*
5am$in puede usarse /debug como opcin con argumentos en (ez de cmo &lag% lo
)ue permite generar una (ersin recortada de la in&ormacin de depuracin* Si de esta
&orma se le da el (alor +ull &uncionar e-ctamente igual )ue al acti(arla como &lag%
pero si se le da el (alor pdbonly entonces la in&ormacin de depuracin generada slo
estar disponi$le para los depuradores desde los )ue se /a+a lanzado la aplicacin pero
no para los )ue se le /a+an adjuntado dinmicamente una (ez lanzada*
Por ,ltimo% respecto a la depuracin de aplicaciones con(iene se1alar )ue por de&ecto el
compilador siempre intenta generar el cdigo ms compacto + e&iciente posi$le% lo )ue
pro(oca )ue compile ms lentamente* Sin em$argo% como cuando se est depurando
suelen realizarse mmuc/as recompilaciones de los &uentes puede )ue en esos casos
interese desacti(ar dic/as optimizaciones + as. as. conseguir recompilar ms rpido*
Ello puede conseguirse llamando al compilador con /optimi1e8 A/o8B
CompiIacin incrementaI
?a 6.?<7-96782 72641?1239- consiste en slo recompilar en cada compilacin )ue se
/aga de un pro+ecto a)uellos mtodos cu+a de&inicin /a+a cam$iado respecto a la
,ltima compilacin realizada% con lo )ue el pro+ecto podr.a compilarse ms rpido )ue
/aciendo una compilacin completa normal*
Para )ue esto sea posi$le /acerlo /a+ )ue llamar al compilador con el &lag
/incremental A/incrB% lo )ue pro(ocar la generacin de un &ic/ero adicional con el
mismo nom$re )ue el $inario generado ms una e-tensin .incr* Por ejemplo% dado3
csc *out+<uente.e$e *incremental Guente.cs
Se generar un ejecuta$le <uente.e$e + un &ic/ero adicional <uente.e$e.incr*
Aun)ue pueda parecer redundante incluir en el ejemplo la opcin /out al llamar al
compilador% es necesaria por)ue al menos en la (ersin del compilador incluida en la
$eta del es o$ligatorio especi&icarla siempre )ue se utilice /incr*
El &ic/ero .incr generado inclu+e in&ormacin so$re la compilacin )ue permitir )ue
posteriores compilaciones )ue se realicen con /incr acti(ado puedan /acerse de
manera incremental* L$(iamente% si este &ic/ero se elimina ser reconstruido en la
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
siguiente compilacin )ue se /aga con /incr% pero dic/a compilacin no se realizar de
manera completa por no disponerse del &ic/ero .incr durante ella*
Sin em$argo% el /ec/o de )ue est disponi$le un &ic/ero .incr al compilar un pro+ecto
no implica )ue se use% pues el compilador puede ignorarlo + realizar una compilacin
completa si detecta )ue /an cam$iado las opciones de compilacin especi&icadas o si
detecta )ue los &uentes /an cam$iado tanto )ue es al menos igual de e&iciente /acerla as.
)ue de manera incremental*
En realidad no es $ueno /acer siempre las compilaciones incrementalmente sino )ue
slo es ,til /acerlo en pro+ectos &ormados por m,tilples &uentes de pe)ue1o tama1o%
minetras )ue en pro+ectos con pocos + grandes &ic/eros se gana poco o nada en tiempo
de compilacin* Adems% los ejecuta$les generados incrementalmente pueden ocupar
ms )ue los generados por compilacin completa% por lo slo es recomenda$le compilar
incrementalmente las (ersiones de prue$a de los pro+ectos pero no las de&initi(as*
Opciones reIativas aI Ienguaje
A lo largo de los anteriores temas se /a ido diseminando di(ersas opciones de
compilacin relacionadas de manera ms o menos directa con el lenguaje C#* En este
punto /aremos recapitulacin de todas ellas mismas + las resumiremos3
/de+ine A/dB3 En el Tema &: El prepro$esador +a se introdujo esta opcin cu+os
(alores recordemos )ue se utilizan para introducir de&iniciones de s.m$olos de
preprocesado al principio de todos los &uentes a compilar*
Por ejemplo% si se desea compilar los &uentes ..cs + 1.cs como si al principio de
ellos se /u$iese incluido las directi(as de preprocesado #define PRUEBA + #define
VERSON1 podr.a llamarse al compilador con3
csc *d+4>?@1.&)@>S;/YC ..cs 1.cs
/chec@ed3 En los temas " + 1T se e-plic )ue todo des$ordamiento )ue ocurra en
operaciones aritmticas entre (aria$les enteras es tratado por de&ecto truncando el
resultado* Pues $ien% la utilidad de acti(ar esta opcin es precisamente &orzar a )ue
se inclu+an en el cdigo generado las compro$aciones necesarias para )ue en caso
de des$ordamiento se lance en su lugar una System.OverfIowException*
L$(iamente el cdigo compilado con /chec@ed se ejecutar ms lento )ue el )ue lo
/aga sin ella +a )ue incluir compro$aciones de des$ordamiento adicionales* Sin
em$ago% a cam$io con ello se consigue detectar con &acilidad errores deri(ados de
des$ordamientos )ue de otra manera podr.an pasar inad(ertidos*
/unsafe3 En el Tema %8: C)di(o inse(#ro +a se e-plic )ue la ,nica utilidad de esta
opcin es ser(ir al compilador de mecanismo de seguridad gracias al )ue pueda
asegurarse de )ue el usario sa$e lo )ue /ace al compilar cdigo con punteros*
/doc3 Esta opcin +a se introdujo en el Tema %:: Do$#menta$i)n ;M+% donde se
e-plic )ue se usa para indicar al compilador )ue es desea generar un &ic/ero S6?
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
con el contenido de los comentarios de documentacin incluidos en los &uentes a
compilar* El nom$re de ese &ic/ero ser el )ue se d como (alor a esta opcin*
Al usar esta opcin /a+ )ue tener en cuenta una cosa% + es )ue para optimizar el
tiempo )ue se tarda en realizar compilaciones incrementales% durante ellas esta
opcin es ignorada* Por tanto% no tiene muc/o sentido com$inar /doc + /incr*
Otras opciones
Aparte de las opciones comentadas% csc admite unas cuantas ms a,n no descritas +a
sea por)ue su uso es mu+ poco &recuente o por)ue no encajan correctamente en ninguno
de los su$ep.gra&es tratados* 5odas estas opciones se recogen &inalmente a)u.3
/+ilealign3 ?os (alores dados a esta opcin indican el tama1o de las secciones en
)ue se di(idirn los &ic/eros $inarios resultantes de la compilacin* Puede tomar los
(alores Q1% 12"% 2"R% "2:T% R1: 1T!R"% + cada seccin en los $inarios
comenzar en un posicin )ue sea m,ltiplo del (alor dado a esta opcin*
Por de&ecto el (alor )ue se le d puede (ariar dependiendo de la implementacin )ue
se /aga del C?>% aun)ue darle un (alor a medida puede ser ,til en el dise1o de
aplicaciones para dispositi(os empotrados con escasa capacidad de almacenamiento
+a )ue puede reducir el tama1o de los &ic/eros generados*
/bugreport3 Cado )ue es mu+ di&.cil dise1ar un compilador 122P li$re de errores%
6icroso&t proporciona a tra(s de esta opcin un mecanismo )ue &acilita a los
usuarios el en(.o de in&ormacin so$re los errores )ue descu$ran en el mismo +
&acilita a 6icroso&t la la$or de interpretarla para solucionarlos lo antes posi$le*
El (alor )ue se d a esta opcin es el nom$re de con el )ue se desea )ue se genere el
&ic/ero con la in&ormacin relati(a al error descu$ierto durante la compilacin* En
dic/o &ic/ero csc insertar automticamente la siguiente in&ormacin3
Lpciones de compilacin utilizadas*
;ersin del compilador% C?> + sistema operati(o usado*
Copia de todos los cdigos &uentes compilados* Como es lgico% para &acilitar la
correcin a 6icroso&t se recomienda en(iar el programa ms compacto posi$le
en el )ue se produzca el error descu$ierto*
6ensajes de salida mostrados durante la compilacin*
Aparte de toda esta in&ormacin insertada automticamente por el compilador%
durante la generacin del &ic/ero de error tam$in se pedir al usuario )ue indi)ue
una pe)ue1a descripcin so$re el error detectado + cmo cree )ue podr.a
solucionarse* Cic/a in&ormacin tam$in ser a1adida de manera automtica al
&ic/ero de error )ue se cree*
Kn ejemplo cmo generar in&ormacin relati(a a un error (er.dico )ue se produce al
compilar un programa error*cs con la 0eta 1 del *4E5 SCD Wrame=orI es3
csc error.cs *-ugre5ort+@rror?sing.cs
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
5ras constestar a las preguntas )ue el compilador /ar al usuario so$re el error
encontrado% el contenido del &ic/ero generado es el siguiente3
### C# Compiler Defect Report, created 07/12/00 20:14:36
### Compiler version: 7.00.9030
### Common Language Runtime version: 1.00.2914.16
### Operating System: Windows NT 5.0.2195 Service Pack 2
### User Name: Administrador
### Compiler command line
csc.exe error.cs /bugreport:ErrorUsing.cs
### Source file: 'e:\c#\ej\error.cs'
using System;
public class R1:Disposable
{
public static void Main()
{
using (R1 r1 = new R1())
{
}
}
public void Dispose()
{}
}
### Compiler output
error.cs(7,3): error CS1513: } expected
error.cs(7,26): error CS1002: ; expected
error.cs(12,9): error CS1518: Expected class, delegate, enum, interface, or struct
error.cs(14,1): error CS1022: Type or namespace definition, or end-of-file expected
### User description
No detecta la instruccion using
### User suggested correct behavior
Posiblemente no haya sido implementada en esta version del compilador
4tese )ue aun)ue el error detectado en el ejemplo es (er.dico% en (ersiones del
compilador posteriores a la 0eta 1 no se produce por)ue +a &ue corregido*
/baseaddress3 Esta opcin slo tiene sentido cuando se solicita la generacin
de una li$rer.a e indica cul es la direccin de memoria en )ue se pre&iere )ue
sta se cargue cuando sea enlazada dinmicamente* 4tese )ue se /a dic/o
li$rer.a% pues si el &ic/ero generado es de cual)uier otro tipo ser ignorada*
El (alor )ue se d a esta opcin puede indicarse tanto en /e-adecimal como en
octal o decimal siguiendo las reglas usadas en C# para la escritura de literales
enteros* Sin em$argo% /a+ )ue tener en cuenta )ue los $its menos signi&icati(os
de esta direccin pueden ser redondeados* Por ejemplo% si escri$imos3
csc <icJero.cs *-aseaddress+$CCCCC
El compilador tratar esta llamada tal + como si se le /u$iese pasado3
csc <icJero.cs *-aseaddress+$CCCC
Si no se da (alor a esta opcin% las li$rer.as se instalarn en el rea de memoria
)ue se estime con(eniente en cada implementacin del C?>*
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
/codepage3 Por de&ecto el compilador acepta &uentes escritos en Knicode% K5WX
R o usando la pgina de cdigos por de&ecto del sistema operati(o* Si se desea
compilar &uentes escritos en otras pginas de cdigo /a+ )ue indicar como (alor
de esta opcin el identi&icador de ella*
Kn uso t.pico de esta opcin es permitir compilar &uentes escritos en espa1ol con
un editor de te-tos de 6SXCLS Acomo edit.comB% caso en )ue /a+ )ue darle el
(alor V(X para )ue acepte los caracteres especiales tales como acentos o e1es*
/ut+Noutput3 Su inclusin indica )ue el compilador /a de mostrar los mensajes
usando el juego de caracteres K5WXR% lo )ue es ,til cuando se utilizan ciertos
sistemas operati(os internacionales en los )ue por de&ecto no se muestren
correctamente dic/os mensajes por la (entana de consola*
Para poder leerla en esos casos se recomienda usar este &lag al compilar +
redirigir la salida a un &ic/ero como muestra el siguiente ejemplo donde se
compila ..cs redirigiendo los mensajes de compilacin a salida.t$t y
mostrndolos en K5WXR3
csc ..cs *ut<Iout5ut = salida.t$t
/help A/RB3 6uestra un mensaje de a+uda resumiendo cules son las opciones
admitidas por el compilador + para )u sir(en* 5oda opcin o &ic/ero a compilar
especi&icado junto opcin son totalmente ignorados*
/nologo3 #ndica )ue no se desea )ue al ejecutar el compilador se genere el
mensaje )ue inclu+e in&ormacin so$re la (ersin del compilador + el cop+rig/t
de 6icroso&t so$re el mismo )ue por de&ecto se muestra*
Suele usarse cuando la compilacin se solicita desde una aplicacin o &ic/ero de
procesamiento por lotes% pues oculta la ejecucin del compilador al usuario +
ello puede (enir $ien para e(itar )ue ste conozca cmo &unciona la aplicacin o
para conseguir un &uncionamiento ms elegante + transparente de la misma*
4cceso al compilador desde 3isual "tudio.NET
Como se e-plic en su momento en el Tema 8: "ntrod#$$i)n a C9% a las opciones de
compilacin de un pro+ecto se accede desde ;S*4E5 a tra(s de las pginas de
propiedades del mismo% las cuales tiene el aspecto mostrado en la #lustracin : + se
o$tienen seleccionando el pro+ecto en el $olution 'xplorer + pulsando so$re (iew
Property Pages en el men, principial de ;isual Studio*
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
I-0;3496782 +: Pginas de propiedades del pro+ecto en ;isual Studio*4E5
Para la ma+or.a de opciones admitidas por csc*e-e se inclu+e en estas pginas controles
tales como cajas de te-to + listas desplega$les )ue permiten con&igurarlas de una
manera (isual% cmoda e intuiti(a* En la 5a$la 1[ se resume en orden al&a$tico cul es
el control )ue en concreto se asocia en estas pginas a cada opcin3
O<6782 C.234.- A7;09-
J$aseaddress
Con&iguration Properties Ad(anced 0ase Address
Jc/ecIed
Con&iguration Properties 0uild C/ecI &or Arit/metic
L(er&lo=JKnder&lo=
Jde$ug
Con&iguration Properties 0uild Generate Ce$ugging #n&ormation
Jde&ine
Con&iguration Properties 0uild Conditional Compilation
Constants
Jdoc
Con&iguration Properties 0uild S6? Cocumentation Wile
J&ilealign
Con&iguration Properties 0uild Wile Alignment
Jincremental
Con&iguration Properties Ad(anced #ncremental 0uild
Jmain
Common Properties General Startup L$ject
Joptimize
Con&iguration Properties 0uild Lptimize code
Jout
Common Properties General Assem$l+ 4ame
Jtarget
Common Properties General Lutput 5+pe
Junsa&e
Con&iguration Properties 0uild Allo= unsa&e code $locIs
J=arn
Con&iguration Properties 0uild Harning ?e(el $locIs
J=arnaserror
Con&iguration Properties 0uild 5reat Harnings As Errors
J=in!icon
Common Properties General Application #con
T9C-9 1!: Controles asociados a opciones de compilacin
Como puede o$ser(ar% desde ;S*4E5 no es posi$le acceder a muc/as de las opciones
del compilador en l.nea de comandos* En los casos de /codepage, /+ullpaths, /lib,
El lenguaje de programacin C# 5ema 23 El compilador de C# de
6icroso&t
/help, /nologo, /recurse + /ut+Noutput esto es lgico +a )ue son opciones )ue
pierden su sentido desde dentro en una inter&az gr&ica* 8a+ otros casos en )ue ello se
de$e a )ue se o&recen desde el men, principal de ;S*4E5 otros mecanismos
alternati(os para especi&icarlas% como son los indicados en la 5a$la 1R3
O<6782 M16927;?. 51 9661;.
J$ugreport
8elp Customer Weed$acI
Jresource
Seleccionar el recurso en Project Add E-isting #tem
Jre&erence
Seleccionar la re&erencia en Project Add >e&erence
T9C-9 18: Acceso a opciones &uera de las pginas de propiedades
Winalmente% )ueda un grupo de opciones )ue no disponi$les simplemente por)ue la
implementacin de ;S*4E5 Aal menos en la 0eta B no las contempla% + son f%
/lin@resource% /nostdlib% /nocon+ig% /nowarn + /winPIres* En este sentido%
mencin aparte merece el (alor module de /t% )ue tampoco puede usarse en tanto )ue
;S*4E5 no soporta el tra$ajo con mdulos*
El lenguaje de programacin C# Cocumentacin de re&erencia
Documentacin de referencia
$ibliograf#a
En el momento de escri$ir estas l.neas no /a+ disponi$le ninguna otra $i$liogra&.a de
calidad so$re C# escrita en castellano% sino )ue toda la disponi$le lo est en ingls*
Entre las &uentes de in&ormacin so$re C# en ingls ca$e destacar el documento NC#
?anguage Speci&icationN escrito por Anders 8ejls$erg% Scott Hiltamut/ + Peter Golde
)ue 6icroso&t /a remitido al EC6A para la estandarizacin del lenguaje* Este
documento inclu+e la especi&icacin completa del mismo + 6icroso&t permite
descargarlo gratuitamente desde la direccin /ttp3JJ===*msdn*microso&t*comJnetJecma*
Sin em$argo% si lo )ue $usca son li$ros )ue e-pli)uen el lenguaje con algo menos de
rigurosidad pero de manera muc/o ms &cil de entender + aplicar% entonces puede
consutlar la siguiente $i$liogra&.a3
NA programmerds introduction to C#O escrito por Eric Gunnerson + pu$licado por
Apress en 222*
C# and t/e *4E5 Wrame=orIO% escrito por Andre= 5roelsen + pu$licado por Apress
en 221
NC# EssentialsO% escrito por 0e$ Al$a/ari% Peter Cra+ton + 0rand 6erril +
pu$licado por Ld>eill+ en 222*
NC# Programming =it/ t/e Pu$lic 0etaO% escrito por 0urton 8ar(e+% Simon
>o$inson% Julian 5empleman + Darli Hatson + pu$licado por Hro- Press en 222*
N#nside C#O% escrito por 5om Arc/er + pu$licado por 6icroso&t en 222
NPresenting C#O% escrito por C/ristop/ Hille + pu$licado por Sams Pu$lis/ing en
222*
NPro&essional C#O% escrito por Simon >o$inson% 0urt 8ar(e+% Craig 6cMueen%
C/ristian 4agel% 6organ SIinner% Ja+ Gl+nn% Darli Hatson% Lllie Cornes% Jerod
6oemeIa + pu$licado por Hro- Press en 221*
NProgramming C#O% escrito por Jesse ?i$ert+ + pu$licado por Ld>eill+ en 221
Ce entre todos estos li$ros )uizs el principalmente recomenda$le tras leer esta o$ra
pueda ser NPro&essional C#O% pues es el ms moderno + a$arca numerosos conceptos
so$re la aplicacin de C# para acceder a la 0C?*
Por otra parte% en relacin con los li$ros pu$licados en 222 /a+ )ue se1alar )ue &ueron
pu$licados para el compilador de C# incluido en la 0eta 1 del SCD% por lo )ue no tratan
los aspectos nue(os introducidos a partir de la 0eta + puede )ue contengan cdigo de
ejemplo )ue /a+a )uedado o$soleto + actualemente no &uncione*
!nformacin en !nternet sobre C(
El lenguaje de programacin C# Cocumentacin de re&erencia
Aun)ue la $i$liogra&.a pu$licada so$re C# al escri$ir estas l.neas es relati(amente
escasa% no ocurre lo mismo con la cantidad de material online disponi$le% )ue cada (ez
(a inundando ms la >ed* En esta seccin se recogen los principales portales% grupos de
noticias + listas de distri$ucin dedicados al lenguaje* Seguramente cuando lea estas
l.neas /a$rn surgido muc/os ms% puede usar la lista o&recida para encontrar enlaces a
los nue(os a partir de los )ue a)u. se recogen*

,ortales
Si $usca un portal so$re C# escrito en castellano el ,nico )ue le puedo recomendar es
NEl >incn en Espa1ol de C#O A/ttp3JJtdg*lsi*us*esJgcs/arpB% )ue es el primero dedicado
a este lenguaje escrito en castellano* 8a sido desarrollado por pro&esores de la Wacultad
de #n&ormtica + Estad.stica de Se(illa% + entre los ser(icios )ue o&rece ca$e destacar
sus aplicaciones de ejemplo% WAM% seminario NonXlineO + lista de distri$ucin de correo*
Si no le importa )ue el portal est en ingls% entonces es de o$ligada (isita el N*4E5
Ce(elopers CenterO A/ttp3JJ===*msdn*microso&t*comJnetB de 6icroso&t% +a )ue al ser
los creadores del C# + la plata&orma *4E5 su in&ormacin so$re los mismos suele ser la
ms amplia% &ia$le + actualizada* Entre los ser(icios )ue o&rece ca$e destacar la
posi$ilidad de descargar gratuitamente el *4E5 Wrame=orI SCD + ;isual Studio
*4E5
1:
% sus numerosos (.deos + art.culos tcnicos% + sus ejemplos de desarrollo de
so&t=are pro&esional de calidad usando estas tecnolog.as*
Aparte del portal de 6icroso&t% otros portales dedicados a C# )ue pue$lan la >ed son3
NC# CornerO A/ttp3JJ===*cXs/arpcorner*comB
NC# 8elpOA/ttp3JJ===*cs/arp/elp*comB
NC# StationO A/ttp3JJ===*cs/arpXstation*comB
NCode/ound C#O A/ttp3JJ===*code/ound*comJcs/arpB
Ncs/arpinde-*comO A/ttp3JJ===*cs/arpinde-*comB
NCe(elopersde-O A/ttp3JJ===*de(elopersde-*comJcs/arpB
N*4E5 HireO A/ttp3JJ===*dotnet=ire*comB
:rupos de noticias % listas de correo
6icroso&t /a puesta a disposicin de los desarrolladores numerosos grupos de noticias
dedicados a resol(er dudas so$re C#% *4E5 + ;isual Studio*4E5* ?os o&recidos en
castellano son3
microso&t*pu$lic*(snet
microso&t*pu$lic*es*cs/arp
1:
El ,ltimo slo para su$scriptores 6SC4 Kni(ersal% aun)ue los no su$criptores pueden pedirlo en este
portal gratuitamente + 6icroso&t se lo en(iar por correo ordinario*
El lenguaje de programacin C# Cocumentacin de re&erencia
>especto a los proporcionados en ingls% se1alar )ue aun)ue algunos de ellos se recogen
en la opcin *nline Community de la pgina de inicio de ;S*4E5% la lista completa
d.a a d.a crece cada (ez ms + en el momento de escri$ir estas l.neas era3
microso&t*pu$lic*dotnet*academic
microso&t*pu$lic*dotnet*distri$utedhapps
microso&t*pu$lic*dotnet*&a)s
microso&t*pu$lic*dotnet*general
microso&t*pu$lic*dotnet*&rame=orI
microso&t*pu$lic*dotnet*&rame=orI*adonet
microso&t*pu$lic*dotnet*&rame=orI*aspnet
microso&t*pu$lic*dotnet*&rame=orI*aspnet*mo$ile
microso&t*pu$lic*dotnet*&rame=orI*aspnet*=e$ser(ices
microso&t*pu$lic*dotnet*&rame=orI*clr
microso&t*pu$lic*dotnet*&rame=orI*componenthser(ices
microso&t*pu$lic*dotnet*&rame=orI*documentation
microso&t*pu$lic*dotnet*&rame=orI*interop
microso&t*pu$lic*dotnet*&rame=orI*od$cnet
microso&t*pu$lic*dotnet*&rame=orI*per&omance
microso&t*pu$lic*dotnet*&rame=orI*remoting
microso&t*pu$lic*dotnet*&rame=orI*sdI
microso&t*pu$lic*dotnet*&rame=orI*setup
microso&t*pu$lic*dotnet*&rame=orI*=indo=s&orms
microso&t*pu$lic*dotnet*languages*cs/arp
microso&t*pu$lic*dotnet*languages*jscript
microso&t*pu$lic*dotnet*languages*($
microso&t*pu$lic*dotnet*languages*($*upgrade
microso&t*pu$lic*dotnet*languages*(c
microso&t*pu$lic*dotnet*languages*(c*li$raries
microso&t*pu$lic*dotnet*samples
microso&t*pu$lic*dotnet*scripting
microso&t*pu$lic*dotnet*(sa
microso&t*pu$lic*dotnet*-ml
microso&t*pu$lic*(snet*de$uggin
microso&t*pu$lic*(snet*documentation
microso&t*pu$lic*(snet*enterprise*tools
microso&t*pu$lic*(snet*&a)s
microso&t*pu$lic*(snet*general
microso&t*pu$lic*(snet*ide
microso&t*pu$lic*(snet*samples
microso&t*pu$lic*(snet*ser(icepacIs
microso&t*pu$lic*(snet*setup
microso&t*pu$lic*(snet*(isualhstudiohmodeler
microso&t*pu$lic*(snet*(sa
microso&t*pu$lic*(snet*(sip
El lenguaje de programacin C# Cocumentacin de re&erencia
microso&t*pu$lic*(snet*(ss
En realidad% de entre todos estos grupos de noticias slo estn e-clusi(amente dedicados
a C# ?764.;.@3.<0C-76.1; + 6;J94< ?764.;.@3.<0C-76.5.3213.-92=09=1;.6;J94<% pero a
medida )ue (a+a adentrandose en el lenguaje descu$rir )ue los dedicados a los
di&erentes aspectos de *4E5 + ;S*4E5 tam$in le resultarn de incalcula$le utililidad*
En lo re&erente a listas de correo% si $usca una lista en castellano la ms recomenda$le
es la del N>incn en Espa1ol de C#O A/ttp3JJtdg*lsi*us*esJcs/arpB antes mencionadaU
mientras )ue si no le importa )ue estn en ingls% entonces puede consultar las o&recidas
por NCe(elop6entorO A/ttp3JJ===*discuss*de(elop*comB

Potrebbero piacerti anche