Está en la página 1de 538

C

#
Especificacin del lenguaje
Versin 3.0
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Enve correcciones, coentarios y c!al"!ier otra s!gerencia a sharp#icrosoft.co
$viso
1999-2008 Microsoft Corporation. Reservados todos los derechos.
Microsoft, Windows, Visal !asic, Visal C" # Visal C$$ son %arcas re&istradas o %arcas co%erciales de Microsoft
Corporation en los ''.((. #)o en otros pa*ses o re&iones.
+os de%,s prodctos # no%-res de co%pa.*as %encionados en esta p-licaci/n peden ser %arcas co%erciales de ss
respectivos propietarios.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
Tabla de contenido
1. Introduccin....................................................................................................................................................1
1.1 Hola a todos.................................................................................................................................................1
1.2 Estructura del programa...............................................................................................................................2
1.3 Tipos y variables.........................................................................................................................................4
1.4 Expresiones.................................................................................................................................................8
1. !nstrucciones..............................................................................................................................................1"
1.# Clases y ob$etos.........................................................................................................................................14
1.#.1 %iembros............................................................................................................................................14
1.#.2 &ccesibilidad......................................................................................................................................1
1.#.3 'ar(metros de tipo...............................................................................................................................1
1.#.4 Clases base..........................................................................................................................................1#
1.#. Campos...............................................................................................................................................1#
1.#.# %)todos..............................................................................................................................................1*
1.#.#.1 'ar(metros.....................................................................................................................................1*
1.#.#.2 Cuerpo del m)todo y variables locales..........................................................................................1+
1.#.#.3 %)todos est(ticos y de instancia....................................................................................................1+
1.#.#.4 %)todos virtuales, de invalidaci-n y abstractos............................................................................2"
1.#.#. .obrecarga de m)todos..................................................................................................................22
1.#.* /tros miembros de 0unci-n.................................................................................................................23
1.#.*.1 Constructores.................................................................................................................................2
1.#.*.2 'ropiedades...................................................................................................................................2
1.#.*.3 !ndi1adores....................................................................................................................................2#
1.#.*.4 Eventos..........................................................................................................................................2#
1.#.*. /peradores....................................................................................................................................2*
1.#.*.# 2estructores...................................................................................................................................2*
1.* Estructuras.................................................................................................................................................28
1.8 %atrices.....................................................................................................................................................2+
1.+ !nter0aces...................................................................................................................................................3"
1.1" Enumeraciones........................................................................................................................................31
1.11 2elegados................................................................................................................................................33
1.12 &tributos..................................................................................................................................................34
2. Estructura lxica...........................................................................................................................................36
2.1 'rogramas..................................................................................................................................................3#
2.2 3ram(ticas.................................................................................................................................................3#
2.2.1 4otaci-n gramatical............................................................................................................................3#
2.2.2 3ram(tica l)xica.................................................................................................................................3*
2.2.3 3ram(tica sint(ctica............................................................................................................................3*
2.3 &n(lisis l)xico...........................................................................................................................................38
2.3.1 Terminadores de l5nea.........................................................................................................................38
2.3.2 Comentarios........................................................................................................................................3+
2.3.3 Espacio en blanco...............................................................................................................................4"
2.4 To6ens.......................................................................................................................................................4"
2.4.1 .ecuencias de escape de caracteres 7nicode.......................................................................................4"
2.4.2 !denti0icadores....................................................................................................................................41
2.4.3 'alabras clave.....................................................................................................................................43
2.4.4 8iterales..............................................................................................................................................44
2.4.4.1 8iterales booleanos........................................................................................................................44
2.4.4.2 8iterales enteros............................................................................................................................44
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. iii
Especificacin del lenguaje C#
2.4.4.3 8iterales reales...............................................................................................................................4
2.4.4.4 8iterales de car(cter.......................................................................................................................4#
2.4.4. 8iterales de cadena........................................................................................................................4*
2.4.4.# El literal null..................................................................................................................................4+
2.4. /peradores y signos de puntuaci-n.....................................................................................................4+
2. 2irectivas de preprocesamiento.................................................................................................................4+
2..1 .5mbolos de compilaci-n condicional.................................................................................................1
2..2 Expresiones de preprocesamiento.......................................................................................................1
2..3 2irectivas de declaraci-n....................................................................................................................2
2..4 2irectivas de compilaci-n condicional...............................................................................................3
2.. 2irectivas de diagn-stico....................................................................................................................
2..# 2irectivas de regi-n............................................................................................................................#
2..* 2irectivas de l5nea...............................................................................................................................#
2..8 2irectivas pragma...............................................................................................................................*
2..8.1 'ragma 9arning.............................................................................................................................*
3. Conceptos bsicos..........................................................................................................................................!"
3.1 !nicio de la aplicaci-n................................................................................................................................+
3.2 :inali1aci-n de la aplicaci-n.....................................................................................................................#"
3.3 2eclaraciones............................................................................................................................................#"
3.4 %iembros..................................................................................................................................................#3
3.4.1 %iembros de espacio de nombres.......................................................................................................#3
3.4.2 %iembros de estructura.......................................................................................................................#3
3.4.3 %iembros de enumeraciones...............................................................................................................#4
3.4.4 %iembros de clase..............................................................................................................................#4
3.4. %iembros de inter0a1..........................................................................................................................#4
3.4.# %iembros de matri1............................................................................................................................#4
3.4.* %iembros de delegados......................................................................................................................#4
3. &cceso a miembros....................................................................................................................................#4
3..1 &ccesibilidad declarada......................................................................................................................#
3..2 2ominios de accesibilidad..................................................................................................................#
3..3 &cceso protegido para miembros de instancia....................................................................................#8
3..4 ;estricciones de accesibilidad.............................................................................................................#+
3.# :irmas y sobrecargas.................................................................................................................................*"
3.* <mbitos.....................................................................................................................................................*1
3.*.1 /cultar nombres..................................................................................................................................*4
3.*.1.1 /cultar mediante anidaci-n...........................................................................................................*
3.*.1.2 /cultar mediante =erencia.............................................................................................................*
3.8 Espacios de nombres y nombres de tipos...................................................................................................**
3.8.1 4ombres completos............................................................................................................................*+
3.+ &dministraci-n autom(tica de la memoria................................................................................................8"
3.1" /rden de e$ecuci-n..................................................................................................................................83
#. Tipos...............................................................................................................................................................$#
4.1 Tipos de valor............................................................................................................................................84
4.1.1 Tipo .ystem.>alueType......................................................................................................................8
4.1.2 Constructores predeterminados...........................................................................................................8
4.1.3 Tipos de estructura..............................................................................................................................8#
4.1.4 Tipos simples......................................................................................................................................8#
4.1. Tipos integrales...................................................................................................................................8*
4.1.# Tipos de punto 0lotante.......................................................................................................................8+
i% Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
4.1.* Tipo decimal.......................................................................................................................................+"
4.1.8 Tipo bool.............................................................................................................................................+"
4.1.+ Tipos de enumeraci-n.........................................................................................................................+1
4.1.1" Tipos ?ue aceptan valores 4788......................................................................................................+1
4.2 Tipos de re0erencia....................................................................................................................................+1
4.2.1 Tipos de clase......................................................................................................................................+2
4.2.2 Tipo ob$ect..........................................................................................................................................+3
4.2.3 Tipo string...........................................................................................................................................+3
4.2.4 Tipos de inter0a1.................................................................................................................................+3
4.2. Tipos de matri1...................................................................................................................................+3
4.2.# Tipos de delegados..............................................................................................................................+3
4.3 Conversiones boxing y unboxing..............................................................................................................+3
4.3.1 Conversiones boxing...........................................................................................................................+3
4.3.2 Conversiones 7nboxing......................................................................................................................+
4.4 Tipos construidos......................................................................................................................................+#
4.4.1 &rgumentos de tipo.............................................................................................................................+*
4.4.2 Tipos cerrados y abiertos....................................................................................................................+*
4.4.3 Tipos enla1ados y sin enla1ar..............................................................................................................+*
4.4.4 Cumplimiento de las restricciones......................................................................................................+8
4. 'ar(metros de tipo.....................................................................................................................................++
4.# Tipos de (rbol de expresiones..................................................................................................................1""
!. &ariables......................................................................................................................................................1'1
.1 Categor5as de variables............................................................................................................................1"1
.1.1 >ariables est(ticas.............................................................................................................................1"1
.1.2 >ariables de instancia.......................................................................................................................1"1
.1.2.1 >ariables de instancia en clases...................................................................................................1"2
.1.2.2 >ariables de instancia en estructuras...........................................................................................1"2
.1.3 Elementos matriciales.......................................................................................................................1"2
.1.4 'ar(metros de valor...........................................................................................................................1"2
.1. 'ar(metros de re0erencia...................................................................................................................1"2
.1.# 'ar(metros de salida..........................................................................................................................1"3
.1.* >ariables locales...............................................................................................................................1"3
.2 >alores predeterminados.........................................................................................................................1"4
.3 Estado de asignaci-n de0initiva...............................................................................................................1"4
.3.1 >ariables asignadas inicialmente......................................................................................................1"
.3.2 >ariables no asignadas inicialmente.................................................................................................1"#
.3.3 ;eglas precisas para determinar asignaciones de0initivas.................................................................1"#
.3.3.1 ;eglas generales para instrucciones.............................................................................................1"#
.3.3.2 !nstrucciones de blo?ues e instrucciones c=ec6ed y unc=ec6ed...................................................1"*
.3.3.3 !nstrucciones de expresiones.......................................................................................................1"*
.3.3.4 !nstrucciones de declaraci-n........................................................................................................1"*
.3.3. !nstrucciones !0............................................................................................................................1"*
.3.3.# !nstrucciones .9itc=....................................................................................................................1"8
.3.3.* !nstrucciones @=ile.....................................................................................................................1"8
.3.3.8 !nstrucciones 2o..........................................................................................................................1"8
.3.3.+ !nstrucciones :or.........................................................................................................................1"8
.3.3.1" !nstrucciones Area6, Continue y 3oto.......................................................................................1"+
.3.3.11 !nstrucciones T=ro9..................................................................................................................1"+
.3.3.12 !nstrucciones ;eturn..................................................................................................................1"+
.3.3.13 !nstrucciones TryBcatc=.............................................................................................................1"+
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. %
Especificacin del lenguaje C#
.3.3.14 !nstrucciones TryB0inally...........................................................................................................11"
.3.3.1 !nstrucciones TryB0inallyBcatc=..................................................................................................11"
.3.3.1# !nstrucciones :oreac=................................................................................................................111
.3.3.1* !nstrucciones 7sing...................................................................................................................111
.3.3.18 !nstrucciones 8oc6.....................................................................................................................111
.3.3.1+ !nstrucciones yield.....................................................................................................................112
.3.3.2" ;eglas generales para expresiones simples................................................................................112
.3.3.21 ;eglas generales para expresiones con expresiones incrustadas................................................112
.3.3.22 Expresiones de invocaci-n y expresiones de creaci-n de ob$etos..............................................112
.3.3.23 Expresiones de asignaci-n simples............................................................................................113
.3.3.24 Expresiones CC........................................................................................................................113
.3.3.2 Expresiones DD.............................................................................................................................114
.3.3.2# Expresiones E.............................................................................................................................11
.3.3.2* Expresiones FF...........................................................................................................................11
.3.3.28 Expresiones FG............................................................................................................................11#
.3.3.2+ :unciones an-nimas..................................................................................................................11#
.4 ;e0erencias de variables..........................................................................................................................11*
. &tomicidad de las re0erencias de variable...............................................................................................11*
6. Con%ersiones................................................................................................................................................11$
#.1 Conversiones impl5citas...........................................................................................................................118
#.1.1 Conversiones de identidad................................................................................................................118
#.1.2 Conversiones num)ricas impl5citas...................................................................................................118
#.1.3 Conversiones de enumeraci-n impl5citas..........................................................................................11+
#.1.4 Conversiones impl5citas ?ue aceptan valores 4788.........................................................................11+
#.1. Conversiones de literal 4788..........................................................................................................12"
#.1.# Conversiones de re0erencia impl5citas...............................................................................................12"
#.1.* Conversiones boxing.........................................................................................................................12"
#.1.8 Conversiones impl5citas de expresi-n constante...............................................................................121
#.1.+ Conversiones impl5citas con par(metros de tipo...............................................................................121
#.1.1" Conversiones de0inidas por el usuario impl5citas............................................................................122
#.1.11 Conversiones de 0unci-n an-nima y conversiones de grupo de m)todos........................................122
#.2 Conversiones expl5citas...........................................................................................................................122
#.2.1 Conversiones expl5citas num)ricas...................................................................................................122
#.2.2 Conversiones de enumeraci-n expl5citas...........................................................................................124
#.2.3 Conversiones expl5citas ?ue aceptan valores 4788.........................................................................124
#.2.4 Conversiones expl5citas de re0erencia...............................................................................................12
#.2. Conversiones 7nboxing....................................................................................................................12#
#.2.# Conversiones expl5citas con par(metros de tipo................................................................................12#
#.2.* Conversiones expl5citas de0inidas por el usuario...............................................................................12*
#.3 Conversiones est(ndar.............................................................................................................................12*
#.3.1 Conversiones impl5citas est(ndar......................................................................................................12*
#.3.2 Conversiones expl5citas est(ndar.......................................................................................................128
#.4 Conversiones de0inidas por el usuario.....................................................................................................128
#.4.1 Conversiones permitidas de0inidas por el usuario.............................................................................128
#.4.2 /peradores de conversi-n de elevaci-n............................................................................................128
#.4.3 Evaluaci-n de conversiones de0inidas por el usuario........................................................................128
#.4.4 Conversiones expl5citas de0inidas por el usuario...............................................................................12+
#.4. Conversiones expl5citas de0inidas por el usuario...............................................................................13"
#. Conversiones de 0unci-n an-nima...........................................................................................................131
#..1 Evaluaci-n de conversiones de 0unci-n an-nima a tipos delegados..................................................132
%i Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
#..2 Evaluaci-n de conversiones de 0unci-n an-nima a tipos delegados de (rbol de expresiones............133
#..3 E$emplo de implementaci-n..............................................................................................................133
#.# Conversiones de grupo de m)todos.........................................................................................................13#
(. Expresiones..................................................................................................................................................13$
*.1 Clasi0icaciones de expresi-n....................................................................................................................138
*.1.1 >alores de expresiones......................................................................................................................13+
*.2 /peradores..............................................................................................................................................13+
*.2.1 'rioridad y asociatividad de los operadores......................................................................................14"
*.2.2 .obrecarga de operadores.................................................................................................................141
*.2.3 ;esoluci-n de sobrecarga de operador unario...................................................................................142
*.2.4 ;esoluci-n de sobrecarga de operador binario..................................................................................142
*.2. /peradores candidatos de0inidos por el usuario................................................................................143
*.2.# 'romociones num)ricas....................................................................................................................143
*.2.#.1 'romociones num)ricas unarias...................................................................................................144
*.2.#.2 'romociones num)ricas binarias.................................................................................................144
*.2.* /peradores de elevaci-n...................................................................................................................14
*.3 AHs?ueda de miembros............................................................................................................................14
*.3.1 Tipos base.........................................................................................................................................14*
*.4 %iembros de 0unci-n...............................................................................................................................14*
*.4.1 8istas de argumentos.........................................................................................................................1"
*.4.2 !n0erencia de tipos.............................................................................................................................12
*.4.2.1 8a primera 0ase............................................................................................................................13
*.4.2.2 8a segunda 0ase...........................................................................................................................13
*.4.2.3 Tipos de entrada..........................................................................................................................14
*.4.2.4 Tipos de resultado......................................................................................................................14
*.4.2. 2ependencia................................................................................................................................14
*.4.2.# !n0erencias de tipo de resultado...................................................................................................14
*.4.2.* !n0erencias expl5citas de tipo de par(metro..................................................................................14
*.4.2.8 !n0erencias exactas......................................................................................................................1
*.4.2.+ !n0erencias de l5mite in0erior.......................................................................................................1
*.4.2.1" :i$ar tipos..................................................................................................................................1
*.4.2.11 Tipo de resultado in0erido..........................................................................................................1
*.4.2.12 !n0erencia de tipos para la conversi-n de grupos de m)todos....................................................1*
*.4.2.13 Auscar el me$or tipo comHn de un con$unto de expresiones......................................................1*
*.4.3 ;esoluci-n de sobrecargas................................................................................................................1*
*.4.3.1 %iembro de 0unci-n aplicable.....................................................................................................18
*.4.3.2 %e$or miembro de 0unci-n..........................................................................................................18
*.4.3.3 %e$or conversi-n de expresiones................................................................................................1+
*.4.3.4 %e$or conversi-n de tipos...........................................................................................................1+
*.4.3. .obrecarga en clases gen)ricas....................................................................................................1#"
*.4.4 !nvocaci-n de miembros de 0unci-n..................................................................................................1#"
*.4.4.1 !nvocaciones en instancias de conversi-n boxing........................................................................1#2
*. Expresiones primarias..............................................................................................................................1#2
*..1 8iterales............................................................................................................................................1#3
*..2 4ombres sencillos.............................................................................................................................1#3
*..2.1 .igni0icado invariable en blo?ues................................................................................................1#
*..3 Expresiones entre par)ntesis.............................................................................................................1##
*..4 &cceso a miembros...........................................................................................................................1##
*..4.1 4ombres simples y nombres de tipos id)nticos...........................................................................1#8
*..4.2 &mbigIedades gramaticales........................................................................................................1#8
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. %ii
Especificacin del lenguaje C#
*.. Expresiones de invocaci-n................................................................................................................1#+
*...1 !nvocaciones de m)todo..............................................................................................................1*"
*...2 !nvocaciones del m)todo de extensi-n........................................................................................1*1
*...3 !nvocaciones de delegados..........................................................................................................1*3
*..# &cceso a elementosG..........................................................................................................................1*4
*..#.1 &cceso a matrices........................................................................................................................1*4
*..#.2 &cceso al indi1ador.....................................................................................................................1*
*..* &cceso a t=is.....................................................................................................................................1*
*..8 &cceso a bases..................................................................................................................................1*#
*..+ /peradores post0i$os de incremento y decremento............................................................................1**
*..1" El operador ne9..............................................................................................................................1*8
*..1".1 Expresiones de creaci-n de ob$etos...........................................................................................1*8
*..1".2 !niciali1adores de ob$eto............................................................................................................18"
*..1".3 !niciali1adores de colecci-n.......................................................................................................182
*..1".4 Expresiones de creaci-n de matrices.........................................................................................183
*..1". Expresiones de creaci-n de delegados.......................................................................................18
*..1".# Expresiones de creaci-n de ob$etos an-nimos...........................................................................18#
*..11 /perador typeo0..............................................................................................................................188
*..12 8os operadores c=ec6ed y unc=ec6ed.............................................................................................1+"
*..13 Expresiones de valor predeterminadas............................................................................................1+2
*..14 Expresiones de m)todos an-nimos..................................................................................................1+2
*.# /peradores unarios..................................................................................................................................1+3
*.#.1 /perador unario de signo m(s...........................................................................................................1+3
*.#.2 /perador unario de signo menos.......................................................................................................1+3
*.#.3 /perador de negaci-n l-gica.............................................................................................................1+4
*.#.4 /perador de complemento de bit a bit..............................................................................................1+4
*.#. /peradores pre0i$os de incremento y decremento.............................................................................1+4
*.#.# Expresiones de conversi-n................................................................................................................1+
*.* /peradores aritm)ticos............................................................................................................................1+#
*.*.1 /perador de multiplicaci-n...............................................................................................................1+#
*.*.2 /perador de divisi-n.........................................................................................................................1+*
*.*.3 /perador de resto..............................................................................................................................1+8
*.*.4 /perador de suma.............................................................................................................................1++
*.*. /perador de resta..............................................................................................................................2"1
*.8 /peradores de despla1amiento................................................................................................................2"3
*.+ /peradores de comprobaci-n de tipos y relacionales..............................................................................2"4
*.+.1 /peradores de comparaci-n de enteros.............................................................................................2"
*.+.2 /peradores de comparaci-n de punto 0lotante..................................................................................2"#
*.+.3 /peradores de comparaci-n decimales.............................................................................................2"#
*.+.4 /peradores de igualdad booleanos....................................................................................................2"*
*.+. /peradores de comparaci-n de tipo de enumeraci-n........................................................................2"*
*.+.# /peradores de igualdad de tipos de re0erencia..................................................................................2"*
*.+.* /peradores de igualdad de cadenas...................................................................................................2"+
*.+.8 /peradores de igualdad de delegados...............................................................................................2"+
*.+.+ /peradores de igualdad y 4788......................................................................................................21"
*.+.1" /perador !s.....................................................................................................................................21"
*.+.11 /perador &s....................................................................................................................................21"
*.1" /peradores l-gicos................................................................................................................................211
*.1".1 /peradores l-gicos enteros.............................................................................................................212
*.1".2 /peradores l-gicos de enumeraci-n................................................................................................212
*.1".3 /peradores l-gicos booleanos.........................................................................................................212
%iii Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
*.1".4 /peradores l-gicos booleanos ?ue aceptan valores 4788.............................................................213
*.11 /peradores l-gicos condicionales..........................................................................................................213
*.11.1 /peradores l-gicos condicionales booleanos..................................................................................214
*.11.2 /peradores l-gicos condicionales de0inidos por el usuario.............................................................214
*.12 El operador de uso combinado de 4788..............................................................................................21
*.13 /perador condicional............................................................................................................................21
*.14 Expresiones de 0unciones an-nimas......................................................................................................21#
*.14.1 :irmas de 0unci-n an-nima.............................................................................................................218
*.14.2 Cuerpos de 0unci-n an-nima...........................................................................................................218
*.14.3 ;esoluci-n de sobrecargas..............................................................................................................21+
*.14.4 >ariables externas...........................................................................................................................22"
*.14.4.1 >ariables externas capturadas....................................................................................................22"
*.14.4.2 Creaci-n de instancias de variables locales...............................................................................221
*.14. Expresiones de evaluaci-n de 0unciones an-nimas.........................................................................223
*.1 Expresiones de consulta.........................................................................................................................223
*.1.1 &mbigIedad en expresiones de consulta.........................................................................................224
*.1.2 Traducci-n de expresiones de consulta...........................................................................................22
*.1.2.1 Cl(usulas .elect y 3roupby con continuaciones........................................................................22
*.1.2.2 Tipos de variable de intervalo expl5citos...................................................................................22#
*.1.2.3 Expresiones de consulta degeneradas........................................................................................22#
*.1.2.4 Cl(usulas 0rom, let, 9=ere, $oin y orderby.................................................................................22*
*.1.2. Cl(usulas .elect.........................................................................................................................23"
*.1.2.# Cl(usulas 3roupby....................................................................................................................23"
*.1.2.* !denti0icadores transparentes.....................................................................................................231
*.1.3 El patr-n de expresiones de consulta...............................................................................................232
*.1# /peradores de asignaci-n......................................................................................................................233
*.1#.1 &signaci-n simple...........................................................................................................................234
*.1#.2 &signaci-n compuesta....................................................................................................................23#
*.1#.3 &signaci-n de eventos.....................................................................................................................23*
*.1* Expresi-n...............................................................................................................................................23*
*.18 Expresiones constantes..........................................................................................................................238
*.1+ Expresiones booleanas...........................................................................................................................23+
$. Instrucciones................................................................................................................................................2#'
8.1 'untos 0inales y alcance...........................................................................................................................24"
8.2 Alo?ues....................................................................................................................................................242
8.2.1 8istas de instrucciones......................................................................................................................242
8.3 !nstrucci-n vac5a......................................................................................................................................243
8.4 !nstrucciones con eti?ueta........................................................................................................................243
8. !nstrucciones de declaraci-n....................................................................................................................244
8..1 2eclaraciones de variables locales....................................................................................................244
8..2 2eclaraciones de constantes locales..................................................................................................24#
8.# !nstrucciones de expresiones...................................................................................................................24#
8.* !nstrucciones de selecci-n.......................................................................................................................24*
8.*.1 !nstrucci-n !0.....................................................................................................................................24*
8.*.2 !nstrucci-n .9itc=............................................................................................................................248
8.8 !nstrucciones de iteraci-n........................................................................................................................22
8.8.1 !nstrucci-n @=ile..............................................................................................................................22
8.8.2 !nstrucci-n 2o...................................................................................................................................22
8.8.3 !nstrucci-n :or..................................................................................................................................23
8.8.4 !nstrucci-n :oreac=...........................................................................................................................24
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. ix
Especificacin del lenguaje C#
8.+ !nstrucciones Jump..................................................................................................................................2*
8.+.1 !nstrucci-n Area6..............................................................................................................................28
8.+.2 !nstrucci-n .tatement........................................................................................................................2+
8.+.3 !nstrucci-n 3oto................................................................................................................................2+
8.+.4 !nstrucci-n ;eturn.............................................................................................................................2#"
8.+. !nstrucci-n T=ro9.............................................................................................................................2#1
8.1" !nstrucci-n Try......................................................................................................................................2#2
8.11 !nstrucciones C=ec6ed y 7nc=ec6ed.....................................................................................................2#
8.12 !nstrucci-n 8oc6....................................................................................................................................2#
8.13 !nstrucci-n 7sing...................................................................................................................................2##
8.14 8a instrucci-n yield...............................................................................................................................2#8
". Espacio de no)bres.....................................................................................................................................2('
+.1 7nidades de compilaci-n.........................................................................................................................2*"
+.2 2eclaraciones de espacio de nombres......................................................................................................2*"
+.3 &lias extern.............................................................................................................................................2*2
+.4 2irectivas 7sing......................................................................................................................................2*2
+.4.1 2irectivas 7sing alias.......................................................................................................................2*3
+.4.2 2irectivas 7sing espacio de nombres................................................................................................2*#
+. %iembros de espacio de nombres............................................................................................................2*8
+.# 2eclaraciones de tipo...............................................................................................................................2*8
+.* Cali0icadores de alias de espacios de nombres.........................................................................................2*+
+.*.1 7nicidad de los alias.........................................................................................................................28"
1'. Clases.........................................................................................................................................................2$1
1".1 2eclaraciones de clases.........................................................................................................................281
1".1.1 %odi0icadores de clase....................................................................................................................281
1".1.1.1 Clases abstractas........................................................................................................................282
1".1.1.2 Clases .ealed.............................................................................................................................282
1".1.1.3 Clases est(ticas..........................................................................................................................283
1".1.2 %odi0icador parcial.........................................................................................................................284
1".1.3 'ar(metros de tipo...........................................................................................................................284
1".1.4 Especi0icaci-n de clase base...........................................................................................................284
1".1.4.1 Clases base................................................................................................................................28
1".1.4.2 !mplementaciones de inter0aces.................................................................................................28#
1".1. ;estricciones de par(metros de tipo................................................................................................28#
1".1.# Cuerpo de clase...............................................................................................................................2+1
1".2 Tipos parciales.......................................................................................................................................2+1
1".2.1 &tributos.........................................................................................................................................2+1
1".2.2 %odi0icadores.................................................................................................................................2+2
1".2.3 'ar(metros de tipo y restricciones...................................................................................................2+2
1".2.4 Clase base.......................................................................................................................................2+3
1".2. !nter0aces base.................................................................................................................................2+3
1".2.# %iembros........................................................................................................................................2+3
1".2.* %)todos parciales...........................................................................................................................2+4
1".2.8 Enlace de nombres..........................................................................................................................2+#
1".3 %iembros de clase.................................................................................................................................2+*
1".3.1 El tipo de instancia .........................................................................................................................2+8
1".3.2 %iembros de tipos construidos........................................................................................................2+8
1".3.3 Herencia..........................................................................................................................................2++
1".3.4 %odi0icador 4e9............................................................................................................................3"1
x Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
1".3. %odi0icadores de acceso.................................................................................................................3"1
1".3.# Tipos constituyentes........................................................................................................................3"2
1".3.* %iembros est(ticos y de instancia...................................................................................................3"2
1".3.8 Tipos anidados................................................................................................................................3"3
1".3.8.1 4ombre completo......................................................................................................................3"3
1".3.8.2 &ccesibilidad declarada.............................................................................................................3"3
1".3.8.3 /cultar.......................................................................................................................................3"4
1".3.8.4 &cceso t=is................................................................................................................................3"
1".3.8. &cceso a miembros privados y protegidos del tipo contenedor.................................................3"
1".3.8.# Tipos anidados en clases gen)ricas............................................................................................3"#
1".3.+ 4ombres de miembro reservados....................................................................................................3"*
1".3.+.1 4ombres de miembros reservados para propiedades.................................................................3"*
1".3.+.2 4ombres de miembros reservados para eventos........................................................................3"8
1".3.+.3 4ombres de miembros reservados para indi1adores..................................................................3"8
1".3.+.4 4ombres de miembros reservados para destructores.................................................................3"8
1".4 Constantes.............................................................................................................................................3"8
1". Campos..................................................................................................................................................31"
1"..1 Campos est(ticos y de instancia......................................................................................................312
1"..2 Campos de s-lo lectura...................................................................................................................312
1"..2.1 7tili1ar campos de s-lo lectura est(ticos para constantes..........................................................313
1"..2.2 >ersiones de constantes y campos de s-lo lectura est(ticos......................................................313
1"..3 Campos volatile..............................................................................................................................314
1"..4 !niciali1aci-n de campos.................................................................................................................31
1".. !niciali1adores de variables.............................................................................................................31
1"...1 !niciali1aci-n de campos est(ticos.............................................................................................31#
1"...2 !niciali1aci-n de campos de instancia........................................................................................318
1".# %)todos.................................................................................................................................................318
1".#.1 'ar(metros de m)todos...................................................................................................................32"
1".#.1.1 'ar(metros de valor...................................................................................................................321
1".#.1.2 'ar(metros de re0erencia...........................................................................................................321
1".#.1.3 'ar(metros de salida..................................................................................................................322
1".#.1.4 %atrices de par(metros.............................................................................................................323
1".#.2 %)todos est(ticos y de instancia.....................................................................................................32#
1".#.3 %)todos virtuales............................................................................................................................32#
1".#.4 %)todos de invalidaci-n.................................................................................................................328
1".#. %)todos sellados.............................................................................................................................33"
1".#.# %)todos abstractos..........................................................................................................................331
1".#.* %)todos externos............................................................................................................................332
1".#.8 %)todos parciales...........................................................................................................................333
1".#.+ %)todos de extensi-n......................................................................................................................333
1".#.1" Cuerpo del m)todo........................................................................................................................334
1".#.11 .obrecarga de m)todos.................................................................................................................334
1".* 'ropiedades...........................................................................................................................................334
1".*.1 'ropiedades est(ticas y de instancia................................................................................................33#
1".*.2 2escriptores de acceso....................................................................................................................33#
1".*.3 'ropiedades autom(ticamente implementadas................................................................................341
1".*.4 &ccesibilidad..................................................................................................................................342
1".*. 2escriptores de acceso virtual, sellado, de invalidaci-n y abstracto................................................343
1".8 Eventos..................................................................................................................................................34
1".8.1 Eventos como campos.....................................................................................................................34*
1".8.2 2escriptores de acceso de evento....................................................................................................34+
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. xi
Especificacin del lenguaje C#
1".8.3 Eventos est(ticos y de instancia......................................................................................................3"
1".8.4 2escriptores de acceso virtual, sellado, de invalidaci-n y abstracto................................................3"
1".+ !ndi1adores............................................................................................................................................31
1".+.1 .obrecarga de indi1adores...............................................................................................................3
1".1" /peradores...........................................................................................................................................3
1".1".1 /peradores unarios.......................................................................................................................3#
1".1".2 /peradores binarios......................................................................................................................3*
1".1".3 /peradores de conversi-n.............................................................................................................38
1".11 Constructores de instancia...................................................................................................................3#"
1".11.1 !niciali1adores de constructor........................................................................................................3#1
1".11.2 !niciali1adores de variables de instancia........................................................................................3#2
1".11.3 E$ecuci-n de constructores............................................................................................................3#2
1".11.4 Constructores predeterminados.....................................................................................................3#4
1".11. Constructores 'rivate....................................................................................................................3#
1".11.# 'ar(metros de constructor de instancia opcionales........................................................................3#
1".12 Constructores static..............................................................................................................................3#
1".13 2estructores.........................................................................................................................................3#8
1".14 !teradores.............................................................................................................................................3#+
1".14.1 !nter0aces del enumerador.............................................................................................................3*"
1".14.2 !nter0aces enumerables..................................................................................................................3*"
1".14.3 Tipo Kield.....................................................................................................................................3*"
1".14.4 /b$etos del enumerador................................................................................................................3*"
1".14.4.1 El m)todo %ove4ext...............................................................................................................3*"
1".14.4.2 8a propiedad Current...............................................................................................................3*2
1".14.4.3 El m)todo 2ispose...................................................................................................................3*2
1".14. /b$etos enumerables.....................................................................................................................3*2
1".14..1 El m)todo 3etEnumerator.......................................................................................................3*3
1".14.# E$emplo de implementaci-n..........................................................................................................3*3
11. Estructuras................................................................................................................................................3$'
11.1 2eclaraciones de estructuras..................................................................................................................38"
11.1.1 %odi0icadores de estructuras..........................................................................................................38"
11.1.2 %odi0icador parcial.........................................................................................................................381
11.1.3 !nter0aces .truct..............................................................................................................................381
11.1.4 Cuerpo de estructura.......................................................................................................................381
11.2 %iembros de estructura.........................................................................................................................381
11.3 2i0erencias entre clase y estructura.......................................................................................................382
11.3.1 .em(nticas de valor........................................................................................................................382
11.3.2 Herencia..........................................................................................................................................383
11.3.3 &signaci-n......................................................................................................................................383
11.3.4 >alores predeterminados.................................................................................................................383
11.3. Conversiones boxing y unboxing....................................................................................................384
11.3.# .igni0icado de T=is.........................................................................................................................38#
11.3.* !niciali1adores de campo.................................................................................................................38#
11.3.8 Constructores..................................................................................................................................38#
11.3.+ 2estructores....................................................................................................................................38*
11.3.1" Constructores static.......................................................................................................................38*
11.4 E$emplos de estructuras.........................................................................................................................388
11.4.1 Tipo entero de base de datos...........................................................................................................388
11.4.2 Tipo booleano de base de datos.......................................................................................................38+
12. *atrices.....................................................................................................................................................3"2
xii Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
12.1 Tipos de matri1......................................................................................................................................3+2
12.1.1 Tipo .ystem.&rray..........................................................................................................................3+3
12.1.2 %atrices y la inter0a1 !8ist gen)rica................................................................................................3+3
12.2 Creaci-n de matrices.............................................................................................................................3+4
12.3 &cceso a los elementos de matri1..........................................................................................................3+4
12.4 %iembros de matri1...............................................................................................................................3+4
12. Covarian1a de matrices..........................................................................................................................3+4
12.# !niciali1adores de matrices....................................................................................................................3+
13. Interfaces...................................................................................................................................................3"(
13.1 2eclaraciones de inter0a1.......................................................................................................................3+*
13.1.1 %odi0icadores de inter0a1................................................................................................................3+*
13.1.2 %odi0icador parcial.........................................................................................................................3+8
13.1.3 !nter0aces base.................................................................................................................................3+8
13.1.4 Cuerpo de inter0a1...........................................................................................................................3+8
13.2 %iembros de inter0a1.............................................................................................................................3++
13.2.1 %)todos de inter0a1.........................................................................................................................4""
13.2.2 'ropiedades de inter0a1...................................................................................................................4""
13.2.3 Eventos de inter0a1..........................................................................................................................4""
13.2.4 !ndi1adores de inter0a1....................................................................................................................4"1
13.2. &cceso a miembros de inter0a1.......................................................................................................4"1
13.3 4ombres completos de miembros de inter0a1........................................................................................4"3
13.4 !mplementaciones de inter0aces.............................................................................................................4"3
13.4.1 !mplementaciones de miembro de inter0a1 expl5citas......................................................................4"4
13.4.2 Exclusividad de inter0aces implementadas......................................................................................4"#
13.4.3 !mplementaci-n de m)todos gen)ricos............................................................................................4"*
13.4.4 &signaci-n de inter0aces.................................................................................................................4"8
13.4. Herencia de implementaci-n de inter0aces......................................................................................411
13.4.# ;eimplementaci-n de inter0aces.....................................................................................................412
13.4.* !nter0aces y clases abstractas...........................................................................................................413
1#. Enu)eraciones..........................................................................................................................................#1!
14.1 2eclaraciones de enumeraci-n..............................................................................................................41
14.2 %odi0icadores de enumeraci-n..............................................................................................................41
14.3 %iembros de enumeraci-n....................................................................................................................41#
14.4 Tipo .ystem.Enum................................................................................................................................418
14. >alores y operaciones de enumeraci-n..................................................................................................418
1!. +elegados...................................................................................................................................................#1"
1.1 2eclaraciones de delegados...................................................................................................................41+
1.2 Compatibilidad de delegados.................................................................................................................421
1.3 Creaci-n de instancias de delegados......................................................................................................422
1.4 !nvocaci-n de delegados........................................................................................................................422
16. Excepciones................................................................................................................................................#2!
1#.1 Causas de excepciones...........................................................................................................................42
1#.2 Clase .ystem.Exception........................................................................................................................42
1#.3 C-mo controlar excepciones..................................................................................................................42
1#.4 Clases de excepci-n comunes................................................................................................................42#
1(. ,tributos....................................................................................................................................................#2$
1*.1 Clases de atributos.................................................................................................................................428
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. xiii
Especificacin del lenguaje C#
1*.1.1 7so de los atributos.........................................................................................................................428
1*.1.2 'ar(metros posicionales y con nombre...........................................................................................42+
1*.1.3 Tipos de par(metros de atributos.....................................................................................................43"
1*.2 Especi0icaci-n de atributos....................................................................................................................43"
1*.3 !nstancias de atributo.............................................................................................................................43#
1*.3.1 Compilaci-n de un atributo.............................................................................................................43#
1*.3.2 ;ecuperaci-n en tiempo de e$ecuci-n de una instancia de atributo.................................................43#
1*.4 &tributos reservados..............................................................................................................................43*
1*.4.1 &tributo &ttribute7sage..................................................................................................................43*
1*.4.2 &tributo Conditional.......................................................................................................................438
1*.4.2.1 %)todos condicionales..............................................................................................................438
1*.4.2.2 Clases de atributo condicional...................................................................................................44"
1*.4.3 &tributo /bsolete............................................................................................................................441
1*. &tributos para interoperabilidad............................................................................................................442
1*..1 !nteroperabilidad con componentes C/% y @in32........................................................................442
1*..2 !nteroperabilidad con otros lengua$es .4ET....................................................................................442
1*..2.1 &tributo !ndexer4ame...............................................................................................................442
1$. Cdigo no seguro.......................................................................................................................................##3
18.1 Contextos no seguros.............................................................................................................................443
18.2 Tipos de punteros..................................................................................................................................44#
18.3 >ariables 0i$as y m-viles.......................................................................................................................448
18.4 Conversiones de puntero........................................................................................................................44+
18.4.1 %atrices de punteros.......................................................................................................................4"
18. 'unteros en expresiones.........................................................................................................................41
18..1 2ireccionamiento indirecto de punteros..........................................................................................41
18..2 &cceso a miembros de puntero.......................................................................................................42
18..3 &cceso a elementos de puntero.......................................................................................................42
18..4 /perador de direcci-n.....................................................................................................................43
18.. !ncremento y decremento de punteros.............................................................................................44
18..# &ritm)tica con punteros..................................................................................................................44
18..* Comparaci-n de punteros................................................................................................................4
18..8 /perador .i1eo0..............................................................................................................................4#
18.# !nstrucci-n 0ixed....................................................................................................................................4#
18.* AH0eres 0i$os..........................................................................................................................................4#"
18.*.1 2eclaraciones de bH0eres 0i$os.........................................................................................................4#"
18.*.2 AH0eres 0i$os en expresiones............................................................................................................4#1
18.*.3 Comprobaci-n de asignaci-n de0initiva..........................................................................................4#2
18.8 &signaci-n de pila.................................................................................................................................4#2
18.+ &signaci-n din(mica de memoria..........................................................................................................4#3
,. Co)entarios de docu)entacin................................................................................................................#66
&.1 !ntroducci-n............................................................................................................................................4##
&.2 Eti?uetas recomendadas..........................................................................................................................4#*
&.2.1 LcM...................................................................................................................................................4#8
&.2.2 LcodeM.............................................................................................................................................4#8
&.2.3 LexampleM.......................................................................................................................................4#+
&.2.4 LexceptionM.....................................................................................................................................4#+
&.2. LincludeM.........................................................................................................................................4*"
&.2.# LlistM................................................................................................................................................4*1
&.2.* LparaM..............................................................................................................................................4*1
xi% Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Tabla de contenido
&.2.8 LparamM...........................................................................................................................................4*2
&.2.+ Lparamre0M.......................................................................................................................................4*2
&.2.1" LpermissionM..................................................................................................................................4*3
&.2.11 Lremar6M........................................................................................................................................4*3
&.2.12 LreturnsM........................................................................................................................................4*3
&.2.13 LseeM..............................................................................................................................................4*4
&.2.14 LseealsoM.......................................................................................................................................4*4
&.2.1 LsummaryM....................................................................................................................................4*
&.2.1# LvalueM..........................................................................................................................................4*
&.2.1* LtypeparamM..................................................................................................................................4*
&.2.18 Ltypeparamre0M..............................................................................................................................4*#
&.3 'rocesar el arc=ivo de documentaci-n....................................................................................................4*#
&.3.1 :ormato de cadena de !d..................................................................................................................4*#
&.3.2 E$emplos de cadena de !d.................................................................................................................4*8
&.4 7n e$emplo.............................................................................................................................................481
&.4.1 C-digo 0uente C#.............................................................................................................................481
&.4.2 N%8 resultante................................................................................................................................484
-. .ra)tica...................................................................................................................................................#$(
A.1 3ram(tica l)xica.....................................................................................................................................48*
A.1.1 Terminadores de l5nea......................................................................................................................48*
A.1.2 Comentarios.....................................................................................................................................48*
A.1.3 Espacio en blanco.............................................................................................................................488
A.1.4 To6ens..............................................................................................................................................488
A.1. .ecuencias de escape de caracteres 7nicode....................................................................................488
A.1.# !denti0icadores..................................................................................................................................48+
A.1.* 'alabras clave...................................................................................................................................4+"
A.1.8 8iterales............................................................................................................................................4+"
A.1.+ /peradores y signos de puntuaci-n..................................................................................................4+2
A.1.1" 2irectivas de preprocesamiento......................................................................................................4+2
A.2 3ram(tica sint(ctica................................................................................................................................4+
A.2.1 Conceptos b(sicos............................................................................................................................4+
A.2.2 Tipos................................................................................................................................................4+
A.2.3 >ariables..........................................................................................................................................4+#
A.2.4 Expresiones......................................................................................................................................4+*
A.2. !nstrucciones...................................................................................................................................."3
A.2.# Espacio de nombres.........................................................................................................................."*
A.2.* Clases..............................................................................................................................................."8
A.2.8 Estructuras........................................................................................................................................1
A.2.+ %atrices............................................................................................................................................1
A.2.1" !nter0aces........................................................................................................................................1#
A.2.11 Enumeraciones...............................................................................................................................1*
A.2.12 2elegados.......................................................................................................................................1*
A.2.13 &tributos.........................................................................................................................................18
A.3 Extensiones de la gram(tica para el c-digo no seguro............................................................................1+
C. /eferencias..................................................................................................................................................!23
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. x%
Cap0tulo 1' Clases
1. Introduccin
C# OPC s=arpQR es un lengua$e de programaci-n sencillo y moderno, orientado a ob$etos y con seguridad de
tipos. C# tiene su ra51 en la 0amilia de lengua$es C y resultar( inmediatamente 0amiliar a programadores de C,
CSS y Java. EC%& !nternational estandari1a C# como el est(ndar ECM$-%%&, e !./TCE! como el est(ndar
'()*'EC 2%2+0. El compilador de C# de %icroso0t para .4ET :rame9or6 es una implementaci-n compatible
de ambos est(ndares.
C# es un lengua$e de programaci-n orientado a ob$etos, pero tambi)n es compatible con la programaci-n
orientada a coponentes. El diseUo de so0t9are contempor(neo se basa cada ve1 m(s en componentes de
so0t9are en 0orma de pa?uetes de 0uncionalidad autodescriptivos y autosu0icientes. 8a clave de dic=os
componentes reside en ?ue presentan un modelo de programaci-n con propiedades, m)todos y eventos, en ?ue
tienen atributos ?ue 0acilitan in0ormaci-n declarativa sobre el componente y en ?ue incorporan su propia
documentaci-n. C# proporciona construcciones de lengua$e para ?ue se admitan directamente estos conceptos,
=aciendo de C# un lengua$e muy natural en el ?ue crear y utili1ar los componentes de so0t9are.
&lgunas de las caracter5sticas de C# ayudan en la construcci-n de aplicaciones s-lidas y duraderasG la
recolecci,n de eleentos no !tili-ados reclama autom(ticamente la memoria ocupada por ob$etos no utili1adosV
el control de e.cepciones proporciona un en0o?ue extensible y estructurado de la detecci-n y recuperaci-n de
erroresV y el diseUo con seg!ridad de tipos del lengua$e =ace ?ue sea imposible leer variables no iniciali1adas,
indi1ar las matrices m(s all( de sus l5mites o reali1ar conversiones de tipo no comprobado.
C# tiene un sistea de tipos !nificado. Todos los tipos de C#, incluidos tipos primitivos como int y double,
=eredan de un tipo ra51 object Hnico. 'or lo tanto, todos los tipos comparten un con$unto de operaciones
comunes, y se pueden almacenar, transportar y tratar valores de cual?uier tipo de una manera co=erente.
&dem(s, C# admite tipos de re0erencia de0inidos por el usuario y tipos de valor, y permite la asignaci-n
din(mica de ob$etos as5 como el almacenamiento en l5nea de estructuras ligeras.
'ara asegurarse de ?ue los programas y bibliotecas de C# evolucionan con el tiempo de 0orma compatible, se =a
dado muc=a importancia al control de versiones en el diseUo de C#. %uc=os lengua$es de programaci-n apenas
prestan atenci-n a este problema y, en consecuencia, los programas escritos en estos lengua$es se interrumpen
m(s de lo necesario cuando se incluyen versiones m(s recientes de bibliotecas dependientes. 8os aspectos del
diseUo de C# con in0luencia directa de las consideraciones sobre el control de versiones incluyen los
modi0icadores virtual y override, las reglas de la resoluci-n de sobrecarga de m)todos y la compatibilidad
con declaraciones expl5citas de miembros de inter0a1.
En el resto de este cap5tulo se explican las caracter5sticas esenciales del lengua$e C#. %ientras ?ue en cap5tulos
posteriores se describen las reglas y las excepciones de una 0orma muy detallada e incluso a veces matem(tica,
este cap5tulo se =a redactado dando prioridad a la claridad y la brevedad, a veces incluso a expensas de la
integridad. El prop-sito es proporcionar al lector una introducci-n al lengua$e ?ue pueda 0acilitarle la
programaci-n de sus primeros programas y la lectura de posteriores cap5tulos.
1.1 Hola a todos
El programa Hola a todos OPHello, @orldQR se utili1a tradicionalmente para presentar un lengua$e de
programaci-n. &?u5 est( en C#G
using System;
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1
Especificacin del lenguaje C#
class Hello
{
static void Main() {
Console.WriteLine("Hello World");
!
!
4ormalmente, la extensi-n de los arc=ivos de c-digo 0uente de C# es .cs. .uponiendo ?ue PHello, @orldQ se
almacena en el arc=ivo "ello.cs, el programa se puede compilar con el compilador de %icroso0t C#,
utili1ando la l5nea de comandos
csc "ello.cs
?ue genera un ensamblado e$ecutable denominado "ello.e#e. El resultado de la e$ecuci-n de esta aplicaci-n
es
Hello World
El programa PHello, @orldQ se inicia con una directiva using ?ue =ace re0erencia al espacio de nombres
System. 8os espacios de nombres proporcionan una $erar?u5a ?ue permite organi1ar programas y bibliotecas de
C#. 8os espacios de nombres contienen tipos y otros espacios de nombres, por e$emplo, el espacio de nombres
System contiene varios tipos, como la clase Console, a la ?ue se =ace re0erencia en el programa, y otros
espacios de nombres, como $% y Collections. 7na directiva using ?ue =ace re0erencia a un espacio de
nombres determinado permite el uso no cali0icado de los tipos ?ue son miembros del espacio de nombres.
2ebido a la directiva using, el programa puede utili1ar Console.WriteLine como 0orma abreviada para
System.Console.WriteLine.
8a clase Hello declarada por el programa PHello, @orldQ tiene un Hnico miembro, el m)todo denominado
Main. El m)todo Main se declara con el modi0icador static. %ientras ?ue los m)todos de instancia =acen
re0erencia a una instancia de ob$eto determinada utili1ando la palabra clave t"is, los m)todos est(ticos
0uncionan sin re0erencia a un ob$eto determinado. 'or convenci-n, un m)todo est(tico denominado Main sirve
como punto de entrada de un programa.
El m)todo WriteLine genera el resultado del programa en la clase Console del espacio de nombres System.
Esta clase es proporcionada por las bibliotecas de clases de .4ET :rame9or6, a las ?ue de 0orma
predeterminada =ace re0erencia autom(ticamente el compilador de %icroso0t C#. /bserve ?ue el propio C# no
tiene una biblioteca en tiempo de e$ecuci-n independiente. En su lugar, .4ET :rame9or6 es la biblioteca en
tiempo de e$ecuci-n de C#.
1.2 Estructura del programa
8os conceptos clave de organi1aci-n en C# son prograas, espacios de no/res, tipos, ie/ros y
ensa/lados. 8os programas de C# constan de uno o varios arc=ivos de c-digo 0uente. 8os programas declaran
tipos, ?ue contienen los miembros y pueden organi1arse en los espacios de nombres. 8as clases y las inter0aces
son e$emplos de tipos. 8os campos, m)todos, propiedades y eventos son e$emplos de miembros. Cuando se
compilan programas de C#, se empa?uetan 05sicamente en ensamblados. 4ormalmente la extensi-n de arc=ivo
de los ensamblados es .e#e o .dll, dependiendo de si implementan aplicaciones o /i/liotecas.
En el e$emplo
using System;
names&ace 'cme.Collections
{
&ublic class Stac(
{
)ntry to&;
&ublic void *us"(object data) {
to& + ne, )ntry(to& data);
!
2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
&ublic object *o&() {
i- (to& ++ null) t"ro, ne, $nvalid%&eration)#ce&tion();
object result + to&.data;
to& + to&.ne#t;
return result;
!
class )ntry
{
&ublic )ntry ne#t;
&ublic object data;
&ublic )ntry()ntry ne#t object data) {
t"is.ne#t + ne#t;
t"is.data + data;
!
!
!
!
se declara una clase denominada Stac( en un espacio de nombres llamado 'cme.Collections. El nombre
completo de esta clase es 'cme.Collections.Stac(. 8a clase contiene varios miembrosG un campo
denominado to&, dos m)todos denominados *us" y *o&, y una clase anidada denominada )ntry. 8a clase
)ntry contiene tres miembros m(sG un campo denominado ne#t, un campo denominado data y un
constructor. .uponiendo ?ue el c-digo 0uente del e$emplo se almacena en el arc=ivo acme.cs, la l5nea de
comandos
csc .t/library acme.cs
compila el e$emplo como una biblioteca Oc-digo sin un punto de entrada MainR y genera un ensamblado
denominado acme.dll.
8os ensamblados contienen c-digo e$ecutable en 0orma de instrucciones de 0eng!a1e interedio O!8R e
in0ormaci-n simb-lica en 0orma de etadatos. &ntes de e$ecutarse, el c-digo !8 de un ensamblado se convierte
autom(ticamente en c-digo espec50ico del procesador mediante el compilador JustB!nBTime OJ!TR de .4ET
Common 8anguage ;untime.
2ado ?ue un ensamblado es una unidad autodescriptiva de 0uncionalidad ?ue contiene c-digo y metadatos, las
directivas 0include y los arc=ivos de encabe1ado no son necesarios en C#. 8os tipos y miembros pHblicos
contenidos en un ensamblado determinado estar(n disponibles en un programa de C# =aciendo re0erencia a
dic=o ensamblado al compilar el programa. 'or e$emplo, este programa utili1a la clase
'cme.Collections.Stac( desde el ensamblado acme.dllG
using System;
using 'cme.Collections;
class 1est
{
static void Main() {
Stac( s + ne, Stac(();
s.*us"(2);
s.*us"(23);
s.*us"(233);
Console.WriteLine(s.*o&());
Console.WriteLine(s.*o&());
Console.WriteLine(s.*o&());
!
!
.i el programa se almacena en el arc=ivo test.cs, cuando se compila test.cs se puede =acer re0erencia al
ensamblado acme.dll utili1ando la opci-n del compilador .rG
csc .r/acme.dll test.cs
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 3
Especificacin del lenguaje C#
2e este modo se crea un ensamblado e$ecutable denominado test.e#e ?ue, cuando se e$ecuta, genera el
resultadoG
233
23
2
C# permite el almacenamiento del texto de origen de un programa en varios arc=ivos de c-digo 0uente. Cuando
se compila un programa de C# de varios arc=ivos, se procesan todos los arc=ivos de c-digo 0uente $untos, y
)stos pueden =acer re0erencia libremente unos a otros. Conceptualmente, es como si todos los arc=ivos de
c-digo 0uente se concatenaran en un gran arc=ivo antes de procesarse. En C# nunca son necesarias las
declaraciones adelantadas por?ue, salvo alguna excepci-n, el orden de la declaraci-n no es signi0icativo. C# no
limita un arc=ivo de c-digo 0uente a declarar un Hnico tipo pHblico ni exige ?ue el nombre del arc=ivo de c-digo
0uente coincida con un tipo declarado en el arc=ivo de c-digo 0uente.
1.3 Tipos y ariables
Hay dos clases de tipos en C#G tipos de valor y tipos de referencia. 8as variables de tipos de valor contienen
directamente sus datos mientras ?ue las variables de tipos de re0erencia almacenan las re0erencias a sus datos,
?ue se conocen como ob$etos. En el caso de los tipos de re0erencia, es posible ?ue dos variables =agan re0erencia
al mismo ob$eto y, por tanto, ?ue las operaciones en una variable a0ecten al ob$eto al ?ue =ace re0erencia la otra
variable. En el caso de los tipos de valor, cada variable tiene su propia copia de los datos, de manera ?ue no es
posible ?ue las operaciones de una a0ecten a la otra Oexceptuando las variables de los par(metros re- y outR.
8os tipos de valor de C# se dividen a su ve1 en tipos siples, tipos de en!eraci,n, tipos de estr!ct!ra, y tipos
"!e aceptan valores 2300, y los tipos de re0erencia de C# en tipos de clase, tipos de interfa-, tipos de atri- y
tipos de delegado.
# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a tabla siguiente proporciona in0ormaci-n general sobre el sistema de tipos de C#.
Categor0a +escripcin
Tipos de
valor
Tipos simples !ntegrales con signoG sbyte, s"ort, int, long
!ntegrales sin signoG byte, us"ort, uint, ulong
Caracteres 7nicodeG c"ar
'unto 0lotante !EEEG -loat, double
2ecimal de gran precisi-nG decimal
AooleanoG bool
Tipos de
enumeraci-n
Tipos de0inidos por el usuario en 0orma de enum ) {...!
Tipos de
estructura
Tipos de0inidos por el usuario en 0orma de struct S {...!
Tipos ?ue
aceptan valores
4788
Extensiones de todos los dem(s tipos de valores con un valor
null
Tipos de
re0erencia
Tipos de clase Clase base Hltima de los dem(s tiposG object
Cadenas de 7nicodeG string
Tipos de0inidos por el usuario en 0orma class C {...!
Tipos de inter0a1 Tipos de0inidos por el usuario en 0orma de inter-ace $
{...!
Tipos de matri1 7nidimensional y multidimensional, por e$emplo, int45 e
int45
Tipos de
delegados
Tipos de0inidos por el usuario por e$. en 0orma de delegate
int 6(...)
8os oc=o tipos integrales admiten los valores de 8 bits, 1# bits, 32 bits y #4 bits, con y sin signo.
8os dos tipos de punto 0lotante -loat y double se representan utili1ando los 0ormatos !EEE *4 de 32 bits de
precisi-n simple y de #4 bits de doble precisi-n.
El tipo decimal es un tipo de datos de 128 bits apto para c(lculos 0inancieros y monetarios.
El tipo bool de C# permite representar valores booleanos, ?ue son true o -alse.
El procesamiento de caracteres y cadenas en C# utili1a la codi0icaci-n 7nicode. El tipo c"ar representa una
unidad de c-digo 7T: de 1# bits y el tipo string representa una secuencia de unidades de c-digo 7T: de
1# bits.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. !
Especificacin del lenguaje C#
8a tabla siguiente resume los tipos num)ricos de C#.
Categor0a -its Tipo Inter%alo1precisin
!ntegral con
signo
8
sbyte
W128...12*
1#
s"ort
W32.*#8...32.*#*
32
int
W2.14*.483.#48...2.14*.483.#4*
#4
long
W+.223.3*2."3#.84.**.8"8...+.223.3*2."3#.84.**.8"*
!ntegral sin
signo
8
byte
"...2
1#
us"ort
"...#.3
32
uint
"...4.2+4.+#*.2+
#4
ulong
"...18.44#.*44."*3.*"+.1.#1
'unto
0lotante
32
-loat
1, X 1"
Y4
a 3,4 X 1"
38
, con precisi-n de * d5gitos
#4
double
," X 1"
Y324
a 1,* X 1"
3"8
, con precisi-n de 1 d5gitos
2ecimal 128
decimal
1," X 1"
Y28
a *,+ X 1"
28
, con precisi-n de 28 d5gitos
8os programas de C# utili1an declaraciones de tipo para crear nuevos tipos. 7na declaraci-n de tipo especi0ica
el nombre y los miembros del nuevo tipo. Cinco de las categor5as de tipos de C# son de0inibles por el usuarioG
tipos de clase, tipos de estructura, tipos de inter0a1, tipos de enumeraci-n y tipos de delegado.
7n tipo de clase de0ine una estructura de datos ?ue contiene miembros de datos OcamposR y miembros de
0unci-n Om)todos, propiedades y otrosR. 8os tipos de clase admiten la =erencia simple y el polimor0ismo,
mecanismos mediante los ?ue las clases derivadas pueden ampliar y especiali1ar clases base.
7n tipo de estructura es similar a un tipo de clase en cuanto a ?ue ambas representan una estructura con
miembros de datos y miembros de 0unci-n. 4o obstante, a di0erencia de las clases, las estructuras son tipos de
valores y no re?uieren asignaci-n del mont-n. 8os tipos de estructura no admiten la =erencia especi0icada por el
usuario y =eredan impl5citamente del tipo object.
7n tipo de inter0a1 de0ine un contrato como un con$unto con nombre de miembros de 0unci-n pHblica. 7na clase
o estructura ?ue implementa una inter0a1 debe proporcionar implementaciones de los miembros de 0unci-n de la
inter0a1. 7na inter0a1 puede derivarse de varias inter0aces base, y una clase o estructura puede implementar
varias inter0aces.
7n tipo delegado representa las re0erencias a los m)todos con una lista de par(metros determinada y un tipo de
valor devuelto. 8os delegados permiten tratar m)todos como entidades, ?ue se pueden asignar a las variables y
pasarse como par(metros. 8os delegados son similares al concepto de punteros a 0unci-n de otros lengua$es,
pero al contrario de los punteros a 0unci-n, los delegados est(n orientados a ob$etos y proporcionan seguridad
de tipos.
8os tipos de delegado, inter0a1, estructura y clase admiten gen)ricos, lo ?ue permite su parametri1aci-n con
otros tipos.
7n tipo de enumeraci-n es un tipo distinto con constantes con nombre. Todos los tipos de enumeraci-n tienen
un tipo subyacente, ?ue debe ser uno de los oc=o tipos integrales. El con$unto de valores de un tipo de
enumeraci-n es el mismo ?ue el del con$unto de valores del tipo subyacente.
6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
C# admite matrices unidimensionales y multidimensionales de cual?uier tipo. &l contrario ?ue los tipos
mencionados antes, los tipos de matri1 no tienen ?ue ser declarados antes de poder utili1arse. En su lugar, los
tipos de matri1 se crean mediante un nombre de tipo seguido de corc=etes. 'or e$emplo, int45 es una matri1
unidimensional de int, int45 es una matri1 bidimensional de int e int4545 es una matri1 unidimensional
de matrices unidimensionales de int.
8os tipos ?ue aceptan valores 4788 tampoco tienen ?ue ser declarados antes de poder utili1arse. 'ara cada tipo
de valor 1 ?ue no acepta valores 4788 =ay un tipo correspondiente de valor 17 ?ue acepta valores 4788, el
?ue puede contener un valor null adicional. 'or e$emplo int7 es un tipo ?ue puede contener cual?uier valor
entro de 32 bits o el valor null.
El sistema de tipos de C# est( uni0icado, de manera ?ue un valor de cual?uier tipo puede tratarse como un
ob$eto. Todos los tipos de C# se derivan directa o indirectamente del tipo de clase object, ?ue es la clase base
de0initiva de todos los tipos. 8os valores de los tipos de re0erencia se tratan como ob$etos consider(ndolos
sencillamente como del tipo object. 8os valores de los tipos de valor se tratan como ob$etos mediante la
reali1aci-n de operaciones de conversi-n /o.ing y !n/o.ing. En el e$emplo siguiente, se convierte un valor int
en object y de nuevo en int.
using System;
class 1est
{
static void Main() {
int i + 289;
object o + i; .. :o#ing
int j + (int)o; .. ;nbo#ing
!
!
Cuando un valor de un tipo de valor se convierte en el tipo object, se asigna una instancia de ob$eto, tambi)n
denominada PboxQ, para ?ue contenga el valor, y )ste se copia en dic=a instancia. & la inversa, cuando se
convierte una re0erencia object en un tipo de valor, se comprueba ?ue el ob$eto al ?ue se =ace re0erencia es un
cuadro del tipo con el valor correcto, y si la comprobaci-n se lleva a cabo con )xito, el valor del cuadro se copia
externamente.
El sistema de tipos uni0icado de C# signi0ica en la pr(ctica ?ue los tipos de valor pueden convertirse en
ob$etosPa petici-nQ. 2ebido a la uni0icaci-n, las bibliotecas de uso general ?ue utili1an el tipo object pueden
utili1arse tanto con los tipos de re0erencia como con los tipos de valor.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. (
Especificacin del lenguaje C#
Hay varios tipos de varia/les en C#, entre los ?ue se incluyen campos, elementos de matri1, variables locales y
par(metros. 8as variables representan ubicaciones de almacenamiento, y cada variable tiene un tipo ?ue
determina ?u) valores se pueden almacenar en ella, como se muestra en la tabla siguiente.
Tipo de %ariable 2osible contenido
Tipo de valor ?ue no
acepta valores
4788
7n valor de ese tipo exacto
Tipo de valor ?ue
acepta valores
4788
7n valor 4788 o un valor de ese tipo exacto
object
7na re0erencia nula, una re0erencia a un ob$eto de cual?uier tipo de
re0erencia o una re0erencia a un valor de tipo box de cual?uier tipo
de valor
Tipo de clase 7na re0erencia nula, una re0erencia a una instancia de ese tipo de clase
o una re0erencia a una instancia de una clase derivada de dic=o tipo
de clase
Tipo de inter0a1 7na re0erencia nula, una re0erencia a una instancia de un tipo de clase
?ue implemente dic=o tipo de inter0a1 o una re0erencia a un valor de tipo
box ?ue implemente dic=o tipo de inter0a1
Tipo de matri1 7na re0erencia nula, una re0erencia a una instancia de dic=o tipo de
matri1 o una re0erencia a una instancia de un tipo de matri1 compatible
Tipo delegado 7na re0erencia nula o una re0erencia a una instancia de dic=o tipo
delegado
1.! E"presiones
8as e.presiones se construyen a partir de operandos y operadores. 8os operadores de una expresi-n indican
?u) operaciones se aplican a los operandos. Entre los e$emplos de operadores se incluyen <, =, >, . y ne,.
.on e$emplos de operandos los literales, campos, variables locales y expresiones.
Cuando una expresi-n contiene varios operadores, la prioridad de los operadores controla el orden de
evaluaci-n de los operadores individuales. 'or e$emplo, la expresi-n # < y > ? se evalHa como # < (y > ?)
por?ue el operador > tiene prioridad sobre <.
8a mayor5a de los operadores se pueden so/recargar. 8a sobrecarga de operadores permite utili1ar
implementaciones de operadores de0inidas por el usuario en operaciones en las ?ue al menos uno de los
operandos es de un tipo estructura o clase de0inido por el usuario.
$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En la tabla siguiente se resumen los operadores de C#, enumerando las categor5as en orden de prioridad de
mayor a menorG 8os operadores de la misma categor5a tienen la misma prioridad.
Categor0a Expresin +escripcin
'rincipal
#.m
&cceso a miembros
#(...)
!nvocaci-n de m)todos y delegados
#4...5
%atri1 y acceso del indi1ador
#<<
!ncremento posterior
#==
2ecremento posterior
ne, 1(...)
Creaci-n de ob$etos y de delegados
ne, 1(...){...!
Creaci-n de ob$eto con el iniciali1ador
ne, {...!
!niciali1ador de ob$eto an-nimo
ne, 14...5
Creaci-n de matrices
ty&eo-(1)
/btiene el ob$eto System.1y&e para 1
c"ec(ed(#)
EvalHa la expresi-n en contexto comprobado
unc"ec(ed(#)
EvalHa la expresi-n en contexto no comprobado
de-ault(1)
/btiene el valor predeterminado del tipo 1
delegate {...!
:unci-n an-nima Om)todo an-nimoR
7nario
<#
!dentidad
=#
4egaci-n
@#
4egaci-n l-gica
A#
4egaci-n bit a bit
<<#
!ncremento previo
==#
2ecremento previo
(1)#
Convierte expl5citamente # en el tipo 1
%ultiplicativo
# > y
%ultiplicaci-n
# . y
2ivisi-n
# B y
;esto
.umatorio
# < y
.uma, concatenaci-n de cadenas, combinaci-n de
delegados
# C y
;esta, eliminaci-n de delegados
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. "
Especificacin del lenguaje C#
2espla1amiento
# DD y
2espla1amiento a la i1?uierda
# EE y
2espla1amiento a la derec=a
Comprobaci-n de
tipos y
relacionales
# D y
%enor ?ue
# E y
%ayor ?ue
# D+ y
%enor o igual ?ue
# E+ y
%ayor o igual ?ue
# is 1
2evuelve true si # es 1, de lo contrario, -alse
# as 1
2evuelve # escrito como 1 o null si # no es un 1
!gualdad
# ++ y
!gual
# @+ y
4o igual
&42 l-gico
# F y
&42 bit a bit entero, &42 l-gico booleano
N/; l-gico
# G y
N/; bit a bit entero, N/; l-gico booleano
/; l-gico
# H y
/; bit a bit entero, /; l-gico booleano
&42 condicional
# FF y
EvalHa y s-lo si # es true
/; condicional
# HH y
EvalHa y s-lo si # es -alse
7so combinado de
4ull
I 77 y
.e evalHa como y si # es null, de lo contrario, como
#
Condicional
# 7 y / ?
EvalHa y si # es true, ? si # es -alse
&signaci-n o
0unci-n an-nima
# + y
&signaci-n
# op+ y &signaci-n compuestaV los operadores compatibles son
>+ .+ B+ <+ =+ DD+ EE+ F+ G+ H+
(1 #) +E y
:unci-n an-nima Oexpresi-n lambdaR
1.# Instrucciones
8as acciones de un programa se expresan utili1ando instr!cciones. C# admite varios tipos de instrucciones,
algunos de los cuales se de0inen en t)rminos de instrucciones incrustadas.
7n blo?ue O/loc4R permite escribir varias instrucciones en contextos donde se permite una Hnica instrucci-n. 7n
blo?ue se compone de una lista de instrucciones escrita entre delimitadores { y !.
8as instr!cciones de declaraci,n se utili1an para declarar constantes y variables locales.
8as instr!cciones de e.presi,n se utili1an para evaluar las expresiones. 8as expresiones ?ue pueden utili1arse
como instrucciones incluyen invocaciones de m)todo, asignaciones de ob$etos utili1ando el operador ne,,
asignaciones ?ue usan + operadores de asignaci-n compuesta y operadores de incremento y decremento ?ue
utili1an los operadores << y ==.
8as instr!cciones de selecci,n seleccionan una de las instrucciones ?ue se van a e$ecutar en 0unci-n del valor de
alguna expresi-n. En este grupo est(n las instrucciones i- y s,itc".
8as instr!cciones de iteraci,n se utili1an para e$ecutar repetidamente una instrucci-n incrustada. En este grupo
est(n las instrucciones ,"ile, do, -or y -oreac".
1' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8as instr!cciones de salto se utili1an para trans0erir el control. En este grupo est(n las instrucciones brea(,
continue, goto, t"ro,, return y yield.
8a instrucci-n try...catc" se utili1a para detectar las excepciones ?ue se producen durante la e$ecuci-n de un
blo?ue y la instrucci-n try...-inally se usa para especi0icar el c-digo de 0inali1aci-n ?ue siempre se e$ecuta,
apare1ca o no una excepci-n.
8as instrucciones c"ec(ed y unc"ec(ed se utili1an con el 0in de controlar el contexto de comprobaci-n de
desbordamiento para operaciones aritm)ticas y conversiones.
8a instrucci-n loc( se utili1a para blo?uear un ob$eto determinado mediante exclusi-n mutua, e$ecutar una
instrucci-n y, a continuaci-n, liberar el blo?ueo.
8a instrucci-n using se utili1a para obtener un recurso, e$ecutar una instrucci-n y, a continuaci-n, eliminar
dic=o recurso.
8a tabla siguiente muestra las instrucciones de C# y proporciona un e$emplo para cada una.
Instruccin Eje)plo
2eclaraciones de
variables locales
static void Main() {
int a;
int b + 8 c + 9;
a + 2;
Console.WriteLine(a < b < c);
!
2eclaraciones de
constantes locales
static void Main() {
const -loat &i + 9.2J2KL8M-;
const int r + 8K;
Console.WriteLine(&i > r > r);
!
!nstrucciones de
expresiones
static void Main() {
int i;
i + 289; .. )#&ression statement
Console.WriteLine(i); .. )#&ression statement
i<<; .. )#&ression statement
Console.WriteLine(i); .. )#&ression statement
!
!nstrucci-n i-
static void Main(string45 args) {
i- (args.Lengt" ++ 3) {
Console.WriteLine("No arguments");
!
else {
Console.WriteLine("%ne or more arguments");
!
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 11
Especificacin del lenguaje C#
!nstrucci-n s,itc"
static void Main(string45 args) {
int n + args.Lengt";
s,itc" (n) {
case 3/
Console.WriteLine("No arguments");
brea(;
case 2/
Console.WriteLine("%ne argument");
brea(;
de-ault/
Console.WriteLine("{3! arguments" n);
brea(;
!
!
!
!nstrucci-n ,"ile
static void Main(string45 args) {
int i + 3;
,"ile (i D args.Lengt") {
Console.WriteLine(args4i5);
i<<;
!
!
!nstrucci-n do
static void Main() {
string s;
do {
s + Console.OeadLine();
i- (s @+ null) Console.WriteLine(s);
! ,"ile (s @+ null);
!
!nstrucci-n -or
static void Main(string45 args) {
-or (int i + 3; i D args.Lengt"; i<<) {
Console.WriteLine(args4i5);
!
!
!nstrucci-n -oreac"
static void Main(string45 args) {
-oreac" (string s in args) {
Console.WriteLine(s);
!
!
!nstrucci-n brea(
static void Main() {
,"ile (true) {
string s + Console.OeadLine();
i- (s ++ null) brea(;
Console.WriteLine(s);
!
!
!nstrucci-n
continue
static void Main(string45 args) {
-or (int i + 3; i D args.Lengt"; i<<) {
i- (args4i5.StartsWit"(".")) continue;
Console.WriteLine(args4i5);
!
!
12 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
!nstrucci-n goto
static void Main(string45 args) {
int i + 3;
goto c"ec(;
loo&/
Console.WriteLine(args4i<<5);
c"ec(/
i- (i D args.Lengt") goto loo&;
!
!nstrucci-n return
static int 'dd(int a int b) {
return a < b;
!
static void Main() {
Console.WriteLine('dd(2 8));
return;
!
!nstrucci-n yield
static $)numerableDintE Oange(int -rom int to) {
-or (int i + -rom; i D to; i<<) {
yield return i;
!
yield brea(;
!
static void Main() {
-oreac" (int # in Oange(=2323)) {
Console.WriteLine(#);
!
!
!nstrucciones t"ro,
y try
static double 6ivide(double # double y) {
i- (y ++ 3) t"ro, ne, 6ivide:yPero)#ce&tion();
return # . y;
!
static void Main(string45 args) {
try {
i- (args.Lengt" @+ 8) {
t"ro, ne, )#ce&tion("1,o numbers reQuired");
!
double # + double.*arse(args435);
double y + double.*arse(args425);
Console.WriteLine(6ivide(# y));
!
catc" ()#ce&tion e) {
Console.WriteLine(e.Message);
!
-inally {
Console.WriteLine(RSood bye@T);
!
!
!nstrucciones
c"ec(ed y
unc"ec(ed
static void Main() {
int i + int.Ma#Ualue;
c"ec(ed {
Console.WriteLine(i < 2); .. )#ce&tion
!
unc"ec(ed {
Console.WriteLine(i < 2); .. %ver-lo,
!
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 13
Especificacin del lenguaje C#
!nstrucci-n loc(
class 'ccount
{
decimal balance;
&ublic void Wit"dra,(decimal amount) {
loc( (t"is) {
i- (amount E balance) {
t"ro, ne, )#ce&tion("$nsu--icient -unds");
!
balance =+ amount;
!
!
!
!nstrucci-n using
static void Main() {
using (1e#tWriter , + Vile.Create1e#t("test.t#t")) {
,.WriteLine("Line one");
,.WriteLine("Line t,o");
,.WriteLine("Line t"ree");
!
!
1.$ %lases y objetos
8as clases son el tipo m(s importante de C#. 7na clase es una estructura de datos ?ue combina estados OcamposR
y acciones Om)todos y otros miembros de 0unci-nR en una unidad Hnica. 7na clase proporciona una de0inici-n
para las instancias de la clase creadas din(micamente, tambi)n conocidas como o/1etos. 8as clases admiten la
herencia y el poliorfiso, mecanismos mediante los ?ue una clase derivada puede ampliar y especiali1ar una
clase /ase.
8as clases nuevas se crean utili1ando declaraciones de clase. 8as declaraciones de clase se inician con un
encabe1ado ?ue especi0ica los atributos y modi0icadores de la clase, el nombre, la clase base Osi se conoceR y las
inter0aces implementadas por ella. El encabe1ado va seguido por el cuerpo de la clase, ?ue consiste en una lista
de declaraciones de miembros escritas entre los delimitadores { y !.
8a siguiente es una declaraci-n de una clase simple denominada *ointG
&ublic class *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
8as instancias de clases se crean utili1ando el operador ne,, ?ue asigna memoria para una nueva instancia,
invoca un constructor para iniciali1ar la instancia y devuelve una re0erencia a la misma. 8as instrucciones
siguientes crean dos ob$etos *oint y almacenan las re0erencias a dic=os ob$etos en dos variablesG
*oint &2 + ne, *oint(3 3);
*oint &8 + ne, *oint(23 83);
8a memoria ocupada por un ob$eto se reclama autom(ticamente cuando el ob$eto de$a de estar en uso. 4o es
posible ni necesario desasignar expl5citamente ob$etos en C#.
1.$.1 &iembros
8os miembros de una clase son o ie/ros est5ticos o ie/ros de instancia. 8os miembros est(ticos
pertenecen a las clases y los miembros de instancia pertenecen a los ob$etos Oinstancias de clasesR.
1# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a tabla siguiente proporciona in0ormaci-n general sobre los tipos de miembros ?ue puede contener una clase.
*ie)bro +escripcin
Constantes >alores constantes asociados a la clase
Campos >ariables de la clase
%)todos C(lculos y acciones ?ue puede reali1ar la clase
'ropiedades &cciones asociadas a la lectura y escritura de propiedades con nombre de la clase
!ndi1adores &cciones asociadas a instancias de indi1aci-n de la clase como una matri1
Eventos 4oti0icaciones ?ue pueden ser generadas por la clase
/peradores Conversiones y operadores de expresi-n admitidos por la clase
Constructores &cciones re?ueridas para iniciali1ar instancias de la clase o la propia clase
2estructores &cciones ?ue =ay ?ue llevar a cabo antes de ?ue las instancias de la clase sean
descartadas de 0orma permanente
Tipos Tipos anidados declarados por la clase
1.$.2 'ccesibilidad
Cada miembro de una clase tiene asociada una accesibilidad, ?ue controla las regiones del texto del programa a
las ?ue tiene acceso el miembro. Existen cinco 0ormas posibles de accesibilidad. Zstas se resumen en la
siguiente tabla.
,ccesibilidad 3ignificado
&ublic
&cceso no limitado
&rotected
&cceso limitado a esta clase o a las clases derivadas de la misma
internal
&cceso limitado a este programa
&rotected internal
&cceso limitado a este programa o a las clases derivadas de la misma
&rivate
&cceso limitado a esta clase
1.$.3 (ar)metros de tipo
7na de0inici-n de clase puede especi0icar con$unto de par(metros de tipo si a continuaci-n del nombre de clase
se colocan corc=etes angulares ?ue contengan una lista con los nombres de los par(metros de tipo. 8os
par(metros de tipo se pueden utili1ar dentro de las declaraciones de clase para de0inir a los miembros de la clase.
En el e$emplo siguiente los par(metros de tipo de *air son 1Virst y 1Second/
&ublic class *airD1Virst1SecondE
{
&ublic 1Virst Virst;
&ublic 1Second Second;
!
7n tipo de clase declarado para incluir par(metros de tipo se denomina tipo de clase gen)rico. 8os tipos struct,
inter0ace y delegate tambi)n pueden ser gen)ricos.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1!
Especificacin del lenguaje C#
Cuando se usa la clase gen)rica, se deben proporcionar argumentos de tipo para cada par(metro de tipo.
*airDintstringE &air + ne, *airDintstringE { Virst + 2 Second + Rt,oT !;
int i + &air.Virst; .. 1Virst is int
string s + &air.Second; .. 1Second is string
7n tipo gen)rico con los argumentos de tipo proporcionados, como *airDintstringE en el e$emplo
anterior, se denomina tipo construido.
1.$.! %lases base
7na declaraci-n de clase puede especi0icar una clase base si a continuaci-n del nombre de clase y los
par(metros de tipo se colocan dos puntos y el nombre de la clase base. /mitir una especi0icaci-n de clase base
es igual ?ue derivar del tipo object. En el e$emplo siguiente, la clase base de *oint96 es *oint, y la clase
base de *oint es objectG
&ublic class *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
&ublic class *oint96/ *oint
{
&ublic int ?;
&ublic *oint96(int # int y int ?)/ base(# y) {
t"is.? + ?;
!
!
8as clases =eredan los miembros de sus clases base. 8a =erencia signi0ica ?ue una clase contiene impl5citamente
todos los miembros de su clase base, salvo los constructores de la clase base. 7na clase derivada puede agregar
nuevos miembros a los =eredados, pero no puede ?uitar la de0inici-n de un miembro =eredado. En el e$emplo
anterior, *oint96 =ereda los campos # e y de *oint, y cada instancia de *oint96 contiene tres campos
#, y y ?.
Existe una conversi-n impl5cita desde un tipo de clase a cual?uiera de sus tipos de clase base. 'or consiguiente,
una variable de un tipo de clase puede =acer re0erencia a una instancia de dic=a clase o a una instancia de
cual?uier clase derivada. 'or e$emplo, teniendo en cuenta las declaraciones de clase anteriores, una variable de
tipo *oint puede =acer re0erencia a un *oint o a un *oint96G
*oint a + ne, *oint(23 83);
*oint b + ne, *oint96(23 83 93);
1.$.# %ampos
7n campo es una variable ?ue est( asociada a una clase o a una instancia de una clase.
7n campo declarado con el modi0icador static de0ine un capo est5tico. 7n campo est(tico identi0ica
exactamente una ubicaci-n de almacenamiento. !ndependientemente del nHmero de instancias ?ue se creen de
una clase, s-lo =abr( una copia de un campo est(tico.
7n campo declarado sin el modi0icador static de0ine un capo de instancia. Todas las instancias de una
clase contienen una copia independiente de todos los campos de instancia de esa clase.
En el e$emplo siguiente, cada instancia de la clase Color tiene una copia independiente de los campos de
instancia r, g y b, pero s-lo =ay una copia de los campos est(ticos :lac(, W"ite, Oed, Sreen y :lueG
16 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
&ublic class Color
{
&ublic static readonly Color :lac( + ne, Color(3 3 3);
&ublic static readonly Color W"ite + ne, Color(8KK 8KK 8KK);
&ublic static readonly Color Oed + ne, Color(8KK 3 3);
&ublic static readonly Color Sreen + ne, Color(3 8KK 3);
&ublic static readonly Color :lue + ne, Color(3 3 8KK);
&rivate byte r g b;
&ublic Color(byte r byte g byte b) {
t"is.r + r;
t"is.g + g;
t"is.b + b;
!
!
Como se puede ver en el e$emplo anterior, los capos de s,lo lect!ra se pueden declarar con un modi0icador
readonly. .olamente se pueden reali1ar asignaciones a un campo readonly como parte de la declaraci-n del
campo o en un constructor en la misma clase.
1.$.$ &*todos
7n 6todo es un miembro ?ue implementa un c(lculo o una acci-n ?ue puede reali1ar un ob$eto o una clase. El
acceso a los 6todos est5ticos se obtiene a trav)s de la clase. .e tiene acceso a los 6todos de instancia a trav)s
de las instancias de la clase.
8os m)todos tienen una lista Oposiblemente vac5aR de par5etros, ?ue representa valores o re0erencias variables
?ue se pasan al m)todo y un tipo de valor dev!elto ?ue especi0ica el tipo del valor calculado y devuelto por el
m)todo. El tipo de valor devuelto de un m)todo es void si no devuelve ningHn valor.
&l igual ?ue los tipos, los m)todos tambi)n pueden tener un con$unto de par(metros de tipo, para los ?ue se
deben especi0icar argumentos de tipo cuando se llama al m)todo. & di0erencia de los tipos, los argumentos de
tipo por lo general se pueden in0erir a partir de los argumentos de una llamada de m)todo y no necesitan darse
de manera expl5cita.
8a fira de un m)todo debe ser Hnica en la clase en la ?ue se declara el m)todo. 8a 0irma de un m)todo se
compone del nombre del m)todo, el nHmero de par(metros de tipo, as5 como del nHmero, modi0icadores y tipos
de sus par(metros. 8a 0irma de un m)todo no incluye el tipo de valor devuelto.
1.6.6.1 Parmetros
8os par(metros se utili1an para pasar valores o re0erencias variables a los m)todos. 8os par(metros de un
m)todo reciben sus valores reales de los arg!entos ?ue se especi0ican cuando se invoca el m)todo. Existen
cuatro clases de par(metrosG par(metros de valores, par(metros de re0erencias, par(metros de salida y matrices
de par(metros.
'ara pasar el par(metro de entrada se utili1a un par5etro de valor. 7n par(metro de valor corresponde a una
variable local ?ue obtiene su valor inicial del argumento proporcionado para el par(metro. 8as modi0icaciones
de un par(metro de valor no a0ectan al argumento proporcionado para el par(metro.
7n par5etro de referencia se utili1a tanto para proporcionar par(metros de entrada como de salida. El
argumento pasado para un par(metro de re0erencia debe ser una variable, y durante la e$ecuci-n del m)todo, el
par(metro de re0erencia representa la misma ubicaci-n de almacenamiento ?ue la variable del argumento. 8os
par(metros de re0erencia se declaran con el modi0icador re-. El e$emplo siguiente ilustra el uso de los
par(metros re-.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1(
Especificacin del lenguaje C#
using System;
class 1est
{
static void S,a&(re- int # re- int y) {
int tem& + #;
# + y;
y + tem&;
!
static void Main() {
int i + 2 j + 8;
S,a&(re- i re- j);
Console.WriteLine("{3! {2!" i j); .. %ut&uts "8 2"
!
!
'ara pasar par(metros de salida se utili1a un par5etro de salida. 7n par(metro de salida es similar a un
par(metro de re0erencia, excepto en ?ue el valor inicial del argumento suministrado por el llamador no es
importante. 8os par(metros de salida se declaran con un modi0icador out. El e$emplo siguiente ilustra el uso de
los par(metros out.
using System;
class 1est
{
static void 6ivide(int # int y out int result out int remainder) {
result + # . y;
remainder + # B y;
!
static void Main() {
int res rem;
6ivide(23 9 out res out rem);
Console.WriteLine("{3! {2!" res rem); .. %ut&uts "9 2"
!
!
7na atri- de par5etros permite pasar un nHmero variable de argumentos a un m)todo. 7na matri1 de
par(metros se declara con un modi0icador &arams. .-lo el Hltimo par(metro de un m)todo puede ser una matri1
de par(metros y el tipo de una matri1 de par(metros debe ser un tipo de matri1 unidimensional. 8os m)todos
Write y WriteLine de la clase System.Console son buenos e$emplos del uso de una matri1 de par(metros.
.e declaran del siguiente modoG
&ublic class Console
{
&ublic static void Write(string -mt &arams object45 args) {...!
&ublic static void WriteLine(string -mt &arams object45 args) {...!
...
!
2entro de un m)todo ?ue utili1a una matri1 de par(metros, la matri1 de par(metros se comporta exactamente
como un par(metro normal de un tipo de matri1. .in embargo, en una invocaci-n de un m)todo con una matri1
de par(metros, es posible pasar un argumento Hnico del tipo de matri1 de par(metros o cual?uier nHmero de
argumentos del tipo elemento de la matri1 de par(metros. En este Hltimo caso, se crea autom(ticamente una
instancia de matri1 y se iniciali1a con los argumentos especi0icados. Este e$emplo
Console.WriteLine("#+{3! y+{2! ?+{8!" # y ?);
e?uivale a escribir lo siguiente.
1$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
string s + "#+{3! y+{2! ?+{8!";
object45 args + ne, object495;
args435 + #;
args425 + y;
args485 + ?;
Console.WriteLine(s args);
1.6.6.2 Cuerpo del mtodo y variables locales
El cuerpo de un m)todo especi0ica las instrucciones ?ue se deben e$ecutar cuando se invo?ue el m)todo.
7n cuerpo del m)todo puede declarar variables espec50icas para la invocaci-n del m)todo. Tales variables se
denominan varia/les locales. 7na declaraci-n de variable local especi0ica un nombre de tipo, un nombre de
variable y posiblemente un valor inicial. El e$emplo siguiente declara una variable local i con un valor inicial de
cero y una variable local j sin valor inicial.
using System;
class SQuares
{
static void Main() {
int i + 3;
int j;
,"ile (i D 23) {
j + i > i;
Console.WriteLine("{3! # {3! + {2!" i j);
i + i < 2;
!
!
!
C# exige ?ue las variables locales est)n definitivaente asignadas para ?ue se puedan obtener sus valores. 'or
e$emplo, si la declaraci-n de i anterior no incluyera un valor inicial, el compilador noti0icar5a un error para la
utili1aci-n subsiguiente de i, por?ue i no estar5a de0initivamente asignada en dic=os puntos del programa.
7n m)todo puede utili1ar instrucciones return para devolver el control a su llamador. En un m)todo ?ue
devuelve void, las instrucciones return no pueden especi0icar una expresi-n. En un m)todo ?ue no devuelve
void, las instrucciones return deben incluir una expresi-n ?ue calcule el valor devuelto.
1.6.6.3 Mtodos estticos y de instancia
7n m)todo declarado con un modi0icador static es un 6todo est5tico. 7n m)todo est(tico no 0unciona en
una instancia espec50ica y s-lo tiene acceso directamente a miembros est(ticos.
7n m)todo declarado sin un modi0icador static es un 6todo de instancia. 8os m)todos de instancia
0uncionan en instancias espec50icas y pueden tener acceso tanto a miembros est(ticos como a los de instancia. .e
puede tener acceso expl5citamente a la instancia en la ?ue se invoc- un m)todo de instancia como t"is. Es
incorrecto =acer re0erencia a t"is en un m)todo est(tico.
8a clase )ntity siguiente tiene tanto miembros est(ticos como de instancia.
class )ntity
{
static int ne#tSerialNo;
int serialNo;
&ublic )ntity() {
serialNo + ne#tSerialNo<<;
!
&ublic int SetSerialNo() {
return serialNo;
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1"
Especificacin del lenguaje C#
&ublic static int SetNe#tSerialNo() {
return ne#tSerialNo;
!
&ublic static void SetNe#tSerialNo(int value) {
ne#tSerialNo + value;
!
!
Cada instancia )ntity contiene un nHmero de serie Oy probablemente alguna otra in0ormaci-n ?ue no se
muestra a?u5R. El constructor )ntity O?ue es como un m)todo de instanciaR iniciali1a la nueva instancia con el
siguiente nHmero de serie disponible. 2ado ?ue el constructor es un miembro de instancia, se puede tener acceso
tanto al campo de instancia serialNo como al campo est(tico ne#tSerialNo.
8os m)todos est(ticos SetNe#tSerialNo y SetNe#tSerialNo pueden tener acceso al campo est(tico
ne#tSerialNo, pero ser5a incorrecto ?ue tuvieran acceso directamente al campo de instancia serialNo.
En el e$emplo siguiente se muestra el uso de la clase )ntity.
using System;
class 1est
{
static void Main() {
)ntity.SetNe#tSerialNo(2333);
)ntity e2 + ne, )ntity();
)ntity e8 + ne, )ntity();
Console.WriteLine(e2.SetSerialNo()); .. %ut&uts "2333"
Console.WriteLine(e8.SetSerialNo()); .. %ut&uts "2332"
Console.WriteLine()ntity.SetNe#tSerialNo()); .. %ut&uts "2338"
!
!
Tenga en cuenta ?ue los m)todos est(ticos SetNe#tSerialNo y SetNe#tSerialNo se invocan en la clase,
mientras ?ue el m)todo de instancia SetSerialNo se invoca en las instancias de la clase.
1.6.6.4 Mtodos virtuales, de invalidacin y abstractos
Cuando una declaraci-n de m)todo de instancia incluye un modi0icador virtual, se dice ?ue el m)todo es un
6todo virt!al. .i no existe un modi0icador virtual, se dice ?ue el m)todo es un 6todo no virt!al.
En la invocaci-n de un m)todo virtual, el tipo en tiepo de e1ec!ci,n de la instancia para la ?ue tiene lugar la
invocaci-n determina la implementaci-n del m)todo real ?ue se va a invocar. Cuando se invoca a un m)todo no
virtual, el 0actor determinante es el tipo en tiepo de copilaci,n de la instancia.
En las clases derivadas, los m)todos virtuales se pueden invalidar. Cuando una declaraci-n del m)todo de
instancia incluye un modi0icador override, el m)todo invalida un m)todo virtual =eredado con la misma
0irma. %ientras ?ue una declaraci-n de m)todo virtual introdce un m)todo nuevo, una declaraci-n de m)todo
de invalidaci-n especiali0a un m)todo virtual =eredado existente proporcionando una nueva implementaci-n de
ese m)todo.
7n m)todo a/stract es un m)todo virtual sin implementaci-n. 8os m)todos abstractos se declaran con el
modi0icador abstract y s-lo se permiten en una clase ?ue tambi)n se declare como abstract. 8os m)todos
abstractos deben invalidarse en cada clase derivada no abstracta.
El e$emplo siguiente declara una clase abstracta, )#&ression, ?ue representa un nodo de (rbol de expresi-n y
tres clases derivadas Constant, UariableOe-erence y %&eration, ?ue implementan los nodos de (rbol de
expresi-n para las constantes, re0erencias variables y operaciones aritm)ticas. OEsto es similar a los tipos de
(rbol de expresiones introducidos en la secci-n [4.#, aun?ue no debe con0undirse con los mismosR.
2' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
using System;
using System.Collections;
&ublic abstract class )#&ression
{
&ublic abstract double )valuate(Has"table vars);
!
&ublic class Constant/ )#&ression
{
double value;
&ublic Constant(double value) {
t"is.value + value;
!
&ublic override double )valuate(Has"table vars) {
return value;
!
!
&ublic class UariableOe-erence/ )#&ression
{
string name;
&ublic UariableOe-erence(string name) {
t"is.name + name;
!
&ublic override double )valuate(Has"table vars) {
object value + vars4name5;
i- (value ++ null) {
t"ro, ne, )#ce&tion(";n(no,n variable/ " < name);
!
return Convert.1o6ouble(value);
!
!
&ublic class %&eration/ )#&ression
{
)#&ression le-t;
c"ar o&;
)#&ression rig"t;
&ublic %&eration()#&ression le-t c"ar o& )#&ression rig"t) {
t"is.le-t + le-t;
t"is.o& + o&;
t"is.rig"t + rig"t;
!
&ublic override double )valuate(Has"table vars) {
double # + le-t.)valuate(vars);
double y + rig"t.)valuate(vars);
s,itc" (o&) {
case W<W/ return # < y;
case W=W/ return # = y;
case W>W/ return # > y;
case W.W/ return # . y;
!
t"ro, ne, )#ce&tion(";n(no,n o&erator");
!
!
8as cuatro clases anteriores se pueden utili1ar para modelar expresiones aritm)ticas. 'or e$emplo, utili1ando
instancias de estas clases, la expresi-n # < 9 se puede representar como sigue.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 21
Especificacin del lenguaje C#
)#&ression e + ne, %&eration(
ne, UariableOe-erence("#")
W<W
ne, Constant(9));
El m)todo )valuate de una instancia )#&ression se invoca para evaluar la expresi-n determinada y generar
un valor double. El m)todo toma como argumento un Has"table ?ue contiene nombres de variable Ocomo
claves de las entradasR y valores Ocomo valores de las entradasR. El m)todo )valuate es un m)todo abstracto
virtual, lo ?ue signi0ica ?ue deben invalidarlo las clases derivadas no abstractas para proporcionar una
implementaci-n real.
7na implementaci-n de Constant de )valuate simplemente devuelve la constante almacenada. 7na
implementaci-n de UariableOe-erence busca el nombre de la variable en la tabla =as= y devuelve el valor
resultante. 7na implementaci-n de %&eration evalHa primero los operandos i1?uierdo y derec=o Oinvocando
de 0orma recursiva sus m)todos )valuateR y, a continuaci-n, lleva a cabo la operaci-n aritm)tica
correspondiente.
El programa siguiente utili1a las clases )#&ression para evaluar la expresi-n # > (y < 8) para distintos
valores de # e y.
using System;
using System.Collections;
class 1est
{
static void Main() {
)#&ression e + ne, %&eration(
ne, UariableOe-erence("#")
W>W
ne, %&eration(
ne, UariableOe-erence("y")
W<W
ne, Constant(8)
)
);
Has"table vars + ne, Has"table();
vars4"#"5 + 9;
vars4"y"5 + K;
Console.WriteLine(e.)valuate(vars)); .. %ut&uts "82"
vars4"#"5 + 2.K;
vars4"y"5 + L;
Console.WriteLine(e.)valuate(vars)); .. %ut&uts "2X.K"
!
!
1.6.6. !obrecar"a de mtodos
8a so/recarga de m)todos permite ?ue varios m)todos de la misma clase tengan el mismo nombre siempre ?ue
sus 0irmas sean Hnicas. &l compilar una invocaci-n de un m)todo sobrecargado, el compilador utili1a la
resol!ci,n de so/recarga para determinar el m)todo concreto ?ue se va a invocar. 8a resoluci-n de sobrecarga
busca el m)todo ?ue me$or se a$usta a los argumentos o in0orma de un error si no se puede encontrar ningHn
a$uste adecuado. El e$emplo siguiente muestra la resoluci-n de sobrecarga en vigor. El comentario para cada
invocaci-n en el m)todo Main muestra ?u) m)todo se =a invocado.
class 1est
{
static void V() {
Console.WriteLine("V()");
!
22 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
static void V(object #) {
Console.WriteLine("V(object)");
!
static void V(int #) {
Console.WriteLine("V(int)");
!
static void V(double #) {
Console.WriteLine("V(double)");
!
static void VD1E(1 #) {
Console.WriteLine("VD1E(1)");
!
static void V(double # double y) {
Console.WriteLine("V(double double)");
!
static void Main() {
V(); .. $nvo(es V()
V(2); .. $nvo(es V(int)
V(2.3); .. $nvo(es V(double)
V("abc"); .. $nvo(es V(object)
V((double)2); .. $nvo(es V(double)
V((object)2); .. $nvo(es V(object)
VDintE(2); .. $nvo(es VD1E(1)
V(2 2); .. $nvo(es V(double double) !
!
Como muestra el e$emplo, un m)todo determinado siempre puede ser seleccionado convirtiendo expl5citamente
los argumentos en los tipos de par(metros exactos yTo proporcionando expl5citamente los argumentos de tipo.
1.$.+ ,tros miembros de funcin
8os miembros ?ue contienen c-digo e$ecutable se conocen colectivamente como ie/ros de f!nci,n de una
clase. 8a secci-n anterior describe m)todos, ?ue son el tipo primario de miembros de 0unci-n. En esta secci-n se
describen los otros tipos de miembros de 0unci-n admitidos por C#G constructores, propiedades, indi1adores,
eventos, operadores y destructores.
8a tabla siguiente muestra una clase gen)rica llamada ListD1E ?ue implementa una lista creciente de ob$etos.
8a clase contiene varios e$emplos de los tipos m(s comunes de miembros de 0unci-n.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 23
Especificacin del lenguaje C#
&ublic class ListD1E
{
const int de-aultCa&acity + J;
Constante
145 items;
int count;
Campos
&ublic List()/ t"is(de-aultCa&acity) {!
&ublic List(int ca&acity) {
items + ne, 14ca&acity5;
!
Constructores
&ublic int Count {
get { return count; !
!
&ublic int Ca&acity {
get {
return items.Lengt";
!
set {
i- (value D count) value + count;
i- (value @+ items.Lengt") {
145 ne,$tems + ne, 14value5;
'rray.Co&y(items 3 ne,$tems 3 count);
items + ne,$tems;
!
!
!
'ropiedades
&ublic 1 t"is4int inde#5 {
get {
return items4inde#5;
!
set {
items4inde#5 + value;
%nC"anged();
!
!
!ndi1ador
&ublic void 'dd(1 item) {
i- (count ++ Ca&acity) Ca&acity + count > 8;
items4count5 + item;
count<<;
%nC"anged();
!
&rotected virtual void %nC"anged() {
i- (C"anged @+ null) C"anged(t"is )vent'rgs.)m&ty);
!
&ublic override bool )Quals(object ot"er) {
return )Quals(t"is ot"er as ListD1E);
!
static bool )Quals(ListD1E a ListD1E b) {
i- (a ++ null) return b ++ null;
i- (b ++ null HH a.count @+ b.count) return -alse;
-or (int i + 3; i D a.count; i<<) {
i- (@object.)Quals(a.items4i5 b.items4i5)) {
return -alse;
!
!
return true;
!
%)todos
2# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
&ublic event )ventHandler C"anged;
Evento
&ublic static bool o&erator ++(ListD1E a ListD1E b) {
return )Quals(a b);
!
&ublic static bool o&erator @+(ListD1E a ListD1E b) {
return @)Quals(a b);
!
/peradores
!
1.6.#.1 Constructores
C# admite tanto constructores de instancia como est(ticos. 7n constr!ctor de instancia es un miembro ?ue
implementa las acciones ?ue se re?uieren para iniciali1ar una instancia de una clase. 7n constr!ctor est5tico es
un miembro ?ue implementa las acciones exigidas para iniciali1ar una clase cuando se carga por primera ve1.
7n constructor se declara como m)todo sin devoluci-n de tipo y con el mismo nombre ?ue la clase contenedora.
.i una declaraci-n de un constructor incluye un modi0icador static, declara un constructor est(tico. 2e lo
contrario, declara un constructor de instancia.
8os constructores de instancia se pueden sobrecargar. 'or e$emplo, la clase ListD1E declara dos constructores
de instancia, uno sin par(metros y otro ?ue toma un par(metro int. 8os constructores de instancia se invocan
utili1ando el operador ne,. 8as siguientes instrucciones asignan dos instancias ListDstringE utili1ando cada
uno de los constructores de la clase List.
ListDstringE list2 + ne, ListDstringE();
ListDstringE list8 + ne, ListDstringE(23);
&l contrario ?ue otros miembros, los constructores de instancia no se =eredan, y una clase s-lo tiene los
constructores de instancia realmente declarados en la clase. .i no se suministra ningHn constructores de
instancia para una clase, se proporcionar( autom(ticamente uno vac5o sin par(metros.
1.6.#.2 Propiedades
8as propiedades son una extensi-n natural de los campos. 8os dos son miembros denominados con tipos
asociados, y la sintaxis ?ue se utili1a para el acceso a campos y propiedades es la misma. 4o obstante, a
di0erencia de los campos, las propiedades no denotan ubicaciones de almacenamiento. 8as propiedades tienen
descriptores de acceso ?ue especi0ican las instrucciones ?ue deben e$ecutarse para leer o escribir sus valores.
7na propiedad se declara como un campo, s-lo ?ue la declaraci-n 0inali1a con un descriptor de acceso get yTo
un descriptor de acceso set escrito entre los delimitadores { y ! en lugar de 0inali1ar con un punto y coma. 7na
propiedad ?ue tiene un descriptor de acceso get y un set es una propiedad de lect!ra y escrit!ra, una
propiedad ?ue tiene s-lo un descriptor de acceso get es una propiedad de s,lo lect!ra, y una propiedad ?ue
tiene s-lo un descriptor de acceso set es una propiedad de s,lo escrit!ra.
7n descriptor de acceso get corresponde a un m)todo sin par(metros ?ue devuelve un valor del tipo de la
propiedad. Exceptuando cuando se trata del destino de una asignaci-n, al =acer re0erencia a una propiedad en
una expresi-n, se invoca al descriptor de acceso get de la propiedad para calcular su valor.
7n descriptor de acceso set corresponde a un m)todo con un par(metro Hnico denominado value y ningHn
tipo de valor devuelto. Cuando se =ace re0erencia a una propiedad como el destino de una asignaci-n o como el
operando de << o ==, se invoca al descriptor de acceso set con un argumento ?ue proporciona el nuevo valor.
8a clase ListD1E declara dos propiedades, Count y Ca&acityV la primera de ellas es de s-lo lectura y la
segunda de lectura y escritura. El siguiente es un e$emplo del uso de estas propiedades.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2!
Especificacin del lenguaje C#
ListDstringE names + ne, ListDstringE();
names.Ca&acity + 233; .. $nvo(es set accessor
int i + names.Count; .. $nvo(es get accessor
int j + names.Ca&acity; .. $nvo(es get accessor
&l igual ?ue los campos y m)todos, C# admite tanto las propiedades de instancia como las propiedades
est(ticas. 8as propiedades est(ticas se declaran con el modi0icador static, y las propiedades de instancias,
sin )l.
8os descriptores de acceso de una propiedad pueden ser virtuales. Cuando una declaraci-n de propiedad incluye
un modi0icador virtual, abstract u override, se aplica a los descriptores de acceso de la propiedad.
1.6.#.3 $ndi%adores
7n indi-ador es un miembro ?ue permite indi1ar ob$etos de la misma manera ?ue una matri1. 7n indi1ador se
declara como una propiedad, salvo en ?ue el nombre del miembro sea t"is seguido de una lista de par(metros
escritos entre delimitadores 4 y 5. 8os par(metros est(n disponibles en los descriptores de acceso del indi1ador.
&l igual ?ue las propiedades, los indi1adores pueden ser de lectura y escritura, de s-lo lectura y de s-lo
escritura, y los descriptores de acceso de un indi1ador pueden ser virtuales.
8a clase List declara un indi1ador de lectura y escritura Hnico ?ue toma un par(metro int. El indi1ador
permite indi1ar instancias List con valores int. 'or e$emploG
ListDstringE names + ne, ListDstringE();
names.'dd("Li?");
names.'dd("Mart"a");
names.'dd(":et"");
-or (int i + 3; i D names.Count; i<<) {
string s + names4i5;
names4i5 + s.1o;&&er();
!
8os indi1adores se pueden sobrecargar, lo ?ue signi0ica ?ue pueden declararse varios indi1adores siempre
y cuando sus par(metros di0ieran en nHmero o tipos.
1.6.#.4 &ventos
7n evento es un miembro ?ue permite a una clase u ob$eto proporcionar noti0icaciones. 7n evento se declara
como un campo, salvo ?ue la declaraci-n incluya una palabra clave event y el tipo deba ser un tipo delegado.
En una clase ?ue declara un miembro de evento, el evento se comporta como un campo de un tipo delegado
Osiempre ?ue el evento no sea abstracto y no declare descriptores de accesoR. El campo almacena una re0erencia
a un delegado ?ue representa los controladores de eventos ?ue se =an agregado al evento. .i no =ay ningHn
controlador de eventos presente, el campo es null.
8a clase ListD1E declara un miembro de evento Hnico llamado C"anged, ?ue indica ?ue se =a agregado un
nuevo elemento a la lista. El m)todo virtual %nC"anged inicia el evento C"anged comprobando previamente
?ue el evento es null Olo ?ue signi0ica ?ue no =ay ningHn controlador presenteR. 8a noci-n de iniciar un evento
e?uivale exactamente a invocar el delegado representado por el eventoV por lo tanto, no =ay construcciones
especiales del lengua$e para producir eventos.
8os clientes reaccionan a los eventos a trav)s de los controladores de eventos. 8os controladores de eventos se
asocian utili1ando el operador <+ y se ?uitan utili1ando el operador =+. El e$emplo siguiente asocia un
controlador de eventos al evento C"anged deListDstringE.
26 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
using System;
class 1est
{
static int c"angeCount;
static void ListC"anged(object sender )vent'rgs e) {
c"angeCount<<;
!
static void Main() {
ListDstringE names + ne, ListDstringE();
names.C"anged <+ ne, )ventHandler(ListC"anged);
names.'dd("Li?");
names.'dd("Mart"a");
names.'dd(":et"");
Console.WriteLine(c"angeCount); .. %ut&uts "9"
!
!
'ara escenarios avan1ados donde se busca el control del almacenamiento subyacente de un evento, una
declaraci-n de evento puede proporcionar expl5citamente descriptores de acceso add y remove ?ue en cierto
modo son similares al descriptor de acceso set de una propiedad.
1.6.#. 'peradores
7n operador es un miembro ?ue de0ine el signi0icado de aplicar un operador de expresi-n determinado a las
instancias de una clase. 'ueden de0inirse tres categor5as de operadoresG operadores unarios, operadores binarios
y operadores de conversi-n. Todos los operadores deber(n declararse como &ublic y static.
8a clase ListD1E declara dos operadores o&erator++ y o&erator@+, proporcionando de este modo un
nuevo signi0icado a expresiones ?ue aplican dic=os operadores a instancias List. Espec50icamente, los
operadores de0inen la igualdad de dos instancias ListD1E comparando todos los ob$etos contenidos ?ue utili1an
sus m)todos )Quals. El e$emplo siguiente utili1a el operador ++ para comparar dos instancias ListDintE.
using System;
class 1est
{
static void Main() {
ListDintE a + ne, ListDintE();
a.'dd(2);
a.'dd(8);
ListDintE b + ne, ListDintE();
b.'dd(2);
b.'dd(8);
Console.WriteLine(a ++ b); .. %ut&uts "1rue"
b.'dd(9);
Console.WriteLine(a ++ b); .. %ut&uts "Valse"
!
!
El resultado del primer Console.WriteLine es 1rue por?ue las dos listas contienen el mismo nHmero de
ob$etos con los mismos valores en el mismo orden. .i ListD1Eno de0iniera o&erator++, el primer
Console.WriteLine =abr5a generado Valse por?ue a y b =acen re0erencia a dos instancias ListDintE
di0erentes.
1.6.#.6 (estructores
7n destr!ctor es un miembro ?ue implementa las acciones necesarias para destruir una instancia de una clase.
8os destructores no pueden tener par(metros, no pueden tener modi0icadores de accesibilidad y no se pueden
invocar de 0orma expl5cita. El destructor de una instancia se invoca autom(ticamente durante la recolecci-n de
elementos no utili1ados.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2(
Especificacin del lenguaje C#
El recolector de elementos no utili1ados tiene una amplia libertad para decidir cu(ndo debe recolectar ob$etos y
e$ecutar destructores. En concreto, el control de tiempo de las invocaciones del destructor no es determinista y
los destructores se pueden e$ecutar en cual?uier subproceso. 'or estas y otras ra1ones, las clases s-lo deber5an
implementar los destructores cuando no es 0actible ninguna otra soluci-n.
8a instrucci-n using constituye una alternativa m(s recomendable para la destrucci-n de ob$etos.
1.+ Estructuras
Como las clases, las str!cts son estructuras de datos ?ue pueden contener miembros de datos y miembros de
0unci-n, pero al contrario ?ue las clases, las estructuras son tipos de valor y no re?uieren asignaci-n del mont-n.
7na variable de un tipo de estructura almacena directamente los datos de la estructura, mientras ?ue una variable
de un tipo de clase almacena una re0erencia a un ob$eto din(micamente asignado. 8os tipos de estructura no
admiten la =erencia especi0icada por el usuario y =eredan impl5citamente del tipo object.
8as estructuras son particularmente Htiles para estructuras de datos pe?ueUas ?ue tienen sem(nticas de valor.
8os nHmeros comple$os, los puntos de un sistema de coordenadas o los pares de valores clave de un diccionario
son buenos e$emplos de estructuras. El uso de estructuras en lugar de clases para estructuras de datos pe?ueUas
puede suponer una di0erencia sustancial en el nHmero de asignaciones de memoria ?ue reali1a una aplicaci-n.
'or e$emplo, el programa siguiente crea e iniciali1a una matri1 de 1"" puntos. Con *oint implementada como
una clase, se iniciali1an 1"1 ob$etos separados, uno para la matri1 y uno para cada uno de los 1"" elementos.
class *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
class 1est
{
static void Main() {
*oint45 &oints + ne, *oint42335;
-or (int i + 3; i D 233; i<<) &oints4i5 + ne, *oint(i i);
!
!
7na alternativa es convertir *oint en una estructura.
struct *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
&=ora, s-lo se crea una instancia de un ob$eto, el de la matri1, y las instancias de *oint se almacenan en l5nea
en la matri1.
8os constructores de estructuras se invocan con el operador ne,, pero esto no implica ?ue se est) asignando la
memoria. En lugar de asignar din(micamente un ob$eto y devolver una re0erencia al mismo, un constructor de
estructuras simplemente devuelve el propio valor de la estructura Onormalmente en una ubicaci-n temporal en la
pilaR y a continuaci-n se copia este valor como sea necesario.
2$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En el caso de las clases, es posible ?ue dos variables =agan re0erencia al mismo ob$eto y, por tanto, ?ue las
operaciones en una variable a0ecten al ob$eto al ?ue =ace re0erencia la otra variable. En el caso de las
estructuras, cada variable tiene su propia copia de los datos, de manera ?ue no es posible ?ue las operaciones de
una a0ecten a la otra. 'or e$emplo, el resultado generado por el 0ragmento de c-digo siguiente depende de si
*oint es una clase o una estructura.
*oint a + ne, *oint(23 23);
*oint b + a;
a.# + 83;
Console.WriteLine(b.#);
.i *oint es una clase, el resultado es 83 por?ue a y b =acen re0erencia al mismo ob$eto. .i *oint es una
estructura, el resultado es 23 por?ue la asignaci-n de a a b crea una copia del valor y esta copia no resulta
a0ectada por la subsiguiente asignaci-n a a.#.
El e$emplo anterior resalta dos de las limitaciones de estructuras. En primer lugar, copiar una estructura
completa normalmente es menos e0ica1 ?ue copiar una re0erencia a un ob$eto, por lo ?ue la asignaci-n y el modo
de pasar par(metros de valor puede ser m(s costoso con estructuras ?ue con tipos de re0erencia. En segundo
lugar, salvo en el caso de los par(metros re- y out, no es posible crear re0erencias a estructuras, lo ?ue descarta
su uso en varias situaciones.
1.- &atrices
7na atri- es una estructura de datos ?ue contiene una serie de variables a las ?ue se obtiene acceso a trav)s de
5ndices calculados. 8as variables contenidas en una matri1, tambi)n conocidas como eleentos de la matri1, son
todas del mismo tipo, denominado tipo de eleento de la atri-.
8os tipos de matri1 son tipos de re0erencia, por lo ?ue la declaraci-n de una variable matricial solamente reserva
espacio para una instancia de matri1. 8as instancias de matri1 reales se crean din(micamente en tiempo de
e$ecuci-n utili1ando el operador ne,. 8a operaci-n ne, especi0ica la longit!d de la nueva instancia de matri1,
?ue se establece para el per5odo de duraci-n de la instancia. 8os 5ndices de los elementos de una matri1 pueden
ir desde 3 a Lengt" = 2. El operador ne, iniciali1a autom(ticamente los elementos de una matri1 con su valor
predeterminado ?ue, por e$emplo, es cero para todos los tipos num)ricos y null para todos los tipos de
re0erencia.
El e$emplo siguiente crea una matri1 de elementos int, iniciali1a la matri1 e imprime su contenido.
using System;
class 1est
{
static void Main() {
int45 a + ne, int4235;
-or (int i + 3; i D a.Lengt"; i<<) {
a4i5 + i > i;
!
-or (int i + 3; i D a.Lengt"; i<<) {
Console.WriteLine("a4{3!5 + {2!" i a4i5);
!
!
!
Este e$emplo crea y 0unciona en una atri- !nidiensional. C# tambi)n admite las atrices
!ltidiensionales. El nHmero de dimensiones de un tipo de matri1, tambi)n conocido como el rango del tipo
de matri1, es uno m(s el nHmero de comas escrito entre los corc=etes del tipo de matri1. El e$emplo siguiente
asigna una matri1 unidimensional, una bidimensional y una tridimensional.
int45 a2 + ne, int4235;
int45 a8 + ne, int423 K5;
int45 a9 + ne, int423 K 85;
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2"
Especificacin del lenguaje C#
8a matri1 a2 contiene 1" elementos, la matri1 a8 contiene " O1" X R elementos y la matri1 a9 contiene 1""
O1" X X 2R elementos.
8os elementos de una matri1 pueden ser de cual?uier tipo, incluido un tipo de matri1. 7na matri1 con elementos
de tipo de matri1 a veces se denomina atri- escalonada por?ue las longitudes de las matrices de elementos no
tienen ?ue ser siempre las mismas. El e$emplo siguiente asigna una matri1 de matrices de intG
int4545 a + ne, int49545;
a435 + ne, int4235;
a425 + ne, int4K5;
a485 + ne, int4835;
8a primera l5nea crea una matri1 con tres elementos, cada uno de tipo int45 y cada uno con un valor inicial
null. & continuaci-n, las l5neas subsiguientes iniciali1an los tres elementos con re0erencias a instancias de
matri1 individuales de longitudes diversas.
El operador ne, permite especi0icar los valores iniciales de los elementos de matri1 utili1ando un iniciali-ador
de atrices, ?ue es una lista de expresiones escrita entre los delimitadores { y !. El e$emplo siguiente asigna e
iniciali1a un int45 con tres elementos.
int45 a + ne, int45 {2 8 9!;
/bserve ?ue la longitud de la matri1 se in0iere del nHmero de expresiones existentes entre { y !. 8a variable
local y las declaraciones de campo se pueden acortar m(s, de tal modo ?ue no es necesario volver a especi0icar
el tipo de matri1.
int45 a + {2 8 9!;
8os dos e$emplos anteriores son e?uivalentes a lo siguienteG
int45 t + ne, int495;
t435 + 2;
t425 + 8;
t485 + 9;
int45 a + t;
1.. Interfaces
7na interfa- de0ine un contrato ?ue puede ser implementado por clases y estructuras. 7na inter0a1 puede
contener m)todos, propiedades, eventos e indi1adores. 7na inter0a1 no proporciona implementaciones de los
miembros ?ue de0ine, simplemente especi0ica los miembros ?ue deben proporcionar las clases o estructuras ?ue
implementan la inter0a1.
8as inter0aces pueden utili1ar una herencia 7ltiple. En el e$emplo siguiente, la inter0a1 $Combo:o# =ereda de
$1e#t:o# y de $List:o#.
inter-ace $Control
{
void *aint();
!
inter-ace $1e#t:o#/ $Control
{
void Set1e#t(string te#t);
!
inter-ace $List:o#/ $Control
{
void Set$tems(string45 items);
!
inter-ace $Combo:o#/ $1e#t:o# $List:o# {!
3' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8as clases y las estructuras pueden implementar varias inter0aces. En el e$emplo siguiente, la clase )dit:o#
implementa $Control e $6ata:ound.
inter-ace $6ata:ound
{
void :ind(:inder b);
!
&ublic class )dit:o#/ $Control $6ata:ound
{
&ublic void *aint() {...!
&ublic void :ind(:inder b) {...!
!
Cuando una clase o estructura implementa una inter0a1 determinada, las instancias de dic=a clase o estructura se
pueden convertir impl5citamente en dic=o tipo de inter0a1. 'or e$emploG
)dit:o# edit:o# + ne, )dit:o#();
$Control control + edit:o#;
$6ata:ound data:ound + edit:o#;
En los casos en los ?ue no se sabe est(ticamente ?ue una inter0a1 pueda implementar una inter0a1 determinada,
se pueden utili1ar conversiones de tipo din(micas. 'or e$emplo, las instrucciones siguientes utili1an
conversiones de tipo din(micas para obtener implementaciones de inter0aces $Control e $6ata:ound de un
ob$eto. 2ado ?ue el tipo real del ob$eto es )dit:o#, las conversiones se reali1aron con )xito.
object obj + ne, )dit:o#();
$Control control + ($Control)obj;
$6ata:ound data:ound + ($6ata:ound)obj;
En la clase )dit:o# anterior, el m)todo *aint de la inter0a1 $Control y el m)todo :ind de la inter0a1
$6ata:ound se implementan utili1ando miembros &ublic. C# tambi)n admite ipleentaciones e.plcitas
de ie/ro de la interfa- y, al utili1arlas la clase o la estructura, se puede evitar ?ue los miembros sean
&ublic. 7na implementaci-n expl5cita de miembro de inter0a1 se escribe utili1ando el nombre completo de
miembro de inter0a1. 'or e$emplo, la clase )dit:o# podr5a implementar los m)todos $Control.*aint e
$6ata:ound.:ind utili1ando implementaciones expl5citas de miembro de inter0a1 del siguiente modo.
&ublic class )dit:o#/ $Control $6ata:ound
{
void $Control.*aint() {...!
void $6ata:ound.:ind(:inder b) {...!
!
.-lo se puede tener acceso a los miembros de inter0a1 expl5citos mediante el tipo de inter0a1. 'or e$emplo, la
implementaci-n de $Control.*aint proporcionada por la clase )dit:o# anterior s-lo se puede invocar
convirtiendo primero la re0erencia )dit:o# en el tipo de inter0a1 $Control.
)dit:o# edit:o# + ne, )dit:o#();
edit:o#.*aint(); .. )rror no suc" met"od
$Control control + edit:o#;
control.*aint(); .. %(
1.10 Enumeraciones
7n tipo en! Oenumeraci-nR es un tipo de valor distinto con un con$unto de constantes con nombre. El e$emplo
siguiente declara y utili1a un tipo enum denominado Color con tres valores constantesG Oed, Sreen y :lue.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 31
Especificacin del lenguaje C#
using System;
enum Color
{
Oed
Sreen
:lue
!
class 1est
{
static void *rintColor(Color color) {
s,itc" (color) {
case Color.Oed/
Console.WriteLine("Oed");
brea(;
case Color.Sreen/
Console.WriteLine("Sreen");
brea(;
case Color.:lue/
Console.WriteLine(":lue");
brea(;
de-ault/
Console.WriteLine(";n(no,n color");
brea(;
!
!
static void Main() {
Color c + Color.Oed;
*rintColor(c);
*rintColor(Color.:lue);
!
!
Cada tipo enum tiene un tipo integral correspondiente denominado tipo s!/yacente del tipo enum. 7n tipo enum
?ue no declara expl5citamente un tipo subyacente tiene int como tipo subyacente. El 0ormato de
almacenamiento y el intervalo de posibles valores de un tipo enum vienen determinados por su tipo subyacente.
El con$unto de valores ?ue puede tomar un tipo enum no est( limitado por sus miembros de enumeraci-n. En
concreto, cual?uier valor del tipo subyacente de una enumeraci-n puede convertirse en el tipo enum, y es un
valor aceptado y distintivo de dic=o tipo enum.
El e$emplo siguiente declara un tipo enum denominado 'lignment con un tipo subyacente de sbyte.
enum 'lignment/ sbyte
{
Le-t + =2
Center + 3
Oig"t + 2
!
Como se muestra en el e$emplo anterior, una declaraci-n de miembro de enumeraci-n puede incluir una
expresi-n constante ?ue especi0ica el valor del miembro. El valor constante de cada miembro de enumeraci-n
debe estar comprendido en el intervalo del tipo subyacente de la enumeraci-n. Cuando una declaraci-n de
miembro de enumeraci-n no especi0ica expl5citamente un valor, se da al miembro el valor cero Osi es el primer
miembro del tipo enumR o el valor del miembro de la enumeraci-n precedente m(s uno.
8os valores de enumeraci-n se pueden convertir en valores de tipo integral y viceversa, utili1ando las
conversiones de tipo. 'or e$emploG
int i + (int)Color.:lue; .. int i + 8;
Color c + (Color)8; .. Color c + Color.:lue;
32 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
El valor predeterminado de cual?uier tipo de enumeraci-n es el valor cero de tipo integral convertido en el tipo
enum. En los casos en los ?ue las variables se iniciali1an autom(ticamente con un valor predeterminado, )ste es
el valor proporcionado para las variables de tipos enum. 'ara ?ue el valor predeterminado de un tipo enum est)
0(cilmente disponible, el literal " se convierte impl5citamente en cual?uier tipo enum. 2e este modo, se permite
lo siguiente.
Color c + 3;
1.11 /elegados
7n tipo delegado representa las re0erencias a los m)todos con una lista de par(metros determinada y un tipo de
valor devuelto. 8os delegados permiten tratar m)todos como entidades, ?ue se pueden asignar a las variables y
pasarse como par(metros. 8os delegados son similares al concepto de punteros a 0unci-n de otros lengua$es,
pero al contrario de los punteros a 0unci-n, los delegados est(n orientados a ob$etos y proporcionan seguridad
de tipos.
El e$emplo siguiente declara y utili1a un tipo delegado denominado Vunction.
using System;
delegate double Vunction(double #);
class Multi&lier
{
double -actor;
&ublic Multi&lier(double -actor) {
t"is.-actor + -actor;
!
&ublic double Multi&ly(double #) {
return # > -actor;
!
!
class 1est
{
static double SQuare(double #) {
return # > #;
!
static double45 '&&ly(double45 a Vunction -) {
double45 result + ne, double4a.Lengt"5;
-or (int i + 3; i D a.Lengt"; i<<) result4i5 + -(a4i5);
return result;
!
static void Main() {
double45 a + {3.3 3.K 2.3!;
double45 sQuares + '&&ly(a SQuare);
double45 sines + '&&ly(a Mat".Sin);
Multi&lier m + ne, Multi&lier(8.3);
double45 doubles + '&&ly(a m.Multi&ly);
!
!
7na instancia del tipo delegado Vunction puede =acer re0erencia a cual?uier m)todo ?ue tome un argumento
double y ?ue devuelva un valor double. El m)todo '&&ly aplica un tipo Vunction determinado a los
elementos de un tipo double45 y devuelve un tipo double45 con los resultados. En el m)todo Main, se utili1a
'&&ly para aplicar tres 0unciones di0erentes a un double45.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 33
Especificacin del lenguaje C#
7n delegado puede =acer re0erencia a un m)todo est(tico Ocomo SQuare o Mat".Sin en el e$emplo anteriorR o
a un m)todo de instancia Ocomo m.Multi&ly en el e$emplo anteriorR. 7n delegado ?ue =ace re0erencia a un
m)todo de instancia tambi)n =ace re0erencia a un ob$eto determinado y, cuando se invoca el m)todo de instancia
a trav)s del delegado, dic=o ob$eto pasa a ser t"is en la invocaci-n.
8os delegados tambi)n se pueden crear mediante 0unciones an-nimas, ?ue son Pm)todos insertadosQ creados
sobre la marc=a. 8as 0unciones an-nimas pueden ver las variables locales de los m)todos adyacentes. &s5, el
e$emplo anterior del multiplicador se puede escribir m(s 0(cilmente sin usar una clase Multi&lierG
double45 doubles + '&&ly(a (double #) +E # > 8.3);
7na propiedad interesante y Htil de un delegado es ?ue no conoce ni necesita conocer la clase del m)todo a la
?ue =ace re0erenciaV lo Hnico ?ue importa es ?ue el m)todo al ?ue se =ace re0erencia tenga los mismos
par(metros y el mismo tipo de valor devuelto ?ue el delegado.
1.12 'tributos
8os tipos, miembros y otras entidades de un programa de C# admiten modi0icadores ?ue controlan ciertos
aspectos de su comportamiento. 'or e$emplo, la accesibilidad de un m)todo se controla utili1ando los
modi0icadores &ublic, &rotected, internal y &rivate. C# generali1a esta 0unci-n de tal 0orma ?ue los
tipos de0inidos por el usuario de in0ormaci-n declarativa puedan agregarse a las entidades del programa y ser
recuperados en tiempo de e$ecuci-n. 8os programas especi0ican esta in0ormaci-n declarativa adicional
de0iniendo y utili1ando atri/!tos.
El e$emplo siguiente declara un atributo Hel&'ttribute ?ue se puede colocar en entidades de programa para
proporcionar v5nculos a la documentaci-n asociada.
using System;
&ublic class Hel&'ttribute/ 'ttribute
{
string url;
string to&ic;
&ublic Hel&'ttribute(string url) {
t"is.url + url;
!
&ublic string ;rl {
get { return url; !
!
&ublic string 1o&ic {
get { return to&ic; !
set { to&ic + value; !
!
!
Todas las clases de atributo derivan de la clase base System.'ttribute proporcionada por .4ET :rame9or6.
8os atributos se pueden aplicar indicando su nombre, $unto con los argumentos, entre corc=etes, $usto antes de la
declaraci-n asociada. .i el nombre de un atributo termina en 'ttribute, se puede omitir dic=a parte del
nombre si se =ace re0erencia al atributo. 'or e$emplo, el atributo Hel&'ttribute se puede utili1ar del
siguiente modo.
4Hel&(""tt&/..msdn.microso-t.com.....MyClass."tm")5
&ublic class Widget
{
4Hel&(""tt&/..msdn.microso-t.com.....MyClass."tm" 1o&ic + "6is&lay")5
&ublic void 6is&lay(string te#t) {!
!
3# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Este e$emplo asocia un Hel&'ttribute a la clase Widget y otro Hel&'ttribute al m)todo 6is&lay de la
clase. 8os constructores pHblicos de una clase de atributo controlan la in0ormaci-n ?ue debe proporcionarse al
asociar el atributo a una entidad de programa. 'uede proporcionarse in0ormaci-n adicional =aciendo re0erencia
a las propiedades pHblicas de lectura y escritura de la clase de atributo Ocomo la re0erencia previa a la propiedad
1o&icR.
El e$emplo siguiente muestra c-mo utili1ar la re0lexi-n para recuperar en tiempo de e$ecuci-n la in0ormaci-n de
atributos para una entidad determinada del programa.
using System;
using System.Oe-lection;
class 1est
{
static void S"o,Hel&(Member$n-o member) {
Hel&'ttribute a + 'ttribute.SetCustom'ttribute(member
ty&eo-(Hel&'ttribute)) as Hel&'ttribute;
i- (a ++ null) {
Console.WriteLine("No "el& -or {3!" member);
!
else {
Console.WriteLine("Hel& -or {3!/" member);
Console.WriteLine(" ;rl+{3! 1o&ic+{2!" a.;rl a.1o&ic);
!
!
static void Main() {
S"o,Hel&(ty&eo-(Widget));
S"o,Hel&(ty&eo-(Widget).SetMet"od("6is&lay"));
!
!
Cuando se solicita un atributo determinado a trav)s de la re0lexi-n, se invoca al constructor para la clase de
atributo con la in0ormaci-n proporcionada en el c-digo 0uente del programa y se devuelve la instancia de
atributo resultante. .i la in0ormaci-n adicional se proporciona a trav)s de propiedades, dic=as propiedades se
establecen en los valores dados antes de ?ue se devuelva la instancia de atributo.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 3!
Especificacin del lenguaje C#
2. Estructura l*"ica
2.1 (rogramas
7n prograa de C# consta de uno o varios archivos de c,digo f!ente, 0ormalmente conocidos como !nidades
de copilaci,n O[+.1R. 7n arc=ivo de c-digo 0uente es una secuencia ordenada de caracteres 7nicode. 8os
arc=ivos de c-digo 0uente normalmente tienen una correspondencia de uno a uno con los arc=ivos de un sistema
de arc=ivos, pero esta correspondencia no es necesaria. 'ara maximi1ar la portabilidad, se recomienda utili1ar la
codi0icaci-n 7T:B8 para los arc=ivos de un sistema de arc=ivos.
En t)rminos conceptuales, un programa se compila en tres 0asesG
1. Trans0ormaci-n, ?ue convierte un arc=ivo, a partir de un repertorio de caracteres y un es?uema de
codi0icaci-n concretos, en una secuencia de caracteres 7nicode.
2. &n(lisis l)xico, ?ue convierte una secuencia de caracteres de entrada 7nicode en una secuencia de s5mbolos
Oto6enR.
3. &n(lisis sint(ctico, ?ue convierte la secuencia de to6ens en c-digo e$ecutable.
2.2 0ram)ticas
Esta especi0icaci-n presenta la sintaxis del lengua$e de programaci-n C# mediante el uso de dos gram(ticas. 8a
gra5tica l6.ica O[2.2.2R de0ine c-mo se combinan los caracteres 7nicode para 0ormar terminadores de l5nea,
espacios en blanco, comentarios, s5mbolos Oto6ensR y directivas de preprocesamiento. 8a gra5tica sint5ctica
O[2.2.3R de0ine c-mo se combinan los to6ens resultantes de la gram(tica l)xica para 0ormar programas de C#.
2.2.1 1otacin gramatical
8as gram(ticas l)xica y sint(ctica se presentan mediante prod!cciones graaticales. Cada producci-n
gramatical de0ine un s5mbolo no terminal y las posibles expansiones de dic=o s5mbolo en secuencias de
s5mbolos no terminales o terminales. En las producciones gramaticales, los s5mbolos no ter%inales se muestran
en cursiva, y los s5mbolos terminal se muestran en una 0uente de anc=o 0i$o.
8a primera l5nea de una producci-n gramatical es el nombre del s5mbolo no terminal ?ue se de0ine, seguido de
un car(cter de dos puntos. Cada l5nea con sangr5a sucesiva contiene una expansi-n posible del s5mbolo no
terminal dado como una secuencia de s5mbolos no terminales o terminales. 'or e$emplo, la producci-nG
while-state%ent1
,"ile ( -oolean-e2pression ) e%-edded-state%ent
de0ine una instrucci-n 9=ile Owhile-state%entR 0ormada por el s5mbolo Oto6enR ,"ile, seguida del s5mbolo P(Q,
de una expresi-n booleana O-oolean-e2pressionR, del s5mbolo P)Q y de una instrucci-n incrustada Oe%-edded-
state%entR.
Cuando =ay m(s de una expansi-n posible de un s5mbolo no terminal, las alternativas se muestran en l5neas
individuales. 'or e$emplo, la producci-nG
state%ent-list1
state%ent
state%ent-list state%ent
36 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
de0ine una lista de instrucciones Ostate%ent-listR ?ue consta de una instrucci-n Ostate%entR o de una lista de
instrucciones Ostate%ent-listR seguida de una instrucci-n Ostate%entR. Es decir, la de0inici-n es recursiva y
especi0ica ?ue una lista de instrucciones consta de una o varias instrucciones.
.e utili1a un su0i$o en sub5ndice P
opt
Q para indicar un s5mbolo opcional. 8a producci-nG
-loc31
{ state%ent-list
opt
!
es una 0orma abreviada deG
-loc31
{ !
{ state%ent-list !
y de0ine un blo?ue O-loc3R compuesto por una lista de instrucciones Ostate%ent-listR opcional entre los to6ens
P{Q y P!Q.
8as alternativas normalmente se enumeran en l5neas distintas, aun?ue en los casos en los ?ue =ay varias
alternativas, el texto Puna de las siguientesQ puede preceder a una lista de expansiones proporcionadas en la
misma l5nea. Esto es sencillamente una 0orma abreviada de mostrar todas las alternativas en l5neas distintas. 'or
e$emplo, la producci-nG
real-t#pe-sffi21 no de
V - 6 d M m
es una 0orma abreviada deG
real-t#pe-sffi21
V
-
6
d
M
m
2.2.2 0ram)tica l*"ica
8a gram(tica l)xica de C# se presenta en [2.3, [2.4 y [2.. 8os s5mbolos terminales de la gram(tica l)xica son
los caracteres del $uego de caracteres 7nicode, y la gram(tica l)xica especi0ica c-mo se combinan los caracteres
para 0ormar to6ens O[2.4R, espacios en blanco O[2.3.3R, comentarios O[2.3.2R y directivas de preprocesamiento
O[2.R.
Todos los arc=ivos de c-digo 0uente de un programa de C# deben a$ustarse a la producci-n entrada OinptR de la
gram(tica l)xica O[2.3R.
2.2.3 0ram)tica sint)ctica
8a gram(tica sint(ctica de C# se presenta en los cap5tulos y ap)ndices ?ue siguen a este cap5tulo. 8os s5mbolos
terminales de la gram(tica sint(ctica son los to6ens de0inidos por la gram(tica l)xica, mientras la gram(tica
sint(ctica es la ?ue especi0ica c-mo se combinan los s5mbolos para 0ormar programas de C#.
Todos los arc=ivos de c-digo 0uente de un programa de C# deben cumplir con la producci-n de unidades de
compilaci-n Oco%pilation-nitR de la gram(tica sint(ctica O[+.1R.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 3(
Especificacin del lenguaje C#
2.3 'n)lisis l*"ico
8a producci-n entrada OinptR de0ine la estructura l)xica de un arc=ivo de c-digo 0uente de C#. 7n arc=ivo de
c-digo 0uente de un programa de C# debe a$ustarse a esta producci-n de la gram(tica l)xica.
inpt1
inpt-section
opt
inpt-section1
inpt-section-part
inpt-section inpt-section-part
inpt-section-part1
inpt-ele%ents
opt
new-line
pp-directive
inpt-ele%ents1
inpt-ele%ent
inpt-ele%ents inpt-ele%ent
inpt-ele%ent1
whitespace
co%%ent
to3en
Cinco elementos b(sicos constituyen la estructura l)xica de un arc=ivo de c-digo 0uente de C#G los terminadores
de l5nea O[2.3.1R, el espacio en blanco O[2.3.3R, los comentarios O[2.3.2R, los s5mbolos Oto6enR O[2.4R y las
directivas de preprocesamiento O[2.R. 2e estos elementos b(sicos, solamente los to6ens son signi0icativos en la
gram(tica sint(ctica de un programa de C# O[2.2.3R.
El procesamiento l)xico de un arc=ivo de c-digo 0uente de C# consiste en reducir el arc=ivo a una secuencia
de to6ens para 0ormar la entrada del an(lisis sint(ctico. 8os terminadores de l5nea, el espacio en blanco y los
comentarios pueden corresponder a to6ens di0erentes, y las directivas de preprocesamiento pueden =acer ?ue
se omitan secciones del arc=ivo de c-digo 0uente, pero por lo dem(s estos elementos l)xicos no tienen
repercusiones en la estructura sint(ctica de un programa de C#.
Cuando varias producciones de la gram(tica l)xica coinciden con una secuencia de caracteres de un arc=ivo
de c-digo 0uente, el procesamiento l)xico siempre 0orma el elemento l)xico m(s largo posible. 'or e$emplo,
la secuencia de caracteres .. se procesa como el principio de un comentario en una sola l5nea, por?ue este
elemento l)xico es m(s largo ?ue un to6en de una sola ..
2.3.1 Terminadores de l2nea
8os terminadores de l5nea dividen los caracteres de un arc=ivo de c-digo 0uente de C# en l5neas.
new-line1
Car,cter de retorno de carro 4;<33365
Car,cter de salto de l*nea 4;<333'5
Car,cter de retorno de carro 4;<33365 se&ido de n car,cter de salto de l*nea 4;<333'5
Car,cter de l*nea si&iente 4;<33YK5
Car,cter separador de l*nea 4;<838Y5
Car,cter separador de p,rrafo 4;<838L5
'or compatibilidad con las =erramientas de edici-n de c-digo 0uente ?ue agregan marcadores de 0in de arc=ivo,
y para permitir ?ue un arc=ivo de c-digo 0uente pueda verse como una secuencia de l5neas terminadas
correctamente, se aplican las siguientes trans0ormaciones, por orden, a todos los arc=ivos de c-digo 0uente de un
programa de C#G
3$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
.i el Hltimo car(cter del arc=ivo de c-digo 0uente es un car(cter ControlB\ O;<332'R, el car(cter se elimina.
&l 0inal del arc=ivo de c-digo de 0uente se agrega un car(cter de retorno de carro O;<3336R si este arc=ivo
no est( vac5o y si su Hltimo car(cter no es un retorno de carro O;<3336R, un salto de l5nea O;<333'R, un
separador de l5nea O;<838YR o un separador de p(rra0o O;<838L6R.
2.3.2 %omentarios
.e aceptan dos 0ormas de comentariosG comentarios en una l5nea y comentarios delimitados. 8os coentarios
de !na sola lnea empie1an con los caracteres .. y se extienden =asta el 0inal de la l5nea de c-digo 0uente. 8os
coentarios deliitados empie1an con los caracteres .> y terminan con los caracteres >.. Estos comentarios
pueden estar en varias l5neas.
co%%ent1
sin&le-line-co%%ent
deli%ited-co%%ent
sin&le-line-co%%ent1
.. inpt-characters
opt
inpt-characters1
inpt-character
inpt-characters inpt-character
inpt-character1
Cal6ier car,cter (nicode e2cepto n new-line-character 4car,cter de neva l*neaR
new-line-character1
Car,cter de retorno de carro 4;<33365
Car,cter de salto de l*nea 4;<333'5
Car,cter de l*nea si&iente 4;<33YK5
Car,cter separador de l*nea 4;<838Y5
Car,cter separador de p,rrafo 4;<838L5
deli%ited-co%%ent1
.> deli%ited-co%%ent-te2t
opt
asteris3s .
deli%ited-co%%ent-te2t1
deli%ited-co%%ent-section
deli%ited-co%%ent-te2t deli%ited-co%%ent-section
deli%ited-co%%ent-section1
.
asteris3s
opt
not-slash-or-asteris3
asteris3s1
>
asteris3s >
not-slash-or-asteris31
Cal6ier car,cter (nicode e2cepto . o >
8os comentarios no pueden anidarse. 8as secuencias de caracteres .> y >. no tienen ningHn signi0icado especial
dentro de un comentario .., y las secuencias de caracteres.. y .> no tienen ningHn signi0icado especial dentro
de un comentario delimitado.
8os comentarios no se procesan dentro de literales de car(cter y de cadena.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 3"
Especificacin del lenguaje C#
El e$emplo
.> Hello ,orld &rogram
1"is &rogram ,rites R"ello ,orldT to t"e console
>.
class Hello
{
static void Main() {
System.Console.WriteLine(""ello ,orld");
!
!
incluye un comentario delimitado.
El e$emplo
.. Hello ,orld &rogram
.. 1"is &rogram ,rites R"ello ,orldT to t"e console
..
class Hello .. any name ,ill do -or t"is class
{
static void Main() { .. t"is met"od must be named "Main"
System.Console.WriteLine(""ello ,orld");
!
!
muestra varios comentarios en una l5nea.
2.3.3 Espacio en blanco
Espacio en blanco se de0ine como cual?uier car(cter con la clase 7nicode \s O?ue incluye el car(cter de espacioR
as5 como el car(cter de tabulaci-n =ori1ontal, el car(cter de tabulaci-n vertical y el car(cter de avance de p(gina.
whitespace1
Cal6ier car,cter con clase (nicode 7s
Car,cter de ta-laci/n hori0ontal 4;<333L5
Car,cter de ta-laci/n vertical 4;<333:5
Car,cter de avance de p,&ina 4;<333C5
2.! To3ens
Existen varias clases de s5mbolos Oto6enRG identi0icadores, palabras clave, literales, operadores y signos de
puntuaci-n. 8os espacios en blanco y los comentarios no son s5mbolos Oto6enR, si bien actHan como separadores
entre ellos.
to3en1
identificador
3e#word
inte&er-literal
real-literal
character-literal
strin&-literal
operator-or-pnctator
2.!.1 4ecuencias de escape de caracteres 5nicode
7na secuencia de escape de caracteres 7nicode representa un car(cter 7nicode. 8as secuencias de escape de
car(cter 7nicode se procesan en identi0icadores O[2.4.2R, literales de car(cter O[2.4.4.4R y literales de cadena
normales O[2.4.4.R. 7n car(cter de escape 7nicode no se procesa en ninguna otra ubicaci-n Opor e$emplo, para
0ormar un operador, un signo de puntuaci-n o una palabra claveR.
#' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
nicode-escape-se6ence1
Zu he2-di&it he2-di&it he2-di&it he2-di&it
Z; he2-di&it he2-di&it he2-di&it he2-di&it he2-di&it he2-di&it he2-di&it he2-di&it
7na secuencia de escape 7nicode representa el Hnico car(cter 7nicode 0ormado por el nHmero =exadecimal ?ue
sigue a los caracteres PZuQ o PZ;Q. 2ado ?ue C# usa una codi0icaci-n de 1# bits de los puntos de c-digo
7nicode en caracteres y valores de cadena, un car(cter 7nicode en el intervalo de 7S1"""" a 7S1":::: no
est( permitido en un literal de caracteres y se representa mediante un par 7nicode suplente en un literal de
cadena. 8os caracteres 7nicode con puntos de c-digo por encima de "x1":::: no se aceptan.
4o se llevan a cabo conversiones mHltiples. 'or e$emplo, el literal de cadena PZu33KCu33KCQ es e?uivalente a
PZu33KCQ en lugar ?ue a PZQ. El valor 7nicode Zu33KC es el car(cter PZQ.
En el e$emplo
class Class2
{
static void 1est(bool Zu33XX) {
c"ar c + WZu33XXW;
i- (Zu33XX)
System.Console.WriteLine(c.1oString());
!
!
se muestran varios usos de Zu33XX, ?ue es la secuencia de escape de la letra P-Q. El programa e?uivale a
class Class2
{
static void 1est(bool -) {
c"ar c + W-W;
i- (-)
System.Console.WriteLine(c.1oString());
!
!
2.!.2 Identificadores
8as reglas de los identi0icadores explicadas en esta secci-n se corresponden exactamente con las recomendadas
por la norma 7nicode &nexo 1, a excepci-n del car(cter de subrayado, ?ue est( permitido como car(cter inicial
Ocomo era tradicional en el lengua$e de programaci-n CR. 8as secuencias de escape 7nicode est(n permitidas en
los identi0icadores y el car(cter P]Q est( permitido como pre0i$o para =abilitar el uso de palabras clave como
identi0icadores.
identifier1
availa-le-identifier
[ identifier-or-3e#word
availa-le-identifier1
(n identifier-or-3e#word 4identificador o pala-ra clave5 6e no es na 3e#word Opalabra claveR
identifier-or-3e#word1
identifier-start-character identifier-part-characters
opt
identifier-start-character1
letter-character
\ 4el car,cter de s-ra#ado ;<33KV5
identifier-part-characters1
identifier-part-character
identifier-part-characters identifier-part-character
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. #1
Especificacin del lenguaje C#
identifier-part-character1
letter-character
deci%al-di&it-character
connectin&-character
co%-inin&-character
for%attin&-character
letter-character1
(n car,cter (nicode de las clases +, +l, +t, +%, +o o 8l
(na secencia de escape (nicode 4nicode-escape-se6ence) 6e representa a n car,cter de
clases +, +l, +t, +%, +o o 8l
co%-inin&-character1
(n car,cter (nicode de las clases Mn o Mc
(na secencia de escape (nicode 4nicode-escape-se6ence5 6e representa n car,cter de clases
Mn o Mc
deci%al-di&it-character1
(n car,cter (nicode de la clase 8d.
(na nicode-escape-se6ence 4secencia de escape (nicode5 6e representa n car,cter de la
clase 8d
connectin&-character1
(n car,cter (nicode de la clase 9c
(na secencia de escape (nicode 4nicode-escape-se6ence5 6e representa n car,cter de la
clase 9c
for%attin&-character1
(n car,cter (nicode de la clase Cf
(na secencia de escape (nicode 4nicode-escape-se6ence5 6e representa n car,cter de la
clase Cf
'ara obtener m(s in0ormaci-n sobre las anteriores clases de caracteres, consulte la secci-n 4. de la versi-n 3."
de la norma 7nicode O(nicode :tandard, Version ;.0R.
Entre los e$emplos de identi0icadores v(lidos se incluyen Pidenti-ier2Q, P\identi-ier8Q y P[i-Q.
8os identi0icadores incluidos en programas segHn la norma deber(n seguir el 0ormato can-nico de0inido en el
documento (nicode 8or%ali0ation <or% C Oanexo 1 de la norma 7nicodeR. El comportamiento ante
identi0icadores ?ue no se a$usten a dic=o 0ormato depender( de la implementaci-nV no obstante, no ser(n
necesarios diagn-sticos.
El pre0i$o P[Q =abilita el uso de palabras clave como identi0icadores, lo cual resulta Htil cuando se interactHa con
otros lengua$es de programaci-n. El car(cter [ en realidad no 0orma parte del identi0icador, por lo ?ue el
identi0icador podr5a considerarse en otros lengua$es como un identi0icador normal, sin el pre0i$o. 8os
identi0icadores con pre0i$o [ se conocen como identificadores te.t!ales. El uso del pre0i$o [ para los
identi0icadores ?ue no son palabras clave est( permitido, pero no se recomienda por cuesti-n de estilo.
En el e$emploG
class [class
{
&ublic static void [static(bool [bool) {
i- ([bool)
System.Console.WriteLine("true");
else
System.Console.WriteLine("-alse");
!
!
#2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class Class2
{
static void M() {
clZu33X2ss.stZu33X2tic(true);
!
!
se de0ine una clase denominada PclassQ con un m)todo est(tico llamado PstaticQ ?ue toma un par(metro
denominado PboolQ. Tenga en cuenta ?ue, dado ?ue los escapes de 7nicode no est(n permitidos en las palabras
clave, el to6en PclZu33X2ssQ es un identi0icador id)ntico a P[classQ.
2os identi0icadores se consideran el mismo si son id)nticos despu)s de aplicarse las siguientes
trans0ormaciones, por ordenG
El pre0i$o P[Q, si aparece, se ?uitar(.
Cada secuencia de escape 7nicode Onicode-escape-se6enceR se trans0ormar( en su car(cter 7nicode
correspondiente.
Todos los caracteres de 0ormato Ofor%attin&-charactersR ser(n ?uitados.
8os identi0icadores ?ue contienen dos caracteres de subrayado O;<33KVR consecutivos se reservan para uso de la
implementaci-n. 'or e$emplo, una implementaci-n podr5a proporcionar palabras clave extendidas ?ue empiecen
por dos caracteres de subrayado.
2.!.3 (alabras clae
7na pala/ra clave es una secuencia de caracteres similar a un identi0icador ?ue est( reservada y no puede
utili1arse como identi0icador excepto cuando tiene como pre0i$o el car(cter [.
palabra clave O3e#wordRG una de
abstract as base bool brea(
byte case catc" c"ar c"ec(ed
class const continue decimal de-ault
delegate do double else enum
event e#&licit e#tern -alse -inally
-i#ed -loat -or -oreac" goto
i- im&licit in int inter-ace
internal es loc( long names&ace
ne, null object o&erator out
override &arams &rivate &rotected &ublic
readonly re- return sbyte sealed
s"ort si?eo- stac(alloc static string
struct s,itc" t"is t"ro, true
try ty&eo- uint ulong unc"ec(ed
unsa-e us"ort using virtual void
volatile ,"ile
En algunos lugares de la gram(tica, =ay identi0icadores espec50icos con signi0icados especiales, pero no son
palabras clave. 'or e$emplo, en una declaraci-n de propiedad, los identi0icadores PgetQ y PsetQ tienen un
signi0icado especial O[1".*.2R. En estas ubicaciones no se permite usar identi0icadores distintos de get o set,
por lo ?ue este uso no presenta con0lictos si se utili1an estas palabras como identi0icadores.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. #3
Especificacin del lenguaje C#
2.!.! 6iterales
7n literal es una representaci-n en c-digo 0uente de un valor.
literal1
-oolean-literal
inte&er-literal
real-literal
character-literal
strin&-literal
nll-literal
2.4.4.1 *iterales booleanos
Existen dos valores literales booleanosG true y -alse.
-oolean-literal1
true
-alse
El tipo de un literal booleano O-oolean-literalR es bool.
2.4.4.2 *iterales enteros
8os literales enteros permiten escribir valores de los tipos int, uint, long, y ulong. 8os literales enteros
tienen dos 0ormatos posiblesG decimal y =exadecimal.
inte&er-literal1
deci%al-inte&er-literal
he2adeci%al-inte&er-literal
deci%al-inte&er-literal1
deci%al-di&its inte&er-t#pe-sffi2
opt
deci%al-di&its1
deci%al-di&it
deci%al-di&its deci%al-di&it
deci%al-di&it1 no de
3 2 8 9 J K X M Y L
inte&er-t#pe-sffi21 no de
; u L l ;L ;l uL ul L; Lu l; lu
he2adeci%al-inte&er-literal1
3# he2-di&its inte&er-t#pe-sffi2
opt
3I he2-di&its inte&er-t#pe-sffi2
opt
he2-di&its1
he2-di&it
he2-di&its he2-di&it
he2-di&it1 no de
3 2 8 9 J K X M Y L ' : C 6 ) V a b c d e -
El tipo de un literal entero se determina como sigueG
.i el literal no tiene su0i$o, su tipo es el primero de los tipos en los cuales se puede representar su valorG int,
uint, long, ulong.
## Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
.i el literal tiene el su0i$o ; o u, su tipo es el primero de los tipos en los cuales se puede representar su valorG
uint, ulong.
.i el literal tiene el su0i$o L o l, su tipo es el primero de los tipos en los cuales se puede representar su valorG
long, ulong.
.i el literal tiene el su0i$o ;L, ;l, uL, ul, L;, Lu, l;, o lu, es de tipo ulong.
.i el valor representado por un literal entero est( 0uera del intervalo de valores del tipo ulong, se produce un
error en tiempo de compilaci-n.
'or cuestiones de estilo, a la =ora de escribir literales de tipo long se recomienda el uso de PLQ en lugar de PlQ
para evitar la 0(cil con0usi-n de la letra PlQ con el d5gito P2Q.
'ara ?ue el nHmero de valores int y long escritos como literales enteros decimales sea el m5nimo posible,
existen las dos reglas siguientesG
Cuando aparece un literal entero decimal Odeci%al-inte&er-literalR con el valor 214*483#48 O2
31
R y sin su0i$o
de tipo entero Ointe&er-t#pe-sffi2R como el s5mbolo Oto6enR inmediatamente posterior a un s5mbolo de
operador unario menos O[*.#.2R, el resultado es una constante de tipo int con el valor Y214*483#48 OY2
31
R.
En todas las dem(s situaciones, un literal entero decimal Odeci%al-inte&er-literalR de estas caracter5sticas es
de tipo uint.
Cuando aparece un literal entero decimal Odeci%al-inte&er-literalR con el valor +2233*2"3#84**8"8 O2
#3
R
y sin su0i$o de tipo entero Ointe&er-t#pe-sffi2R o con el su0i$o de tipo entero L o l como to6en
inmediatamente posterior de un to6en de operador unario menos O[*.#.2R, el resultado es una constante de
tipo long con el valor Y+2233*2"3#84**8"8 OY2
#3
R. En todas las dem(s situaciones, un literal entero
decimal Odeci%al-inte&er-literalR de estas caracter5sticas es de tipo ulong.
2.4.4.3 *iterales reales
8os literales reales permiten escribir valores de los tipos -loat, double y decimal.
real-literal1
deci%al-di&its . deci%al-di&its e2ponent-part
opt
real-t#pe-sffi2
opt
. deci%al-di&its e2ponent-part
opt
real-t#pe-sffi2
opt
deci%al-di&its e2ponent-part real-t#pe-sffi2
opt
deci%al-di&its real-t#pe-sffi2
e2ponent-part1
e si&n
opt
deci%al-di&its
) si&n
opt
deci%al-di&its
si&n1 no de
< =
real-t#pe-sffi21 no de
V - 6 d M m
.i no se especi0ica el su0i$o de tipo real Oreal-t#pe-sffi2R, el tipo del literal real es double. 2e lo contrario, el
su0i$o de tipo real determina el tipo del literal real, como sigueG
7n literal real con el su0i$o V o - es de tipo -loat. 'or e$emplo, los literales 2-, 2.K-, 2e23- y 289.JKXV
son de tipo -loat.
7n literal real con el su0i$o 6 o d es de tipo double. 'or e$emplo, los literales 2d, 2.Kd, 2e23d y
289.JKX6 son de tipo double.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. #!
Especificacin del lenguaje C#
7n literal real con el su0i$o M o m es de tipo decimal. 'or e$emplo, los literales 2m, 2.Km, 2e23m y
289.JKXM son de tipo decimal. Este literal se convierte en un valor decimal tomando el valor exacto y,
si es necesario, redondeando al valor m(s cercano ?ue se pueda representar mediante el redondeo de banca
O[4.1.*R. .e conserva cual?uier escala ?ue se detecte en el literal, salvo ?ue el valor est) redondeado o sea
cero Oen este caso, el signo y la escala son "R. 'or lo tanto, el an(lisis del literal 8.L33m se interpreta para
0ormar un decimal con signo 3, coe0iciente 8L33 y escala 9.
.i el literal especi0icado no puede representarse en el tipo indicado, se produce un error en tiempo de
compilaci-n.
El valor de un literal real de tipo -loat o double se determina mediante el uso del modo Predondeo al m(s
cercanoQ de !EEE.
Tenga en cuenta ?ue, en un literal real, siempre son necesarios d5gitos decimales tras el punto decimal. 'or
e$emplo, 2.9V es un literal real pero 2.V no lo es.
2.4.4.4 *iterales de carcter
7n literal de car(cter representa un car(cter Hnico y normalmente est( compuesto por un car(cter entre comillas,
como por e$emplo WaW.
character-literal1
W character W
character1
sin&le-character
si%ple-escape-se6ence
he2adeci%al-escape-se6ence
nicode-escape-se6ence
sin&le-character1
Cal6ier car,cter e2ceptoW 4;<338M5, Z 4;<33KC5 # n new-line-character 4car,cter de neva
l*neaR
si%ple-escape-se6ence1 no de
ZW Z" ZZ Z3 Za Zb Z- Zn Zr Zt Zv
he2adeci%al-escape-se6ence1
Z# he2-di&it he2-di&it
opt
he2-di&it
opt
he2-di&it
opt
Todo car(cter ?ue siga a un car(cter de barra diagonal OZR en un car(cter OcharacterR debe ser uno de los
siguientes caracteresG W, ", Z, 3, a, b, -, n, r, t, u, ;, #, v. En caso contrario, se producir( un error en tiempo de
compilaci-n.
7na secuencia de escape =exadecimal representa un solo car(cter 7nicode cuyo valor est( 0ormado por el
nHmero =exadecimal ?ue siga a PZ#Q.
.i el valor representado por un literal de car(cter es mayor ?ue ;<VVVV, se produce un error en tiempo de
compilaci-n.
7na secuencia de escape de caracteres 7nicode O[2.4.1R en un literal de caracteres debe estar comprendido en el
intervalo de ;<3333 a ;<VVVV.
7na secuencia de escape sencilla representa una codi0icaci-n de caracteres 7nicode, como se describe en la
tabla in0erior.
#6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
3ecuencia de
escape
4o)bre del
carcter
Codificacin
5nicode
ZW
Comilla simple
3#338M
Z"
Comilla doble
3#3388
ZZ
Aarra invertida
3#33KC
Z3
4ulo
3#3333
Za
&lerta
3#333M
Zb
;etroceso
3#333Y
Z-
&vance de
p(gina
3#333C
Zn
4ueva l5nea
3#333'
Zr
;etorno de carro
3#3336
Zt
Tabulaci-n
=ori1ontal
3#333L
Zv
Tabulaci-n
vertical
3#333:
El tipo de un literal de caracteres Ocharacter-literalR es c"ar.
2.4.4. *iterales de cadena
C# admite dos 0ormatos de literales de cadena8 literales de cadena reg!lares y literales de cadena te.t!ales.
7n literal de cadena regular consta de cero o m(s caracteres entre comillas dobles Ocomo en ^"ello^R y puede
incluir secuencias de escape sencillas Ocomo Zt para el car(cter de tabulaci-nR y secuencias de escape
=exadecimales y 7nicode.
7n literal de cadena textual consta de un car(cter [ seguido de un car(cter de comillas dobles, cero o m(s
caracteres y un car(cter de comillas dobles de cierre. 7n e$emplo sencillo puede ser [""ello". En un literal de
cadena textual, los caracteres comprendidos entre los delimitadores se interpretan de manera literal, siendo la
Hnica excepci-n una secuencia de escape comillas O6ote-escape-se6enceR. En concreto, las secuencias de
escape sencillas, las secuencias de escape =exadecimales y 7nicode no se procesan en los literales de cadena
textuales. 7n literal de cadena textual puede estar en varias l5neas.
strin&-literal1
re&lar-strin&-literal
ver-ati%-strin&-literal
re&lar-strin&-literal1
" re&lar-strin&-literal-characters
opt
"
re&lar-strin&-literal-characters1
re&lar-strin&-literal-character
re&lar-strin&-literal-characters re&lar-strin&-literal-character
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. #(
Especificacin del lenguaje C#
re&lar-strin&-literal-character1
sin&le-re&lar-strin&-literal-character
si%ple-escape-se6ence
he2adeci%al-escape-se6ence
nicode-escape-se6ence
sin&le-re&lar-strin&-literal-character1
Cal6ier car,cter e2cepto" 4;<33885, Z 4;<33KC5 # n new-line-character 4car,cter de neva
l*neaR
ver-ati%-strin&-literal1
[" ver-ati% -strin&-literal-characters
opt
"
ver-ati%-strin&-literal-characters1
ver-ati%-strin&-literal-character
ver-ati%-strin&-literal-characters ver-ati%-strin&-literal-character
ver-ati%-strin&-literal-character1
sin&le-ver-ati%-strin&-literal-character
6ote-escape-se6ence
sin&le-ver-ati%-strin&-literal-character1
Cal6ier car,cter e2cepto "
6ote-escape-se6ence1
""
Todo car(cter ?ue siga a un car(cter de barra diagonal OZR en un car(cter literal de cadena regular Ore&lar-
strin&-literal-characterR debe ser uno de los siguientes caracteresG W, ", Z, 3, a, b, -, n, r, t, u, ;, #, v. En caso
contrario, se producir( un error en tiempo de compilaci-n.
El e$emplo
string a + ""ello ,orld"; .. "ello ,orld
string b + [""ello ,orld"; .. "ello ,orld
string c + ""ello Zt ,orld"; .. "ello ,orld
string d + [""ello Zt ,orld"; .. "ello Zt ,orld
string e + "]oe said Z"HelloZ" to me"; .. ]oe said "Hello" to me
string - + ["]oe said ""Hello"" to me"; .. ]oe said "Hello" to me
string g + "ZZZZserverZZs"areZZ-ile.t#t"; .. ZZserverZs"areZ-ile.t#t
string " + ["ZZserverZs"areZ-ile.t#t"; .. ZZserverZs"areZ-ile.t#t
string i + "oneZrZnt,oZrZnt"ree";
string j + ["one
t,o
t"ree";
muestra varios literales de cadena. El Hltimo literal de cadena, j, es un literal de cadena textual ?ue ocupa varias
l5neas. 8os caracteres encerrados entre comillas, incluidos los espacios en blanco Opor e$emplo, caracteres de
nueva l5neaR, se conservan literalmente.
'uesto ?ue una secuencia de escape =exadecimal puede tener un nHmero variable de d5gitos =exadecimales, el
literal de cadena "Z#289" contiene un solo car(cter con un valor =exadecimal de 123. 'ara crear una cadena
?ue contenga el car(cter con el valor =exadecimal 12 seguido del car(cter 3, se podr5a escribir "Z#33289" o "Z
#28" < "9" en su lugar.
El tipo de un literal de cadena Ostrin&-literalR es string.
#$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Cada literal de cadena no genera necesariamente una nueva instancia de cadena. Cuando aparecen dos o m(s
literales de cadena e?uivalentes segHn el operador de igualdad de cadenas O[*.+.*R en el mismo programa, estos
literales se re0ieren a la misma instancia de cadena. 'or e$emplo, el resultado del programa
class 1est
{
static void Main() {
object a + ""ello";
object b + ""ello";
System.Console.WriteLine(a ++ b);
!
!
es 1rue por?ue los dos literales =acen re0erencia a la misma instancia de cadena.
2.4.4.6 &l literal null
nll-literal1
null
nll-literal se puede convertir de manera impl5cita en un tipo de re0erencia o un tipo ?ue acepta valores 4788.
2.!.# ,peradores y signos de puntuacin
Existen varias clases de operadores y signos de puntuaci-n. 8os operadores se utili1an en las expresiones para
describir operaciones ?ue implican uno o m(s operandos. 'or e$emplo, la expresi-n a < b usa el operador <
para sumar los dos operandos, a y b. 8os signos de puntuaci-n permiten agrupar y separar.
operator-or-pnctator1 no de
{ ! 4 5 ( ) . / ;
< = > . B F H G @ A
+ D E 7 77 // << == FF HH
=E ++ @+ D+ E+ <+ =+ >+ .+ B+
F+ H+ G+ DD DD+ +E
ri&ht-shift1
E=E
ri&ht-shift-assi&n%ent1
E=E+
8a barra vertical en las producciones de despla1amiento a la derec=a Ori&ht-shiftR y de asignaci-n de
despla1amiento a la derec=a Ori&ht-shift-assi&n%entR, al contrario de lo ?ue ocurre con otras producciones en la
gram(tica sint(ctica, no se puede insertar ningHn tipo de caracteres Oni si?uiera espacios en blancoR entre
s5mbolos Oto6enR. Estas producciones se tratan de manera especial para permitir el correcto control de t#pe-
para%eter-lists O[1".1.3R.
2.# /irectias de preprocesamiento
8as directivas de preprocesamiento o0recen la capacidad de omitir condicionalmente secciones de los arc=ivos
de c-digo 0uente, con el 0in de noti0icar errores y advertencias, as5 como de delimitar regiones caracter5sticas del
c-digo 0uente. El t)rmino Pdirectivas de preprocesamientoQ se utili1a por motivos de co=erencia con los
lengua$es de programaci-n C y CSS. En C#, no existe un paso de preprocesamiento individualV las directivas de
preprocesamiento se procesan como parte de la 0ase de an(lisis l)xico.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. #"
Especificacin del lenguaje C#
pp-directive1
pp-declaration
pp-conditional
pp-line
pp-dia&nostic
pp-re&ion
pp-pra&%a
& continuaci-n se indican las directivas de preprocesamiento disponiblesG
0de-ine y 0unde-, ?ue permiten de0inir y anular, respectivamente, s5mbolos de compilaci-n condicional
O[2..3R.
0i-, 0eli-, 0else, y 0endi-, para omitir de 0orma condicional secciones de arc=ivos de c-digo 0uente
O[2..4R.
0line, ?ue permite controlar nHmeros de l5nea de errores y advertencias O[2..*R.
0error y 0,arning, ?ue permiten emitir errores y advertencias, respectivamente O[2..R.
0region y 0endregion, para marcar de 0orma expl5cita secciones del c-digo 0uente O[2..#R.
0&ragma, ?ue se utili1a para especi0icar in0ormaci-n contextual opcional en el compilador O[2..8R.
7na directiva de preprocesamiento siempre ocupa una l5nea independiente del c-digo 0uente y siempre empie1a
por un car(cter 0 y un nombre de directiva de preprocesamiento. 'uede =aber un espacio en blanco antes del
car(cter 0 y entre )ste y el nombre de la directiva.
7na l5nea del c-digo 0uente ?ue contiene una directiva 0de-ine, 0unde-, 0i-, 0eli-, 0else, 0endi- o
0line puede terminar con un comentario de una sola l5nea. 8os comentarios delimitados Oel estilo de
comentarios .> >.R no est(n permitidos en las l5neas de c-digo 0uente ?ue contienen directivas de
preprocesamiento.
8as directivas de preprocesamiento no son s5mbolos Oto6ensR y no 0orman parte de la gram(tica sint(ctica de C#.
4o obstante, las directivas de preprocesamiento pueden utili1arse para incluir o excluir secuencias de to6ens y,
de esta 0orma, pueden a0ectar al signi0icado de un programa de C#. 'or e$emplo, una ve1 compilado, el
programaG
0de-ine '
0unde- :
class C
{
0i- '
void V() {!
0else
void S() {!
0endi-
0i- :
void H() {!
0else
void $() {!
0endi-
!
produce como resultado exactamente la misma secuencia de to6ens ?ue el programaG
!' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class C
{
void V() {!
void $() {!
!
'or lo tanto, aun?ue los dos programas sean muy di0erentes l)xicamente, sint(cticamente son id)nticos.
2.#.1 42mbolos de compilacin condicional
8a compilaci-n condicional ?ue suministran 0uncionalmente las directivas 0i-, 0eli-, 0else, y 0endi- se
controla mediante expresiones de preprocesamiento O[2..2R y s5mbolos de compilaci-n condicional.
conditional-s#%-ol1
Cal6ier identificador o pala-ra clave 4identifier-or-3e#word5 e2cepto true o -alse
7n s5mbolo de compilaci-n condicional tiene dos estados posiblesG definido o no definido. &l principio del
procesamiento l)xico de un arc=ivo de c-digo 0uente, un s5mbolo de compilaci-n condicional tiene el estado no
de0inido, a menos ?ue =aya sido de0inido de 0orma expl5cita por un mecanismo externo Ocomo una opci-n del
compilador de la l5nea de comandosR. Cuando se procesa una directiva 0de-ine, el s5mbolo de compilaci-n
condicional nombrado en la directiva ?ueda de0inido en el arc=ivo de c-digo 0uente. El s5mbolo permanece
de0inido =asta ?ue se procesa una directiva 0unde- del mismo s5mbolo o =asta ?ue se llega al 0inal del arc=ivo
de c-digo 0uente. 7na de las implicaciones es ?ue las directivas 0de-ine y 0unde- de un arc=ivo de c-digo
0uente no surten e0ecto en otros arc=ivos de c-digo 0uente del mismo programa.
Cuando se =ace re0erencia a un s5mbolo de compilaci-n condicional de0inido en una expresi-n de
preprocesamiento, )ste ad?uiere el valor booleano true, y un s5mbolo de compilaci-n condicional no de0inido
tiene el valor booleano -alse. 4o es necesario ?ue los s5mbolos de compilaci-n condicional se declaren
expl5citamente antes de ?ue se =aga re0erencia a ellos en expresiones de preprocesamiento. En lugar de ello, los
s5mbolos no declarados simplemente no se de0inen y, por lo tanto, tienen el valor -alse.
El espacio de nombres de los s5mbolos de compilaci-n condicional es Hnico y exclusivo de todas las dem(s
entidades con nombre de un programa de C#. .-lo puede =acerse re0erencia a los s5mbolos de compilaci-n
condicional en directivas 0de-ine y 0unde- y en expresiones de preprocesamiento.
2.#.2 E"presiones de preprocesamiento
8as expresiones de preprocesamiento pueden encontrarse en las directivas 0i- y 0eli-. En las expresiones de
preprocesamiento se permiten los operadores @, ++, @+, FF y HH, adem(s de los par)ntesis, empleados para
agrupar.
pp-e2pression1
whitespace
opt
pp-or-e2pression whitespace
opt
pp-or-e2pression1
pp-and-e2pression
pp-or-e2pression whitespace
opt
HH whitespace
opt
pp-and-e2pression
pp-and-e2pression1
pp-e6alit#-e2pression
pp-and-e2pression whitespace
opt
FF whitespace
opt
pp-e6alit#-e2pression
pp-e6alit#-e2pression1
pp-nar#-e2pression
pp-e6alit#-e2pression whitespace
opt
++ whitespace
opt
pp-nar#-e2pression
pp-e6alit#-e2pression whitespace
opt
@+ whitespace
opt
pp-nar#-e2pression
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. !1
Especificacin del lenguaje C#
pp-nar#-e2pression1
pp-pri%ar#-e2pression
@ whitespace
opt
pp-nar#-e2pression
pp-pri%ar#-e2pression1
true
-alse
conditional-s#%-ol
( whitespace
opt
pp-e2pression whitespace
opt
)
Cuando se =ace re0erencia a un s5mbolo de compilaci-n condicional de0inido en una expresi-n de
preprocesamiento, )ste ad?uiere el valor booleano true, y un s5mbolo de compilaci-n condicional no de0inido
tiene el valor booleano -alse.
8a evaluaci-n de una expresi-n de preprocesamiento siempre produce un valor booleano. 8as reglas de
evaluaci-n de una expresi-n de preprocesamiento son las mismas ?ue las de una expresi-n constante O[*.18R,
excepto en ?ue las Hnicas entidades de0inidas por el usuario a las ?ue puede =acerse re0erencia son s5mbolos de
compilaci-n condicional.
2.#.3 /irectias de declaracin
8as directivas de declaraci-n permiten de0inir o anular la de0inici-n de s5mbolos de compilaci-n condicional.
pp-declaration1
whitespace
opt
0 whitespace
opt
de-ine whitespace conditional-s#%-ol pp-new-line
whitespace
opt
0 whitespace
opt
unde- whitespace conditional-s#%-ol pp-new-line
pp-new-line1
whitespace
opt
sin&le-line-co%%ent
opt
new-line
El procesamiento de una directiva 0de-ine causa la de0inici-n del s5mbolo de compilaci-n condicional dado,
empe1ando en la l5nea del c-digo 0uente ?ue sigue a la directiva. 2e igual manera, el procesamiento de una
directiva 0unde- causa la eliminaci-n de la de0inici-n del s5mbolo de compilaci-n condicional dado,
empe1ando en la l5nea del c-digo 0uente ?ue sigue a la directiva.
Todas las directivas 0de-ine y 0unde- de un arc=ivo de c-digo 0uente deben aparecer antes del primer
s5mbolo Oto3enR O[2.4R en el arc=ivo de c-digo 0uenteV de lo contrario, se producir( un error en tiempo de
compilaci-n. En t)rminos intuitivos, las directivas 0de-ine y 0unde- deben preceder a cual?uier Pc-digo realQ
en el arc=ivo de c-digo 0uente.
El e$emploG
0de-ine )nter&rise
0i- *ro-essional HH )nter&rise
0de-ine 'dvanced
0endi-
names&ace Megacor&.6ata
{
0i- 'dvanced
class *ivot1able {...!
0endi-
!
es v(lido por?ue las directivas 0de-ine preceden al primer s5mbolo Oto6enR Ola palabra clave names&aceR en el
arc=ivo de c-digo 0uente.
El siguiente e$emplo dar5a como resultado un error en tiempo de compilaci-n por?ue en )l =ay una directiva
0de-ine despu)s del c-digo realG
!2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
0de-ine '
names&ace N
{
0de-ine :
0i- :
class Class2 {!
0endi-
!
'uede utili1arse 0de-ine para de0inir un s5mbolo de compilaci-n condicional ?ue ya est) de0inido, sin
necesidad de ?ue intervenga ningHn s5mbolo 0unde- para ello. El e$emplo siguiente de0ine un s5mbolo de
compilaci-n condicional ' y despu)s lo de0ine otra ve1.
0de-ine '
0de-ine '
0unde- puede Panular la de0inici-nQ de un s5mbolo de compilaci-n condicional ?ue no est) de0inido. En el
siguiente e$emplo se de0ine un s5mbolo de compilaci-n condicional ' para despu)s eliminar dic=a de0inici-n dos
vecesV el segundo 0unde-, pese a no surtir ningHn e0ecto, sigue siendo v(lido.
0de-ine '
0unde- '
0unde- '
2.#.! /irectias de compilacin condicional
8as directivas de compilaci-n condicional permiten incluir o excluir de 0orma condicional partes de un arc=ivo
de c-digo 0uente.
pp-conditional1
pp-if-section pp-elif-sections
opt
pp-else-section
opt
pp-endif
pp-if-section1
whitespace
opt
0 whitespace
opt
i- whitespace pp-e2pression pp-new-line conditional-
section
opt
pp-elif-sections1
pp-elif-section
pp-elif-sections pp-elif-section
pp-elif-section1
whitespace
opt
0 whitespace
opt
eli- whitespace pp-e2pression pp-new-line conditional-
section
opt
pp-else-section1
whitespace
opt
0 whitespace
opt
else pp-new-line conditional-section
opt
pp-endif1
whitespace
opt
0 whitespace
opt
endi- pp-new-line
conditional-section1
inpt-section
s3ipped-section
s3ipped-section1
s3ipped-section-part
s3ipped-section s3ipped-section-part
s3ipped-section-part1
s3ipped-characters
opt
new-line
pp-directive
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. !3
Especificacin del lenguaje C#
s3ipped-characters1
whitespace
opt
not-n%-er-si&n inpt-characters
opt
not-n%-er-si&n1
Cal6ier car,cter de entrada 4inpt-character5 e2cepto 0
Como indica la sintaxis, las directivas de compilaci-n condicional deben escribirse como con$untos 0ormados
por Oen este ordenRG una directiva 0i-, cero o m(s directivas 0eli-, cero o m(s directivas 0else y una
directiva 0endi-. Entre las directivas se encuentran secciones condicionales de c-digo 0uente. Cada secci-n
est( controlada por la directiva inmediatamente precedente. 7na secci-n condicional puede contener directivas
de compilaci-n condicional anidadas a condici-n de ?ue dic=as directivas 0ormen con$untos completos.
7na condicional pp Opp-conditionalR selecciona como muc=o una de las secciones condicionales Oconditional-
sectionsR contenidas para el procesamiento l)xico normalG
8as expresiones pp Opp-e2pressionR de las directivas 0i- y 0eli- se evalHan por orden =asta ?ue una
produce un resultado true. .i una expresi-n produce true, se selecciona la secci-n condicional
Oconditional-sectionR de la directiva correspondiente.
.i el resultado de todas las expresiones pp Opp-e2pressionR es -alse, y si =ay presente una directiva 0else,
se selecciona la secci-n condicional Oconditional-sectionR de la directiva 0else.
En caso contrario, no se selecciona la secci-n condicional Oconditional-sectionR.
8a secci-n condicional seleccionada, si existe, se procesa como una secci-n entrada Oinpt-sectionR normalG el
c-digo 0uente de la secci-n debe cumplir la gram(tica l)xicaV se generan s5mbolos Oto6ensR a partir de dic=o
c-digo y las directivas de preprocesamiento de la secci-n tienen los e0ectos prescritos.
8as secciones condicionales restantes Oconditional-sectionsR, si existen, se procesan como secciones omitidas
Os3ipped-sectionsRG excepto en lo ?ue respeta a las directivas de preprocesamiento, el c-digo 0uente de la secci-n
no tiene por ?u) cumplir la gram(tica l)xicaV no se generan to6ens a partir del c-digo 0uente de la secci-nV y las
directivas de preprocesamiento de la secci-n deben ser l)xicamente correctas, pero en caso contrario no se
procesan. 2entro de una secci-n condicional Oconditional-sectionR ?ue se =a procesado como secci-n
omitidaOs3ipped-sectionR, cual?uier secci-n condicional Oconditional-sectionR anidada Ocontenida en
construcciones 0i-...0endi- y 0region...0endregion anidadasR tambi)n se procesa como secci-n omitida
Os3ipped-sectionR.
En el e$emplo siguiente se ilustra c-mo pueden anidarse directivas de compilaci-n condicionalG
0de-ine 6ebug .. 6ebugging on
0unde- 1race .. 1racing o--
class *urc"ase1ransaction
{
void Commit() {
0i- 6ebug
C"ec(Consistency();
0i- 1race
Write1oLog(t"is.1oString());
0endi-
0endi-
CommitHel&er();
!
!
Excepto por las directivas de preprocesamiento, el c-digo 0uente omitido no se somete al an(lisis l)xico. 'or
e$emplo, el c-digo siguiente es v(lido, a pesar del comentario sin terminaci-n de la secci-n 0elseG
!# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
0de-ine 6ebug .. 6ebugging on
class *urc"ase1ransaction
{
void Commit() {
0i- 6ebug
C"ec(Consistency();
0else
.> 6o somet"ing else
0endi-
!
!
4o obstante, debe tenerse en cuenta ?ue las directivas de preprocesamiento deben ser l)xicamente correctas
aun?ue se encuentren en secciones omitidas del c-digo 0uente.
8as directivas de preprocesamiento no se procesan cuando aparecen en elementos de entrada ?ue ocupan varias
l5neas. 'or e$emplo, el programaG
class Hello
{
static void Main() {
System.Console.WriteLine([""ello
0i- 6ebug
,orld
0else
Nebras(a
0endi-
");
!
!
da como resultadoG
"ello
0i- 6ebug
,orld
0else
Nebras(a
0endi-
En casos concretos, el con$unto de directivas de preprocesamiento ?ue se procesa puede depender de la
evaluaci-n de la expresi-n pp Opp-e2pressionR. En el e$emploG
0i- I
.>
0else
.> >. class ^ { !
0endi-
se muestra siempre la misma secuencia de to6ens Oclass ^ { !R, independientemente de ?ue I est) de0inido o
no. .i I est( de0inido, las Hnicas directivas ?ue se procesan son 0i- y 0endi-, a causa del comentario en varias
l5neas. .i I no est( de0inido, las tres directivas O0i-, 0else, 0endi-R 0orman parte del con$unto de directivas.
2.#.# /irectias de diagnstico
8as directivas de diagn-stico permiten generar de 0orma expl5cita mensa$es de error y advertencias ?ue se
noti0ican de la misma manera ?ue otros errores y advertencias en tiempo de compilaci-n.
pp-dia&nostic1
whitespace
opt
0 whitespace
opt
error pp-%essa&e
whitespace
opt
0 whitespace
opt
,arning pp-%essa&e
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. !!
Especificacin del lenguaje C#
pp-%essa&e1
new-line
whitespace inpt-characters
opt
new-line
En el e$emploG
0,arning Code revie, needed be-ore c"ec(=in
0i- 6ebug FF Oetail
0error ' build canWt be bot" debug and retail
0endi-
class 1est {...!
se muestra siempre la advertencia OPCode revie9 needed be0ore c=ec6BinQR. &dem(s, si est(n de0inidos los
s5mbolos condicionales 6ebug y Oetail, se muestra el error en tiempo de compilaci-n P& build can_t be bot=
debug and retailQ. /bserve ?ue en un mensa$e pp Opp-%essa&eR puede especi0icarse cual?uier textoG no es
necesario incluir to6ens 0ormados correctamente, como indica el ap-stro0o Ocomilla simpleR de la palabra
can_t.
2.#.$ /irectias de regin
8as directivas de regi-n marcan de 0orma expl5cita regiones del c-digo 0uente.
pp-re&ion1
pp-start-re&ion conditional-section
opt
pp-end-re&ion
pp-start-re&ion1
whitespace
opt
0 whitespace
opt
region pp-%essa&e
pp-end-re&ion1
whitespace
opt
0 whitespace
opt
endregion pp-%essa&e
4o se asocia ningHn signi0icado sem(ntico a las regionesV los programadores y las =erramientas autom(ticas las
utili1an para marcar secciones del c-digo 0uente. El mensa$e especi0icado en una directiva 0region o
0endregion tampoco tiene un signi0icado sem(nticoV sencillamente se usa para identi0icar la regi-n. 8as
directivas 0region y 0endregion correspondientes pueden tener mensa$es pp Opp-%essa&eR di0erentes.
El procesamiento l)xico de una regi-nG
0region
...
0endregion
se corresponde exactamente con el procesamiento l)xico de una directiva de compilaci-n condicional de la
0ormaG
0i- true
...
0endi-
2.#.+ /irectias de l2nea
8as directivas de l5nea permiten cambiar los nHmeros de l5nea y los nombres de arc=ivo de c-digo 0uente ?ue
comunica el compilador en resultados del tipo de advertencias y errores.
8as directivas de l5nea suelen utili1arse en =erramientas de metaprogramaci-n ?ue generan c-digo 0uente C# a
partir de otras entradas de texto.
pp-line1
whitespace
opt
0 whitespace
opt
line whitespace line-indicator pp-new-line
!6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
line-indicator1
deci%al-di&its whitespace file-na%e
deci%al-di&its
de-ault
"idden
file-na%e1
" file-na%e-characters "
file-na%e-characters1
file-na%e-character
file-na%e-characters file-na%e-character
file-na%e-character1
Cal6ier car,cter de entrada 4inpt-character5 e2cepto "
Cuando no aparecen directivas 0line, el compilador muestra en su resultado los nHmeros de l5nea y nombres de
arc=ivo de c-digo 0uente reales. Cuando se procesa una directiva 0line ?ue incluye un indicador de l5nea Oline-
indicatorR ?ue no es de-ault, el compilador trata la l5nea si&iente a la directiva como si tuviera el nHmero de
l5nea dado Oy el nombre de arc=ivo, si se especi0icaR.
7na directiva 0line de-ault invierte el e0ecto de todas las directivas #line anteriores. El compilador
comunica la in0ormaci-n de l5nea real para las l5neas posteriores, exactamente igual ?ue si no se =ubieran
procesado directivas 0line.
7na directiva 0line "idden no produce ningHn e0ecto sobre el arc=ivo ni sobre los nHmeros de l5nea de los
?ue se in0orma en los mensa$es de error, pero s5 a0ecta a la depuraci-n en el nivel de c-digo 0uente. 2urante la
depuraci-n, las l5neas entre una directiva 0line "idden y la siguiente directiva 0line Ono 0line "iddenR
carecer(n de in0ormaci-n de nHmero de l5nea. Cuando se recorre el c-digo en el depurador, estas l5neas se
omiten por completo.
/bserve ?ue los nombres de arc=ivo Ofile-na%eR se di0erencian de los literales de cadena ordinarios en ?ue los
caracteres de escape no se procesanV en los nombres de arc=ivo, el car(cter `Za s-lo designa un car(cter
convencional de barra diagonal inversa.
2.#.- /irectias pragma
8a directiva de preprocesamiento 0&ragma se utili1a para especi0icar in0ormaci-n contextual opcional en el
compilador. 8a in0ormaci-n suministrada en una directiva 0&ragma nunca cambiar( la sem(ntica del programa.
pp-pra&%a1
whitespace
opt
0 whitespace
opt
&ragma whitespace pra&%a--od# pp-new-line
pra&%a--od#1
pra&%a-warnin&--od#
C# proporciona directivas 0&ragma para controlar advertencias del compilador. Es posible ?ue en 0uturas
versiones del lengua$e se incluyan directivas 0&ragma adicionales. 'ara garanti1ar la interoperabilidad con
otros compiladores de C#, el compilador de %icroso0t C# no genera errores de compilaci-n para directivas
0&ragma conocidasV sin embargo, dic=as directivas s5 generan advertencias.
2..+.1 Pra"ma ,arnin"
8a directiva 0&ragma ,arning se utili1a para des=abilitar o restaurar todos los mensa$es de advertencia o un
con$unto en particular durante la compilaci-n del texto del programa subsiguiente.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. !(
Especificacin del lenguaje C#
pra&%a-warnin&--od#1
,arning whitespace warnin&-action
,arning whitespace warnin&-action whitespace warnin&-list
warnin&-action1
disable
restore
warnin&-list1
deci%al-di&its
warnin&-list whitespace
opt
whitespace
opt
deci%al-di&its
7na directiva 0&ragma ,arning ?ue omite la lista de advertencias a0ecta a todas las advertencias. 7na
directiva 0&ragma ,arning ?ue incluye una lista de advertencias a0ecta Hnicamente a a?uellas advertencias
especi0icadas en la lista.
7na directiva 0&ragma ,arning disable des=abilita todas las advertencias o un con$unto determinado de las
mismas.
7na directiva 0&ragma ,arning restore restaura todas las advertencias o un con$unto dado de las mismas
al estado en el ?ue se encontraban al inicio de la unidad de compilaci-n. Tenga en cuenta ?ue si una advertencia
concreta se des=abilit- externamente, una directiva 0&ragma ,arning restore Opara todas las advertencias
o para una espec50icaR no re=abilitar( dic=a advertencia.
En el siguiente e$emplo se muestra el uso de 0&ragma ,arning para des=abilitar temporalmente la advertencia
noti0icada al =acer re0erencia a miembros obsoletos, con el nHmero de advertencia del compilador de
%icroso0t C#.
using System;
class *rogram
{
4%bsolete5
static void Voo() {!
static void Main() {
0&ragma ,arning disable X28
Voo();
0&ragma ,arning restore X28
!
!
!$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
3. %onceptos b)sicos
3.1 Inicio de la aplicacin
7na aplicaci,n es un ensamblado ?ue contiene un p!nto de entrada. Cuando se e$ecuta una aplicaci-n, se crea
un nuevo doinio de aplicaci,n. 'ueden existir varias creaciones de instancias di0erentes de una aplicaci-n
simult(neamente en el mismo e?uipo, cada una con su propio dominio de aplicaci-n.
7n dominio de aplicaci-n =abilita el aislamiento de aplicaciones, al actuar como contenedor del estado de una
aplicaci-n. 7n dominio de aplicaci-n se comporta como contenedor y l5mite de los tipos de0inidos en la
aplicaci-n y en las bibliotecas de clases ?ue utili1a. 8os tipos cargados en un dominio de aplicaci-n son distintos
de los mismos tipos cargados en otro, y las instancias de los ob$etos no se comparten directamente entre
dominios de aplicaci-n. 'or e$emplo, cada dominio de aplicaci-n mantiene su propia copia de variables est(ticas
para estos tipos, y un constructor est(tico de un tipo se e$ecuta como m(ximo una ve1 por dominio de
aplicaci-n. 8as implementaciones tienen libertad para proporcionar mecanismos o directivas espec50icas de la
implementaci-n para la creaci-n y destrucci-n de los dominios de aplicaci-n.
7n inicio de prograa se produce cuando el entorno de e$ecuci-n llama a un m)todo designado, ?ue se conoce
como punto de entrada de la aplicaci-n. Este m)todo de punto de entrada siempre se denomina Main y puede
tener una de las 0irmas siguientesG
static void Main() {...!
static void Main(string45 args) {...!
static int Main() {...!
static int Main(string45 args) {...!
Como se muestra, el punto de entrada de manera opcional puede devolver un valor int. El valor devuelto se
utili1a en la 0inali1aci-n de la aplicaci-n O[3.2R.
El punto de entrada puede tener, opcionalmente, un par(metro 0ormal. El par(metro puede tener cual?uier
nombre, pero el tipo del par(metro debe ser string45. .i el par(metro 0ormal est( presente, el entorno de
e$ecuci-n crea y pasa un argumento string45 ?ue contiene los argumentos de l5nea de comandos especi0icados
al iniciar la aplicaci-n. El argumento string45 nunca es null, pero puede tener longitud cero si no se encuentra
especi0icado ningHn argumento de l5nea de comandos.
2ado ?ue C# acepta la sobrecarga de m)todos, una clase o una estructura puede contener varias de0iniciones del
mismo m)todo, a condici-n de ?ue todas tengan una 0irma di0erente. 4o obstante, ninguna clase o estructura de
un mismo programa podr( contener m(s de un m)todo denominado Main cuya de0inici-n lo certi0i?ue para ser
utili1ado como punto de entrada de aplicaci-n. .in embargo, s5 se permiten otras versiones sobrecargadas de
Main, a condici-n de ?ue tengan m(s de un par(metro o de ?ue su Hnico par(metro no sea de tipo string45.
7na aplicaci-n puede estar compuesta por varias clases o estructuras. Es posible para m(s de una de esas clases
o estructuras contener un m)todo denominado Main cuya de0inici-n lo certi0ica para ser utili1ado como punto
de entrada de la aplicaci-n. En tales casos, debe utili1arse un mecanismo externo Opor e$emplo, una opci-n de
compilador de l5nea de comandosR para seleccionar uno de estos m)todos Main como punto de entrada.
En C#, todos los m)todos deben estar de0inidos como miembros de una clase o una estructura. 4ormalmente,
la accesibilidad declarada O[3..1R de un m)todo est( determinada por los modi0icadores de acceso O[1".3.R
especi0icados en su declaraci-n y, de 0orma similar, la accesibilidad declarada de un tipo est( determinada por
los modi0icadores de acceso especi0icados en su declaraci-n. 'ara ?ue un m)todo dado de un tipo concreto sea
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. !"
Especificacin del lenguaje C#
invocable, tanto el tipo como el miembro deben ser accesibles. 4o obstante, el punto de entrada de la aplicaci-n
es un caso especial. En concreto, el entorno de e$ecuci-n puede tener acceso al punto de entrada de la aplicaci-n
con independencia de su accesibilidad declarada y de la accesibilidad declarada de sus declaraciones de tipo
envolvente.
Es posible ?ue el m)todo de punto de entrada de la aplicaci-n no se encuentre dentro de una declaraci-n de
clase gen)rica.
& todos los dem(s respectos, los m)todos de punto de entrada se comportan como los de punto de no entrada.
3.2 7inali8acin de la aplicacin
8a finali-aci,n de la aplicaci,n devuelve el control al entorno de e$ecuci-n.
.i el tipo del valor devuelto por el m)todo de punto de entrada de la aplicaci-n es int, el valor devuelto
cumple la 0unci-n de cdigo de estado de finali6acin de la misma. El prop-sito de este c-digo es permitir la
comunicaci-n del )xito o el error al entorno de e$ecuci-n.
.i el tipo del valor devuelto del m)todo de punto de entrada es void, cuando se alcan1a la llave de cierre O!R,
?ue 0inali1a el m)todo, o cuando se e$ecuta una instrucci-n return ?ue no contiene una expresi-n, se produce
un c-digo de estado de 0inali1aci-n igual a 3.
&ntes de la 0inali1aci-n de una aplicaci-n, se llama a destructores para todos los ob$etos ?ue aHn no =ayan sido
sometidos a la recolecci-n de elementos no utili1ados Osalvo ?ue se =aya suprimido este tipo de limpie1a
mediante, por e$emplo, una llamada al m)todo de biblioteca SC.Su&&ressVinali?eR.
3.3 /eclaraciones
8as declaraciones de un programa de C# de0inen los elementos constituyentes del programa. 8os programas de
C# se organi1an mediante el uso de espacios de nombres O[+R, ?ue pueden contener declaraciones de tipo y
declaraciones de espacio de nombres anidadas. 8as declaraciones de tipo O[+.#R se utili1an para de0inir clases
O[1"R, estructuras O[1".14R, inter0aces O[13R, enumeraciones O[14R y delegados O[1R. 8as categor5as de los
miembros permitidos en una declaraci-n de tipo dependen de la 0orma de la declaraci-n. 'or e$emplo, las
declaraciones de clase pueden contener declaraciones para las constantes O[1".4R, campos O[1".R, m)todos
O[1".#R, propiedades O[1".*R, eventos O[1".8R, indi1adores O[1".+R, operadores O[1".1"R, constructores de
instancia O[1".11R, constructores est(ticos O[1".12R, destructores O[1".13R y tipos anidados.
7na declaraci-n de0ine un nombre en el espacio de declaraci-n Odeclaration spaceR al ?ue pertenece la
declaraci-n. Con la excepci-n de los miembros sobrecargados O[3.#R, es un error en tiempo de compilaci-n
contar con dos o m(s declaraciones ?ue introducen miembros con el mismo nombre en un espacio de
declaraci-n. 4o est( permitido ?ue un espacio de declaraci-n contenga categor5as de miembros di0erentes con
el mismo nombre. 'or e$emplo, un espacio de declaraci-n no puede contener un campo y un m)todo con el
mismo nombre.
Existen varios tipos di0erentes de espacios de declaraci-n, como se explica a continuaci-n.
2entro de todos los arc=ivos de c-digo 0uente de un programa, las declaraciones de miembros de espacios
de nombres Ona%espace-%e%-er-declarationsR sin una declaraci-n de espacio de nombres envolvente son
miembros de un solo espacio de declaraci-n combinado, denominado espacio de declaraci-n global Oglo/al
declaration spaceR.
2entro de todos los arc=ivos de c-digo 0uente de un programa, las declaraciones de miembros de espacios
de nombres Ona%espace-%e%-er-declarationsR de las declaraciones de espacio de nombres Ona%espace-
declarationsR ?ue tienen el mismo nombre completo del espacio de nombres son miembros de un solo
espacio de declaraci-n combinado.
6' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Cada declaraci-n de clase, estructura o inter0a1 crea un nuevo espacio de declaraci-n. 8os nombres se
introducen en este espacio de declaraci-n mediante declaraciones de miembros de clase Oclass-%e%-er-
declarationsR, declaraciones de miembros de estructura Ostrct-%e%-er-declarationsR, declaraciones de
miembros de inter0a1 Ointerface-%e%-er-declarationsR o par(metros de tipo t#pe-para%eters. Excepto en las
declaraciones de constructores de instancia y declaraciones de constructor est(tico sobrecargadas, una clase
o estructura no puede contener una declaraci-n de miembro con el mismo nombre ?ue la clase o la
estructura. 7na clase, estructura o inter0a1 permite la declaraci-n de m)todos e indi1adores sobrecargados.
&simismo, las clases y estructuras admiten la declaraci-n de operadores y constructores de instancia
sobrecargados. 'or e$emplo, una clase, una estructura o una inter0a1 pueden contener varias declaraciones
de m)todo con el mismo nombre, a condici-n de ?ue dic=as declaraciones di0ieran en su 0irma O[3.#R.
2ebe tenerse en cuenta ?ue las clases base no contribuyen al espacio de declaraci-n de una clase, y ?ue las
inter0aces base no contribuyen al espacio de declaraci-n de una inter0a1. 'or lo tanto, una clase o inter0a1
derivada tiene permitido declarar un miembro con el mismo nombre ?ue un miembro =eredado. .e dice ?ue
un miembro como )ste oc!lta al miembro =eredado.
7na declaraci-n de delegado crea un espacio de declaraci-n nuevo. 8os nombres se introducen en este
espacio de declaraci-n a trav)s de par(metros 0ormales Opar,%etros de tipo fi>ado y %atrices de
par,%etrosR y par,%etros de tipo.
7na declaraci-n de enumeraci-n crea un espacio de declaraci-n nuevo. 8os nombres se introducen en este
espacio de declaraci-n mediante declaraciones de miembros de enumeraci-n Oen%-%e%-er-declarationsR.
Cada declaraci-n de m)todo, declaraci-n de indi1ador, declaraci-n de operador, declaraci-n de constructor
de instancia y 0unci-n an-nima crea un nuevo espacio de declaraci-n denominado espacio de declaraci,n
de la varia/le local. 8os nombres se introducen en este espacio de declaraci-n a trav)s de par(metros
0ormales Opar,%etros de tipo fi>ado y %atrices de par,%etrosR y par,%etros de tipo. El cuerpo del miembro
de 0unci-n o de la 0unci-n an-nima, si existe, se considera anidado dentro del espacio de declaraci-n de la
variable local. bue el espacio de declaraci-n de una variable local y el espacio de declaraci-n de una
variable local anidado contengan elementos con el mismo nombre supone un error. 'or lo tanto, dentro de
un espacio de declaraci-n anidado no es posible declarar una variable o constante local con el mismo
nombre ?ue una variable o constante local contenida en un espacio de declaraci-n. Es posible ?ue dos
espacios de declaraci-n contengan elementos con el mismo nombre siempre y cuando ninguno de los
espacios de declaraci-n contenga al otro.
Cada -lo6e o blo?ue s9itc= Oswitch--loc3R, as5 como una instrucci-n for, foreach y sin&, crea un espacio
de declaraci-n de la variable local para variables y constantes locales. 8os nombres se introducen en este
espacio de declaraci-n mediante declaraciones de variable local Olocal-varia-le-declarationsR y
declaraciones de constante local Olocal-constant-declarationsR. Tenga en cuenta ?ue los blo?ues ?ue tienen
lugar como o dentro del cuerpo de un miembro de 0unci-n o una 0unci-n an-nima se anidan dentro del
espacio de declaraci-n de la variable local declarado por a?uellas 0unciones para sus par(metros. bue, por
e$emplo, un m)todo con una variable local y un par(metro tengan el mismo nombre supone un error.
Cada blo?ue O-loc3R o blo?ue s9itc= Oswitch--loc3R crea un espacio de declaraci-n independiente para las
eti?uetas. 8os nombres se introducen en este espacio de declaraci-n mediante instrucciones con eti?uetas
Ola-eled-state%entsR y se =ace re0erencia a ellos mediante instrucciones goto O&oto-state%entsR. El espacio
de declaraci,n de eti"!etas de un blo?ue incluye blo?ues anidados. 'or lo tanto, dentro de un blo?ue
anidado no es posible declarar una eti?ueta del mismo nombre ?ue una eti?ueta contenida en un blo?ue
contenedor.
El orden textual de declaraci-n de los nombres generalmente carece de importancia. &s5, el orden textual no
resulta signi0icativo para la declaraci-n o el uso de espacios de nombres, constantes, m)todos, propiedades,
eventos, indi1adores, operadores, constructores de instancia, destructores, constructores est(ticos o tipos.
El orden de declaraci-n es signi0icativo de las siguientes 0ormasG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 61
Especificacin del lenguaje C#
El orden de declaraci-n de las declaraciones de campos y de variables locales determina el orden en ?ue
se e$ecutan sus iniciali1adores Osi existenR.
8as variables locales no se pueden utili1ar antes de su de0inici-n O[3.*R.
El orden de declaraci-n para las declaraciones de miembros de enumeraci-n O[14.3R es importante cuando
se omiten los valores de expresi-n constante Oconstant-e2pressionR.
El espacio de declaraci-n de un espacio de nombres es Pde extremo abiertoQ, es decir, dos declaraciones de
espacio de nombres con un mismo nombre completo contribuir(n al mismo espacio de declaraci-n. 'or e$emploG
names&ace Megacor&.6ata
{
class Customer
{
...
!
!
names&ace Megacor&.6ata
{
class %rder
{
...
!
!
8as dos declaraciones de espacios de nombres anteriores contribuyen al mismo espacio de declaraci-n, en este
caso declarando dos clases con los nombres completos Megacor&.6ata.Customer y
Megacor&.6ata.%rder. Como las dos declaraciones contribuyen al mismo espacio de declaraci-n, si cada
una contiene una declaraci-n de clase con el mismo nombre se producir( un error en tiempo de compilaci-n.
Como se especi0ic- anteriormente, el espacio de declaraci-n de un blo?ue incluye cual?uier blo?ue anidado.
2e este modo, en el siguiente e$emplo, los m)todos V y S producen errores en tiempo de compilaci-n por?ue el
nombre i est( declarado en el blo?ue exterior y no se puede volver a declarar en el blo?ue interior. .in embargo,
los m)todos H e $ son v(lidos por?ue los dos caracteres i se declaran en blo?ues independientes no anidados.
class '
{
void V() {
int i + 3;
i- (true) {
int i + 2;
!
!
void S() {
i- (true) {
int i + 3;
!
int i + 2;
!
void H() {
i- (true) {
int i + 3;
!
i- (true) {
int i + 2;
!
!
62 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
void $() {
-or (int i + 3; i D 23; i<<)
H();
-or (int i + 3; i D 23; i<<)
H();
!
!
3.! &iembros
8os espacios de nombres y los tipos tienen ie/ros. 8os miembros de una entidad est(n generalmente
disponibles mediante el uso de un nombre completo compuesto por una re0erencia a la entidad seguida de un
to6en P.Q y el nombre del miembro.
8os miembros de un tipo se declaran en la declaraci-n de tipo o se heredan de la clase base del tipo. .i un tipo
se deriva de una clase base, todos los miembros de dic=a clase, excepto los constructores de instancia,
destructores y constructores est(ticos, pasan a ser miembros del tipo derivado. 8a accesibilidad declarada de un
miembro de clase base no controla si el miembro se =eredaG la =erencia se ampl5a a cual?uier miembro ?ue no
sea un constructor de instancia, un constructor est(tico o un destructor. 4o obstante, un miembro =eredado
puede no estar accesible en un tipo derivado, ya sea a causa de su accesibilidad declarada O[3..1R o por?ue est(
oculto por una declaraci-n del propio tipo O[3.*.1.2R.
3.!.1 &iembros de espacio de nombres
8os espacios de nombres y los tipos ?ue no tienen un espacio de nombres envolvente son miembros del espacio
de no/res glo/al. Esto corresponde directamente a los nombres declarados en el espacio de declaraci-n
global.
8os espacios de nombres y los tipos declarados en de un espacio de nombres son miembros de dic=o espacio.
Esto corresponde directamente a los nombres declarados en el espacio de declaraci-n del espacio de nombres.
8os espacios de nombres no presentan restricciones de acceso. 4o es posible declarar espacios de nombres
privados, protegidos o internos, y los nombres de los espacios de nombres siempre son accesibles pHblicamente.
3.!.2 &iembros de estructura
8os miembros de una estructura son los miembros declarados en la estructura y los miembros =eredados de la
clase base directa de la estructura System.Ualue1y&e y la clase base indirecta object.
8os miembros de un tipo simple se corresponden directamente con los del tipo de la estructura con alias por el
tipo simpleG
8os miembros de sbyte son los miembros de la estructura System.S:yte.
8os miembros de byte son los miembros de la estructura System.:yte.
8os miembros de s"ort son los miembros de la estructura System.$nt2X.
8os miembros de us"ort son los miembros de la estructura System.;$nt2X.
8os miembros de int son los miembros de la estructura System.$nt98.
8os miembros de uint son los miembros de la estructura System.;$nt98.
8os miembros de long son los miembros de la estructura System.$ntXJ.
8os miembros de ulong son los miembros de la estructura System.;$ntXJ.
8os miembros de c"ar son los miembros de la estructura System.C"ar.
8os miembros de -loat son los miembros de la estructura System.Single.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 63
Especificacin del lenguaje C#
8os miembros de double son los miembros de la estructura System.6ouble.
8os miembros de decimal son los miembros de la estructura System.6ecimal.
8os miembros de bool son los miembros de la estructura System.:oolean.
3.!.3 &iembros de enumeraciones
8os miembros de una enumeraci-n son las constantes declaradas en la enumeraci-n y los miembros =eredados
de la clase base directa de la enumeraci-n System.)num y las clases base indirectas System.Ualue1y&e
y object.
3.!.! &iembros de clase
8os miembros de una clase son a?uellos ?ue se declaran en la clase y los ?ue se =eredan de la clase base Oa
excepci-n de la clase object, ?ue no tiene clase baseR. Entre los miembros =eredados de la clase base se
incluyen las constantes, los campos, los m)todos, las propiedades, los eventos, los indi1adores, los operadores
y los tipos de la clase base, pero no los constructores de instancia, los destructores ni los constructores est(ticos
de la clase base. 8os miembros de la base clase se =eredan con independencia de su accesibilidad.
8a declaraci-n de una clase puede contener declaraciones de constantes, campos, m)todos, propiedades,
eventos, indi1adores, operadores, constructores de instancia, destructores, constructores est(ticos y tipos.
8os miembros de object y string se corresponden directamente con los miembros de los tipos de clases
de los ?ue son aliasG
8os miembros de object son los miembros de la clase System.%bject.
8os miembros de string son los miembros de la clase System.String.
3.!.# &iembros de interfa8
8os miembros de una inter0a1 son los miembros declarados en la inter0a1 y en todas las inter0aces base de la
misma. 8os miembros de la clase object no son, estrictamente =ablando, miembros de ninguna inter0a1
O[13.2R. .in embargo, los miembros de la clase object est(n disponibles a trav)s de la bHs?ueda de miembros
en cual?uier tipo de inter0a1 O[*.3R.
3.!.$ &iembros de matri8
8os miembros de una matri1 son los miembros =eredados de la clase System.'rray.
3.!.+ &iembros de delegados
8os miembros de un delegado son los miembros =eredados de la clase System.6elegate.
3.# 'cceso a miembros
8as declaraciones a miembros aportan control sobre el acceso a los miembros. 8a accesibilidad de un miembro
se establece mediante la accesibilidad declarada O[3..1R del miembro combinada con la accesibilidad del tipo
contenedor inmediato, si existe.
Cuando se permite el acceso a un miembro concreto, se dice ?ue )ste es accesi/le. 'or otro lado, cuando no se
permite el acceso a un miembro concreto, se dice ?ue )ste es inaccesi/le. El acceso a un miembro est( permitido
cuando la ubicaci-n textual en la ?ue tiene lugar el acceso est( incluida en el dominio de accesibilidad O[3..2R
del miembro.
6# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
3.#.1 'ccesibilidad declarada
8a accesi/ilidad declarada de un miembro puede ser cual?uiera de las siguientesG
'ublic, ?ue se selecciona mediante la inclusi-n de un modi0icador &ublic en la declaraci-n del miembro.
El signi0icado intuitivo de &ublic es Pacceso sin restriccionesQ.
'rotected, ?ue se selecciona mediante la inclusi-n de un modi0icador &rotected en la declaraci-n del
miembro. El signi0icado intuitivo de &rotected es Pacceso restringido para la clase contenedora o los tipos
derivados de ellaQ.
!nternal, ?ue se selecciona mediante la inclusi-n de un modi0icador internal en la declaraci-n del
miembro. El signi0icado intuitivo de internal es Pacceso restringido al programaQ.
'rotected internal Oes decir, protegida o internaR, ?ue se selecciona mediante la inclusi-n de los
modi0icadores &rotected e internal en la declaraci-n del miembro. El signi0icado intuitivo de
&rotected internal es Pacceso restringido al programa actual o a los tipos derivados de la clase
contenedoraQ.
'rivate, ?ue se selecciona mediante la inclusi-n de un modi0icador &rivate en la declaraci-n del miembro.
El signi0icado intuitivo de &rivate es Pacceso restringido al tipo contenedorQ.
.egHn el contexto en el ?ue se produce la declaraci-n de un miembro, s-lo se permite declarar ciertos tipos de
accesibilidad. &dem(s, si una declaraci-n del miembro no incluye modi0icadores de acceso, el contexto en ?ue
tiene lugar la declaraci-n determina la accesibilidad declarada predeterminada.
8os espacios de nombres tienen impl5citamente la accesibilidad declarada &ublic. 8os modi0icadores de
acceso no se pueden utili1ar en las declaraciones de espacios de nombres.
8os tipos declarados en las unidades de compilaci-n o los espacios de nombres pueden tener la accesibilidad
declarada &ublic o internal y su valor predeterminado puede ser internal.
8os miembros de clase pueden tener cual?uiera de las cinco clases de accesibilidad declarada y el valor
predeterminado de la accesibilidad declarada &rivate. O2ebe tenerse en cuenta ?ue un tipo declarado como
miembro de una clase s-lo puede tener una de las cinco clases de accesibilidad declarada, mientras ?ue un
tipo declarado como miembro de un espacio de nombres s-lo puede tener la accesibilidad declarada &ublic
o internal.R
8os miembros de estructura pueden tener la accesibilidad declarada &ublic, internal o &rivate, siendo
el valor predeterminado &rivate, puesto ?ue las estructuras son impl5citamente de tipo sealed. 8os
miembros de estructura introducidos en una estructura Oes decir, no =eredados por ellaR no pueden tener una
accesibilidad declarada &rotected o &rotected internal. Tenga en cuenta ?ue un tipo declarado como
miembro de una estructura accesibilidad declarada &ublic, internal o &rivate, mientras ?ue un tipo
declarado como miembro de un espacio de nombres s-lo puede tener la accesibilidad declarada &ublic o
internal.
8os miembros de inter0a1 tienen impl5citamente la accesibilidad declarada &ublic. 8os modi0icadores de
acceso no se pueden utili1ar en las declaraciones de miembros de inter0a1.
8os miembros de enumeraci-n tienen impl5citamente la accesibilidad declarada &ublic. 8os modi0icadores
de acceso no pueden utili1arse en las declaraciones de miembros de enumeraci-n.
3.#.2 /ominios de accesibilidad
El doinio de accesi/ilidad de un miembro est( 0ormado por las secciones Oposiblemente separadasR de texto
del programa en las ?ue est( permitido el acceso al miembro. 'ara de0inir el dominio de accesibilidad de un
miembro, se dice ?ue un miembro es de nivel s!perior si no est( declarado dentro de un tipo, y se dice ?ue est(
anidado si se declara dentro de otro tipo. &simismo, el te.to de prograa de un programa se de0ine como todo
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 6!
Especificacin del lenguaje C#
el texto de programa contenido en todos los arc=ivos de c-digo 0uente. El texto de programa de un tipo se de0ine
como todo el texto del programa contenido entre los to6ens de apertura y cierre P{Q y P!Q del cuerpo de clase
Oclass--od#R, del cuerpo de estructura Ostrct--od#R, del cuerpo de inter0a1 Ointerface--od#R o del cuerpo de
enumeraci-n Oen%--od#R del tipo Oincluidos, posiblemente, los tipos anidados dentro del tipoR.
El dominio de accesibilidad de un tipo prede0inido Ocomo object, int o doubleR es ilimitado.
El dominio de accesibilidad de un tipo sin enla1ar de nivel superior 1 O[R declarado en un programa * se de0ine
como sigueG
8a accesibilidad declarada de 1 es &ublic, el dominio de accesibilidad de 1 es el texto del programa de *
y cual?uier programa ?ue =aga re0erencia a *.
.i la accesibilidad declarada de 1 es internal, el dominio de accesibilidad de 1 es el texto del programa
de *.
& partir de estas de0iniciones, se deduce ?ue el dominio de accesibilidad de un tipo sin enla1ar de nivel superior
es, al menos, el texto del programa en el ?ue se declara ese tipo.
El dominio de accesibilidad para un tipo construido 1D'2 ...'NE es la intersecci-n entre el dominio de
accesibilidad del tipo gen)rico sin enla1ar 1 y los dominios de accesibilidad de los argumentos de tipo
'2 ...'N.
El dominio de accesibilidad de un miembro anidado M declarado en un tipo 1 dentro de un programa * se de0ine
como sigue Oteniendo en cuenta ?ue M probablemente sea un tipoRG
.i la accesibilidad declarada de M es &ublic, el dominio de accesibilidad de M es el dominio de 1.
.i la accesibilidad declarada de M es &rotected internal, 6 ser( la uni-n del texto del programa de *
y del texto del programa de cual?uier tipo derivado de 1, ?ue se declara 0uera de *. El dominio de
accesibilidad de M es la intersecci-n del dominio de accesibilidad de 1 con 6.
.i la accesibilidad declarada de M es &rotected internal, 6 ser( la uni-n del texto del programa de 1
y del texto del programa de cual?uier tipo derivado de 1. El dominio de accesibilidad de M es la intersecci-n
del dominio de accesibilidad de 1 con 6.
.i la accesibilidad declarada de M es internal, el dominio de accesibilidad de M es la intersecci-n del
dominio de accesibilidad de 1 con el texto de programa de *.
.i la accesibilidad declarada de M es &rivate, el dominio de accesibilidad de M es el texto del programa de
1.
2e estas de0iniciones se deduce ?ue el dominio de accesibilidad de un tipo anidado es siempre, al menos, el
texto de programa del tipo donde el miembro aparece declarado. &simismo, se concluye ?ue el dominio de
accesibilidad de un miembro nunca es m(s inclusivo ?ue el dominio de accesibilidad del tipo en el ?ue se
declara el miembro.
En t)rminos intuitivos, cuando se obtiene acceso a un tipo o un miembro M, se evalHan los pasos siguientes para
garanti1ar ?ue el acceso est) permitidoG
En primer lugar, si M se declara dentro de un tipo Opor oposici-n a una unidad de compilaci-n o un espacio
de nombresR, se produce un error en tiempo de compilaci-n si el tipo no est( accesible.
Entonces, si M es &ublic, el acceso est( permitido.
/ bien, si M es &rotected internal, el acceso est( permitido si se produce dentro del programa en el ?ue
est( declarado M o si se produce dentro de una clase derivada de la clase en la ?ue est( declarado M y tiene
lugar por medio del tipo de la clase derivada O[3..3R.
66 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
/ bien, si M es &rotected, el acceso est( permitido si se produce dentro de la clase en la ?ue est( declarado
M o si se produce dentro de una clase derivada de la clase en la ?ue est( declarado M y tiene lugar por medio
del tipo de la clase derivada O[3..3R.
/ bien, si M es internal, el acceso est( permitido si ocurre dentro del programa en el ?ue est( declarado M.
/ bien, si M es &rivate, el acceso est( permitido si ocurre dentro del programa en el ?ue est( declarado M.
2e lo contrario, el tipo o el miembro es inaccesible y se produce un error en tiempo de compilaci-n.
En el e$emplo
&ublic class '
{
&ublic static int I;
internal static int `;
&rivate static int P;
!
internal class :
{
&ublic static int I;
internal static int `;
&rivate static int P;
&ublic class C
{
&ublic static int I;
internal static int `;
&rivate static int P;
!
&rivate class 6
{
&ublic static int I;
internal static int `;
&rivate static int P;
!
!
las clases y los miembros tienen los siguientes dominios de accesibilidadG
El dominio de accesibilidad de ' y '.I es ilimitado.
El dominio de accesibilidad de '.`, :, :.I, :.`, :.C, :.C.I, y :.C.` es el texto del programa
contenedor.
El dominio de accesibilidad de '.P es el texto del programa de '.
El dominio de accesibilidad de :.P y :.6 es el texto de programa de :, incluido el texto de programa
de :.C y de :.6.
El dominio de accesibilidad de :.C.P es el texto del programa de :.C.
El dominio de accesibilidad de :.6.I y :.6.` es el texto de programa de :, incluido el texto de programa
de :.C y de :.6.
El dominio de accesibilidad de :.6.P es el texto del programa de :.6.
Como muestra el e$emplo, el dominio de accesibilidad de un miembro nunca es mayor ?ue el de un tipo
contenedor. 'or e$emplo, aun?ue todos los miembros I tengan una accesibilidad declarada como public, todos
excepto '.I tienen dominios de accesibilidad ?ue est(n restringidos por un tipo contenedor.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 6(
Especificacin del lenguaje C#
Como se explica en la [3.4, todos los miembros de una clase base, a excepci-n de los constructores de instancia,
destructores y constructores est(ticos, son =eredados por tipos derivados. Esto incluye incluso a los miembros
privados de una clase base. 4o obstante, el dominio de accesibilidad de un miembro privado s-lo incluye el
texto del programa del tipo donde el miembro aparece declarado. En el e$emplo
class '
{
int #;
static void V(: b) {
b.# + 2; .. %(
!
!
class :/ '
{
static void V(: b) {
b.# + 2; .. )rror # not accessible
!
!
la clase : =ereda el miembro privado # de la clase '. 2ado ?ue el miembro es privado, s-lo est( accesible dentro
del cuerpo de clase Oclass--od#R de '. 'or lo tanto, el acceso a b.# es correcto en el m)todo '.V, pero no en el
m)todo :.V.
3.#.3 'cceso protegido para miembros de instancia
Cuando se obtiene acceso a un miembro de instancia &rotected 0uera del texto del programa de la clase en la
?ue est( declarado, y cuando se obtiene acceso a un miembro de instancia &rotected internal 0uera del
texto del programa en el ?ue est( declarado, el acceso debe tener lugar dentro de una declaraci-n de clase
derivada de la clase en la ?ue est( declarada. Es m(s, es necesario ?ue el acceso se produ1ca a trav?s de una
instancia de ese tipo de clase derivada o un tipo de clase construido a partir de la misma. Esta restricci-n impide
?ue una clase derivada tenga acceso a miembros protegidos de otras clases derivadas, incluso cuando los
miembros son =eredados de la misma clase base.
.upongamos ?ue : es una clase base ?ue declara un miembro de instancia M protegido, y ?ue 6 es una clase ?ue
se deriva de :. 2entro del cuerpo de clase Oclass--od#R de 6, el acceso a M puede tener uno de los siguientes
0ormatosG
7n nombre de tipo Ot#pe-na%eR o expresi-n primaria Opri%ar#-e2pressionR sin cali0icar de la 0orma M.
7na expresi-n primaria Opri%ar#-e2pressionR de la 0orma ).M, siempre ?ue el tipo de ) sea 1 o una clase
derivada de 1, donde 1 es el tipo de clase 6, o un tipo de clase construido a partir de 6.
7na expresi-n primaria Opri%ar#-e2pressionR de la 0orma base.M.
&dem(s de estas 0ormas de acceso, una clase derivada puede tener acceso a un constructor de instancia
protegido de una clase base en un iniciali1ador de constructor Oconstrctor-initiali0erR O[1".11.1R.
En el e$emplo
&ublic class '
{
&rotected int #;
static void V(' a : b) {
a.# + 2; .. %(
b.# + 2; .. %(
!
!
6$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
&ublic class :/ '
{
static void V(' a : b) {
a.# + 2; .. )rror must access t"roug" instance o- :
b.# + 2; .. %(
!
!
dentro de ', es posible obtener acceso a # mediante instancias de ' y de :, puesto ?ue en cual?uiera de los dos
casos el acceso tiene lugar %ediante una instancia de ' o una clase derivada de '. 4o obstante, dentro de :, no
es posible el acceso a # por medio de una instancia de ', puesto ?ue ' no se deriva de :.
En el e$emplo
class CD1E
{
&rotected 1 #;
!
class 6D1E/ CD1E
{
static void V() {
6D1E dt + ne, 6D1E();
6DintE di + ne, 6DintE();
6DstringE ds + ne, 6DstringE();
dt.# + de-ault(1);
di.# + 289;
ds.# + "test";
!
!
se permiten las tres asignaciones a # por?ue todas se dan gracias a instancias de tipos de clase construidos desde
el tipo gen)rico.
3.#.! 9estricciones de accesibilidad
&lgunas construcciones del lengua$e C# re?uieren ?ue un tipo sea al enos tan accesi/le coo un miembro
u otro tipo. .e dice ?ue un tipo 1 es por lo menos tan accesible como un miembro o un tipo M si el dominio
de accesibilidad de 1 es un supracon$unto del dominio de accesibilidad de M. Es decir, 1 es por lo menos tan
accesible como M si 1 es accesible en todos los contextos donde M es accesible.
Existen las siguientes restricciones de la accesibilidadG
8a clase base directa de un tipo de clase debe ser al menos tan accesible como el propio tipo de clase.
8as inter0aces base expl5citas de un tipo de inter0a1 deben ser al menos tan accesibles como el propio tipo
de inter0a1.
El tipo de valor devuelto y los tipos de los par(metros de un tipo delegado deben ser al menos tan accesibles
como el propio tipo delegado.
El tipo de una constante debe ser al menos tan accesible como la propia constante.
El tipo de un campo debe ser al menos tan accesible como el propio campo.
El tipo de valor devuelto y los tipos de par(metros de un m)todo deben ser al menos tan accesibles como
el propio m)todo.
El tipo de una propiedad debe ser al menos tan accesible como la misma propiedad.
El tipo de un evento debe ser al menos tan accesible como el propio evento.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 6"
Especificacin del lenguaje C#
El tipo y los tipos de par(metros de un indi1ador deben ser al menos tan accesibles como el propio
indi1ador.
El tipo de valor devuelto y los tipos de par(metros de un operador deben ser al menos tan accesibles como
el propio operador.
8os tipos de par(metros de un constructor de instancia deben ser al menos tan accesibles como el propio
constructor de instancia.
En el e$emplo
class ' {...!
&ublic class :/ ' {...!
la clase : produce un error en tiempo de compilaci-n por?ue ' no tiene una capacidad de acceso m5nima
como :.
&n(logamente, en el e$emploG
class ' {...!
&ublic class :
{
' V() {...!
internal ' S() {...!
&ublic ' H() {...!
!
el m)todo H de : produce un error en tiempo de compilaci-n por?ue el tipo de valor devuelto ' no es por lo
menos tan accesible como el m)todo.
3.$ 7irmas y sobrecargas
8os m)todos, constructores de instancia, indi1adores y operadores est(n caracteri1ados por sus firasG
8a 0irma de un m)todo se compone del nombre del m)todo, el nHmero de par(metros de tipo y el tipo y la
categor5a Ovalor, re0erencia o resultadoR de sus par(metros 0ormales, considerados de i1?uierda a derec=a.
Con este 0in, todo par(metro de tipo del m)todo ?ue se produce en el tipo de un par(metro 0ormal se
identi0ica no por su nombre, sino por su posici-n ordinal en la lista de argumentos de tipo del m)todo. 8a
0irma de un m)todo no incluye espec50icamente el tipo de valor devuelto, el modi0icador &arams ?ue puede
especi0icarse para el par(metro situado m(s a la derec=a, ni la restricci-n de par(metro de tipo opcional.
8a 0irma de un constructor de instancias se compone del tipo y la categor5a Ovalor, re0erencia o resultadoR
de sus par(metros 0ormales, considerados de i1?uierda a derec=a. 8a 0irma de un constructor de instancias
no incluye espec50icamente el modi0icador &arams, ?ue puede especi0icarse para el par(metro situado m(s
a la derec=a.
8a 0irma de un indi1ador est( 0ormada por el tipo de sus par(metros 0ormales, considerados de i1?uierda a
derec=a. 8a 0irma de un indi1ador no incluye espec50icamente el tipo de elemento ni el modi0icador &arams
?ue puede estar especi0icado para el par(metro situado m(s a la derec=a.
8a 0irma de un operador se compone del nombre del operador y del tipo de sus par(metros 0ormales,
considerados de i1?uierda a derec=a. 8a 0irma de un operador no incluye espec50icamente el tipo del
resultado.
8as 0irmas constituyen el mecanismo de =abilitaci-n ?ue permite so/recargar los miembros de clases,
estructuras e inter0acesG
(' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a sobrecarga de los m)todos permite ?ue una clase, estructura o inter0a1 declare varios m)todos con
el mismo nombre, siempre ?ue sus 0irmas sean Hnicas dentro de esa clase, estructura o inter0a1.
8a sobrecarga de los constructores de instancia permite ?ue una clase o una estructura declare varios
constructores de instancia, a condici-n de ?ue sus 0irmas sean Hnicas dentro de esa clase o estructura.
8a sobrecarga de los indi1adores permite ?ue una clase, estructura o inter0a1 declare varios indi1adores,
siempre ?ue sus 0irmas sean Hnicas dentro de esa clase, estructura o inter0a1.
8a sobrecarga de los operadores permite ?ue una clase o una estructura declare varios operadores con el
mismo nombre, siempre ?ue sus 0irmas sean Hnicas dentro de esa clase o estructura.
&un?ue los modi0icadores de par(metros out y re- se consideran como parte de una 0irma, los miembros
declarados en un tipo Hnico no pueden di0erir en la 0irma Hnicamente por re- y out. .i dos miembros se
declaran en el mismo tipo con 0irmas ?ue ser5an iguales si todos los par(metros de ambos m)todos con
modi0icadores out se cambiaran a modi0icadores re-, se produce un error de compilaci-n. 'ara otros
prop-sitos de coincidencia de 0irma Opor e$emplo, para ocultar o invalidarR, re- y out se consideran como parte
de la 0irma y no coinciden entre s5. OEsta restricci-n se utili1a para permitir traducir con 0acilidad los programas
de C# para ?ue se e$ecuten en Common 8anguage !n0rastructure OC8!R, ?ue no proporciona una manera de
de0inir m)todos ?ue solamente se di0erencian en re- y out.R
El siguiente e$emplo muestra un con$unto de declaraciones de m)todos sobrecargados con sus 0irmas.
inter-ace $1est
{
void V(); .. V()
void V(int #); .. V(int)
void V(re- int #); .. V(re- int)
void V(out int #); .. V(out int) error
void V(int # int y); .. V(int int)
int V(string s); .. V(string)
int V(int #); .. V(int) error
void V(string45 a); .. V(string45)
void V(&arams string45 a); .. V(string45) error
!
.e debe tener en cuenta ?ue los modi0icadores de par(metros re- y out O[1".#.1R 0orman parte de una 0irma.
'or lo tanto, V(int) y V(re- int) son 0irmas Hnicas. .in embargo, V(re-int) y V(outint) no se pueden
declarar dentro de la misma inter0a1 por?ue sus 0irmas se di0erencian Hnicamente en re- y out. &simismo, el
tipo de valor devuelto y el modi0icador &arams no 0orman parte de una 0irma, por lo ?ue no es posible
sobrecargar bas(ndose exclusivamente en el tipo de valor devuelto o en la inclusi-n o exclusi-n del modi0icador
&arams. Como tales, las declaraciones de los m)todos V(int) y V(&arams string45) anteriormente
identi0icadas producen un error en tiempo de compilaci-n.
3.+ :mbitos
El 5/ito OscopeR de un nombre es la regi-n del texto del programa en la cual es posible re0erirse a la entidad
declarada por el nombre sin la cali0icaci-n de )ste. 8os (mbitos se pueden anidar y un (mbito interno puede
volver a declarar el signi0icado de un nombre de un (mbito exterior Osin embargo, de esta 0orma no se ?uita la
restricci-n impuesta por [3.3 de ?ue, dentro de un blo?ue anidado, no se puede declarar una variable local con el
mismo nombre de una variable local de un blo?ue contenedorR. En este caso, se dice ?ue el nombre del (mbito
e.terno est( oculto en la regi-n del texto del programa cubierta por el (mbito interno, y el acceso al nombre
externo s-lo es posible si se certi0ica el nombre.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. (1
Especificacin del lenguaje C#
El (mbito de un miembro de espacio de nombres declarado por una declaraci-n de miembro de espacio de
nombres Ona%espace-%e%-er-declarationR O[R sin declaraci-n envolvente de espacio de nombres
Ona%espace-declarationR es todo el texto del programa.
El (mbito de un miembro de espacio de nombres declarado mediante una declaraci-n de miembro de
espacio de nombres Ona%espace-%e%-er-declarationR, dentro de una declaraci-n de espacio de nombres
Ona%espace-declarationR cuyo nombre completo sea N, ser( el cuerpo de espacio de nombres Ona%espace-
-od#R de todas las declaraciones de espacio de nombres Ona%espace-declarationR cuyo nombre completo sea
N o empiece por N, seguido por un punto.
El (mbito de un nombre de0inido por una directiva de alias extern se extiende a trav)s de directivas using
Osin&-directivesR, atributos globales O&lo-al-attri-tesR y declaraciones de miembros de espacios de
nombres Ona%espace-%e%-er-declarationsR de la unidad de compilaci-n o del cuerpo de espacio de
nombres inmediato. 7na directiva de alias extern Oe2tern-alias-directiveR no contribuye con ningHn miembro
nuevo al espacio de declaraci-n subyacente. En otras palabras, una directiva de alias extern Oe2tern-alias-
directiveR no es transitiva, sino ?ue s-lo a0ecta a la unidad de compilaci-n o al cuerpo de espacio de
nombres en el ?ue se da.
El (mbito de un nombre de0inido o importado por una directiva using Osin&-directiveR O[+.4R se ampl5a a las
declaraciones de miembros de espacios de nombres Ona%espace-%e%-er-declarationsR de la unidad de
compilaci-n Oco%pilation-nitR o del cuerpo de espacio de nombres Ona%espace--od#R en ?ue tiene lugar la
directiva using Osin&-directiveR. 7na directiva using Osin&-directiveR puede o0recer cero o m(s espacios de
nombres o nombres de tipos disponibles dentro de una unidad de compilaci-n Oco%pilation-nitR o cuerpo
de espacio de nombres Ona%espace--od#R en particular, pero no aporta ningHn miembro nuevo al espacio
de declaraci-n subyacente. Es decir, una directiva using Osin&-directiveR no es transitiva, sino ?ue a0ecta
Hnicamente a la unidad de compilaci-n Oco%pilation-nitR o al cuerpo de espacio de nombres Ona%espace-
-od#R en ?ue tiene lugar.
El (mbito de un par(metro de tipo declarado por una lista de par(metros de tipo Ot#pe-para%eter-listR en una
declaraci-n de clase Oclass-declarationR O[R es la clase base Oclass--aseR, las cl(usulas de restricciones de
par(metros de tipo Ot#pe-para%eter-constraints-clasesR, y el cuerpo de clase Oclass--od#R de esa
declaraci-n de clase Oclass-declarationR.
El (mbito de un par(metro de tipo declarado por una lista de par(metros de tipo Ot#pe-para%eter-listR en una
declaraci-n de estructura Ostrc-declarationR O[R son las inter0aces de estructuras Ostrct-interfacesR, las
cl(usulas de restricciones de par(metros de tipo Ot#pe-para%eter-constraints-clasesR, y el cuerpo de
estructura Ostrct--od#R de esa declaraci-n de estructura Oclass-strctR.
El (mbito de un par(metro de tipo declarado por una lista de par(metros de tipo Ot#pe-para%eter-listR en una
declaraci-n de inter0a1 Ointerface-declarationR O[13.1R es la base de inter0a1 Ointerface--aseR, las cl(usulas
de restricciones de par(metros de tipo Ot#pe-para%eter-constraints-clasesR, y el cuerpo de inter0a1
Ointerface--od#R de esa declaraci-n de inter0a1 Ointerface-declarationR.
El (mbito de un par(metro de tipo declarado por una lista de par(metros de tipo Ot#pe-para%eter-listR en una
declaraci-n de delegado Odele&ate-declarationR O[1.1R es el tipo devuelto Oretrn-t#peR, la lista de
par(metros 0ormales Ofor%al-para%eter-listR, y las cl(usulas de restricciones de par(metros de tipo Ot#pe-
para%eter-constraints-clasesR de esa declaraci-n de delegado Odele&ate-declarationR.
El (mbito de un miembro declarado por una declaraci-n de miembro de clase Oclass-%e%-er-declarationR
O[1".1.#R es el cuerpo de clase Oclass--od#R en ?ue se produce la declaraci-n. &simismo, el (mbito de un
miembro de clase se ampl5a al cuerpo de clase Oclass--od#R de las clases derivadas ?ue est)n incluidas en
el dominio de accesibilidad O[3..2R del miembro.
El (mbito de un miembro declarado por una declaraci-n de miembro de estructura Ostrct-%e%-er-
declarationR O[11.2R es el cuerpo de estructura Ostrct--od#R en ?ue se produce la declaraci-n.
(2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
El (mbito de un miembro declarado por una declaraci-n de miembro de enumeraci-n Oen%-%e%-er-
declarationR O[14.3R es el cuerpo de enumeraci-n Oen%--od#R en el ?ue se produce la declaraci-n.
El (mbito de un par(metro declarado en una declaraci-n de m)todo O%ethod-declarationR O[1".#R es el
cuerpo del m)todo O%ethod--od#R de dic=a declaraci-n de m)todo O%ethod-declarationR.
El (mbito de un par(metro declarado en una declaraci-n de indi1ador Oinde2er-declarationR O[1".+R son las
declaraciones de descriptor de acceso Oaccessor-declarationsR de dic=a declaraci-n de indi1ador Oinde2er-
declarationR.
El (mbito de un par(metro declarado en una declaraci-n de operador Ooperator-declarationR O[1".1"R es el
blo?ue O-loc3R de dic=a declaraci-n de operador Ooperator-declarationR.
El (mbito de un par(metro declarado en una declaraci-n de constructor Oconstrctor-declarationR O[1".11R
es el iniciali1ador de constructor Oconstrctor-initiali0erR y el blo?ue O-loc3R de dic=a declaraci-n de
constructor Oconstrctor-declarationR.
El (mbito de un par(metro declarado en una expresi-n de lambda la%-da-e2pression O[R es el cuerpo de
expresi-n de lambda Ola%-da-e2pression--od#R de dic=a expresi-n de lambda Ola%-da-e2pressionR.
El (mbito de un par(metro declarado en una expresi-n de m)todo an-nimo anon#%os-%ethod-e2pression
O[R es el blo?ue O-loc3R de dic=a expresi-n de m)todo an-nimo Oanon#%os-%ethod-e2pressionR.
El (mbito de una eti?ueta declarada en una instrucci-n con eti?ueta Ola-eled-state%entR O[8.4R es el blo?ue
O-loc3R en ?ue se produce la declaraci-n.
El (mbito de una variable local declarada en una declaraci-n de variable local Olocal-varia-le-declarationR
O[R es el blo?ue donde se produce la declaraci-n.
El (mbito de una variable local declarada en un blo?ue s9itc= Oswitch--loc3R de una instrucci-n s,itc"
O[8.*.2R es el blo?ue s9itc= Oswitch--loc3R.
El (mbito de una variable local declarada en un iniciali1ador 0or Ofor-initiali0erR de una instrucci-n -or
O[8.8.3R es el iniciali1ador 0or Ofor-initiali0erR, la condici-n 0or Ofor-conditionR, el iterador 0or Ofor-iteratorR y
la instrucci-n Ostate%entR contenida de la instrucci-n -or.
El (mbito de una constante local declarada en una declaraci-n de constante local Olocal-constant-
declarationR O[R es el blo?ue donde se produce la declaraci-n. Es un error en tiempo de compilaci-n =acer
re0erencia a una constante local en una posici-n textual ?ue precede a su declarador de constante Oconstant-
declaratorR.
El (mbito de una variable declarada como parte de una instrucci-n 0oreac= Oforeach-state%entR, instrucci-n
using Osin&-state%entR, instrucci-n loc6 Oloc3-state%entR o expresi-n de consulta O6er#-e2pressionR est(
determinado por la expansi-n de la construcci-n determinada.
2entro del (mbito de un miembro de espacio de nombres, clase, estructura o enumeraci-n es posible =acer
re0erencia al miembro en una posici-n textual ?ue precede a la declaraci-n del miembro. 'or e$emploG
class '
{
void V() {
i + 2;
!
int i + 3;
!
'or lo tanto, es v(lido ?ue V =aga re0erencia a i antes de su declaraci-n.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. (3
Especificacin del lenguaje C#
En el (mbito de una variable local, es un error en tiempo de compilaci-n =acer re0erencia a la variable local en
una posici-n textual ?ue preceda al declarador de la variable local Olocal-varia-le-declaratorR. 'or e$emploG
class '
{
int i + 3;
void V() {
i + 2; .. )rror use &recedes declaration
int i;
i + 8;
!
void S() {
int j + (j + 2); .. Ualid
!
void H() {
int a + 2 b + <<a; .. Ualid
!
!
En el m)todo V anterior, la primera asignaci-n de i no =ace ninguna re0erencia concreta al campo declarado en
el (mbito externo. En lugar de ello, =ace re0erencia a la variable local, con lo ?ue se produce un error durante la
compilaci-n, por?ue precede textualmente a la declaraci-n de la variable. En el m)todo S, el uso de j en el
iniciali1ador de la declaraci-n de j es v(lido por?ue no precede al declarador de variable local Olocal-varia-le-
declaratorR. En el m)todo H, un declarador de variable local Olocal-varia-le-declaratorR posterior =ace
re0erencia correctamente a una variable local declarada en un declarador de variable local Olocal-varia-le-
declaratorR anterior con la misma declaraci-n de variable local Olocal-varia-le-declarationR.
8as reglas ?ue rigen el (mbito de las variables locales pretenden garanti1ar ?ue el signi0icado de un nombre
utili1ado en el contexto de una expresi-n no var5e dentro de un blo?ue. .i el (mbito de una variable local s-lo se
extiende desde su declaraci-n =asta el 0inal del blo?ue, entonces, en el e$emplo anterior, la primera asignaci-n
asignar( a la variable de instancia y la segunda a la variable local, lo ?ue posiblemente producir( errores en
tiempo de compilaci-n si m(s adelante 0uera necesario reorgani1ar las instrucciones del blo?ue.
El signi0icado de un nombre contenido en un blo?ue puede di0erir segHn el contexto en ?ue se utilice el nombre.
En el e$emplo
using System;
class ' {!
class 1est
{
static void Main() {
string ' + ""ello ,orld";
string s + '; .. e#&ression conte#t
1y&e t + ty&eo-('); .. ty&e conte#t
Console.WriteLine(s); .. ,rites ""ello ,orld"
Console.WriteLine(t); .. ,rites "'"
!
!
el nombre ' se utili1a en el contexto de una expresi-n para =acer re0erencia a la variable local ' y en un
contexto de tipo para =acer re0erencia a la clase '.
3.+.1 ,cultar nombres
El (mbito de una entidad =abitualmente abarca m(s texto del programa ?ue el espacio de declaraci-n de la
entidad. En concreto, el (mbito de una entidad puede incluir declaraciones ?ue introducen nuevos espacios de
(# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
declaraci-n ?ue contienen entidades con el mismo nombre. 8as declaraciones de este tipo =acen ?ue la entidad
original ?uede oculta OhiddenR. & la inversa, se dice ?ue una entidad es visi/le cuando no est( oculta.
8a ocultaci-n de nombres se produce cuando los (mbitos se superponen a causa del anidamiento y cuando se
superponen por =erencia. 8as caracter5sticas de los dos tipos de ocultaci-n se explican en las pr-ximas
secciones.
3.#.1.1 'cultar mediante anidacin
8a ocultaci-n de nombres por medio del anidamiento puede ser el resultado del anidamiento de espacios de
nombres o tipos contenidos en espacios de nombres, la consecuencia del anidamiento de tipos dentro de clases o
estructuras y el resultado de las declaraciones de par(metros y variables locales.
En el e$emplo
class '
{
int i + 3;
void V() {
int i + 2;
!
void S() {
i + 2;
!
!
dentro del m)todo V, la variable de instancia i ?ueda oculta por la variable local i, pero dentro del m)todo S, i
se sigue re0iriendo a la variable de instancia.
Cuando un nombre en un (mbito interno oculte otro nombre en el (mbito externo, ocultar( tambi)n todas sus
apariciones sobrecargadas. En el e$emplo
class %uter
{
static void V(int i) {!
static void V(string s) {!
class $nner
{
void S() {
V(2); .. $nvo(es %uter.$nner.V
V("Hello"); .. )rror
!
static void V(long l) {!
!
!
la llamada V(2) invoca la V declarada en $nner por?ue la declaraci-n interna oculta todas las apariciones
externas de V. 'or el mismo motivo, la llamada V("Hello") produce un error en tiempo de compilaci-n.
3.#.1.2 'cultar mediante -erencia
8a ocultaci-n de nombres por medio de la =erencia ocurre cuando clases o estructuras vuelven a declarar
nombres ?ue se =an =eredado de clases base. Este tipo de ocultaci-n de nombres toma una de las siguientes
0ormasG
7na constante, campo, propiedad, evento o tipo introducido en una clase o estructura ?ue oculta todos los
miembros de la clase base con el mismo nombre.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. (!
Especificacin del lenguaje C#
7n m)todo introducido en una clase o estructura ?ue oculta todos los miembros de clase base no de m)todo
con el mismo nombre, y todos los m)todos de clase base con la misma 0irma Onombre de m)todo y nHmero
de par(metros, modi0icadores y tiposR.
!ndi1ador introducido en una clase o estructura ?ue oculta todos los indi1adores de la clase base con la
misma 0irma OnHmero de par(metros y tiposR.
8as reglas ?ue gobiernan las declaraciones de operador O[1".1"R imposibilitan la declaraci-n por una clase
derivada de un operador con la misma 0irma ?ue un operador de una clase base. 'or lo tanto, los operadores
nunca se ocultan mutuamente.
&l contrario ?ue cuando se oculta un nombre de un (mbito externo, cuando se oculta un nombre accesible desde
un (mbito =eredado se genera una advertencia. En el e$emplo
class :ase
{
&ublic void V() {!
!
class 6erived/ :ase
{
&ublic void V() {! .. Warning "iding an in"erited name
!
la declaraci-n de V en 6erived genera una advertencia. /cultar un nombre =eredado no es espec50icamente un
error, puesto ?ue esto impedir5a la evoluci-n independiente de las clases base. 'or e$emplo, la situaci-n anterior
podr5a =aberse producido por?ue una versi-n posterior de :ase introdu$o un m)todo V ?ue no estaba presente
en una versi-n anterior de la clase. .i la situaci-n anterior =ubiera sido un error, cal6ier cambio reali1ado a
una clase base en una versi-n independiente de la biblioteca de clases podr5a =aber invalidado las clases
derivadas.
8a advertencia causada por la ocultaci-n de un nombre =eredado puede eliminarse mediante uso del
modi0icador ne,G
class :ase
{
&ublic void V() {!
!
class 6erived/ :ase
{
ne, &ublic void V() {!
!
El modi0icador ne, indica ?ue V de 6erived es PnuevoQ, y ?ue su prop-sito real es ocultar el miembro
=eredado.
7na declaraci-n de un miembro nuevo oculta un miembro =eredado s-lo dentro del (mbito del nuevo miembro.
class :ase
{
&ublic static void V() {!
!
class 6erived/ :ase
{
ne, &rivate static void V() {! .. Hides :ase.V in 6erived only
!
class More6erived/ 6erived
{
static void S() { V(); ! .. $nvo(es :ase.V
!
(6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En el e$emplo anterior, la declaraci-n de m)todo V en la clase 6erived oculta el m)todo V ?ue se =ered- de
:ase, pero, como el nuevo m)todo V de 6erived tiene acceso de tipo privado, su (mbito no se extiende a
More6erived. 2e este modo, la llamada V() de More6erived.S es v(lida e invocar( a :ase.V.
3.- Espacios de nombres y nombres de tipos
&lgunos contextos de un programa de C# re?uieren ?ue se especi0i?ue un nombre de espacio de nombres
Ona%espace-na%eR o un nombre de tipo Ot#pe-na%eR.
na%espace-na%e1
na%espace-or-t#pe-na%e
t#pe-na%e1
na%espace-or-t#pe-na%e
na%espace-or-t#pe-na%e1
identifier t#pe-ar&%ent-list
opt
na%espace-or-t#pe-na%e . identifier t#pe-ar&%ent-list
op
6alified-alias-%e%-er
7n nombre de espacio de nombres Ona%espace-na%eR es un nombre de espacio de nombres o de tipo
Ona%espace-or-t#pe-na%eR ?ue =ace re0erencia a un espacio de nombres. Con0orme a la resoluci-n explicada
m(s adelante, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR de un nombre de espacio
de nombres Ona%espace-na%eR debe =acer re0erencia a un espacio de nombres o, de lo contrario, se producir( un
error en tiempo de compilaci-n. 4o puede =aber argumentos de tipo O[4.4.1R en un nombre de espacio de
nombres Ona%espace-na%eRV s-lo los tipos pueden tener argumentos de tipo.
7n nombre de tipo Ot#pe-na%eR es un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR ?ue
=ace re0erencia a un tipo. Con0orme a la resoluci-n explicada m(s adelante, el nombre de espacio de nombres o
de tipo Ona%espace-or-t#pe-na%eR de un nombre de tipo Ot#pe-na%eR debe =acer re0erencia a un tipo o, de lo
contrario, se producir( un error en tiempo de compilaci-n.
.i el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR es un miembro de alias completo su
signi0icado es como se describe en [. En caso contrario, un nombre de espacio de nombres o de tipo
Ona%espace-or-t#pe-na%eR adopta una de las cuatro estructuras siguientesG
$
$D'2 ... 'aE
N.$
N.$D'2 ... 'aE
donde $ es un solo identi0icador, N es un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR y
D'2 ... 'aE es una lista de argumentos de tipo Ot#pe-ar&%ent-listR. .i no se especi0ica ninguna lista de
argumentos de tipo Ot#pe-ar&%ent-listR, se considera ?ue a es cero.
El signi0icado de un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR se determina como
sigueG
.i el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR tiene la estructura $ o
$D'2 ... 'aEG
o .i a es cero y el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR aparece dentro de
una declaraci-n de m)todo gen)rico O[1".#R y si dic=a declaraci-n incluye un par(metro de tipo
O[1".1.3R con el nombre $, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace
re0erencia a dic=o par(metro de tipo.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. ((
Especificacin del lenguaje C#
o 2e lo contrario, si el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR aparece dentro
de una declaraci-n de tipo, para cada tipo de instancia 1O[1".3.1R, empe1ando por el tipo de instancia de
dic=a declaraci-n tipo y continuando con el tipo de instancia para cada clase envolvente o declaraci-n
de estructura Osi las =ubieraRG
.i a es cero y la declaraci-n de 1 incluye un par(metro de tipo con el nombre $, el nombre de
espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace re0erencia a dic=o par(metro de tipo.
2e lo contrario, si el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR aparece
dentro del cuerpo de a declaraci-n de tipo y 1 o alguno de sus tipos base contiene un tipo accesible
anidado con el nombre $ y par(metros de tipo a, el nombre de espacio de nombres o de tipo
Ona%espace-or-t#pe-na%eR =ace re0erencia a dic=o tipo construido con los argumentos de tipo
dados. .i =ay m(s de uno de esos tipos, se selecciona el tipo declarado dentro del tipo m(s derivado.
Tenga en cuenta ?ue los miembros ?ue no son de tipo Oconstantes, campos, m)todos, propiedades,
indi1adores, operadores, constructores de instancia, destructores y constructores est(ticosR y
miembros de tipo con un nHmero di0erente de par(metros de tipo se omiten a la =ora de determinar
el signi0icado de un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR.
o .i los pasos anteriores no produ$eron resultados satis0actorios, para cada espacio de nombres N,
empe1ando por el espacio de nombres en el ?ue se produce el nombre de espacio de nombres o de tipo
Ona%espace-or-t#pe-na%eR, continuando por cada uno de los espacios de nombres envolventes Osi los
=ubieraR y terminando por el espacio de nombres global, se ir(n evaluando los siguientes pasos =asta
?ue se localice una entidadG
.i a es cero e $ es el nombre de un espacio de nombres en NG
o .i la ubicaci-n donde tiene lugar el nombre de espacio de nombres o de tipo Ona%espace-or-
t#pe-na%eR tiene una declaraci-n de espacio de nombres para N y la declaraci-n de espacio de
nombres contiene una directiva de alias extern Oe2tern-alias-directiveR o una directiva de alias
using Osin&-alias-directiveR ?ue asocia el nombre $ con un nombre de espacio de nombres o de
tipo, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR es ambiguo y se
genera un error en tiempo de compilaci-n.
o 2e lo contrario, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace
re0erencia al espacio de nombres denominado $ en N.
2e lo contrario, si N contiene un tipo accesible con un nombre $ y par(metros de tipo aG
o .i a es cero y la ubicaci-n donde tiene lugar el nombre de espacio de nombres o de tipo
Ona%espace-or-t#pe-na%eR tiene una declaraci-n de espacio de nombres para N y la declaraci-n
de espacio de nombres contiene una directiva de alias extern Oe2tern-alias-directiveR o una
directiva de alias using Osin&-alias-directiveR ?ue asocia el nombre con un nombre de espacio
de nombres o de tipo, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR es
ambiguo y se genera un error en tiempo de compilaci-n.
o 2e lo contrario, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace
re0erencia al tipo construido con los argumentos de tipo dados.
2e lo contrario, si la ubicaci-n donde tiene lugar el nombre de espacio de nombres o de tipo
Ona%espace-or-t#pe-na%eR tiene una declaraci-n de espacio de nombres para NG
o .i a es cero y la declaraci-n de espacio de nombres contiene una directiva de alias extern
Oe2tern-alias-directiveR o una directiva de alias using Osin&-alias-directiveR ?ue asocia el
nombre $ a un espacio de nombres o tipo importado, entonces el nombre de espacio de nombres
o de tipo Ona%espace-or-t#pe-na%eR =ace re0erencia a dic=o espacio de nombres o tipo.
($ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
o 2e lo contrario, si los espacios de nombres importados por las directivas using de espacio de
nombres Osin&-na%espace-directivesR de la declaraci-n del espacio de nombres contienen
exactamente un Hnico tipo con el nombre $ y par(metros de tipo a, entonces el nombre de
espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace re0erencia al tipo construido con
los argumentos de tipo dados.
o 2e lo contrario, si los espacios de nombres importados por las directivas using de espacio de
nombres Osin&-na%espace-directivesR de la declaraci-n del espacio de nombres contienen m(s
de un tipo con el nombre $ y par(metros de tipo a, entonces el nombre de espacio de nombres o
de tipo Ona%espace-or-t#pe-na%eR ser( ambiguo y se producir( un error.
o 2e lo contrario, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR no est( de0inido
y se produce un error en tiempo de compilaci-n.
2e lo contrario, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR tiene la estructura
N.$ o N.$D'2 ... 'aE. .e resuelve primero N como nombre de espacio de nombres o de tipo Ona%espace-
or-t#pe-na%eR. .i la resoluci-n de N no es correcta, se produce un error en tiempo de compilaci-n. 2e lo
contrario, N.$ o N.$D'2 ... 'aE se resuelve de la siguiente maneraG
o .i a es cero y N =ace re0erencia a un espacio de nombres y N contiene un espacio de nombres anidado
con el nombre $, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace re0erencia
a dic=o espacio de nombres anidado.
o 2e lo contrario, si N contiene un espacio de nombres y N contiene un tipo accesible con el nombre $ y
par(metros de tipo a, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace
re0erencia a dic=o tipo construido con los argumentos de tipo dados.
o 2e lo contrario, si N =ace re0erencia a una clase Oposiblemente construidaR o a un tipo struct y N o
algunas de sus clases base contiene un tipo accesible anidado con el nombre $ y par(metros de tipo a, el
nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace re0erencia a dic=o tipo
construido con los argumentos de tipo dados. .i =ay m(s de uno de esos tipos, se selecciona el tipo
declarado dentro del tipo m(s derivado. Tenga en cuenta ?ue si el signi0icado de N.$ se determina como
parte de la resoluci-n de la especi0icaci-n de la clase base de N, la clase base directa de N se considera
ob$ect O[R.
o 2e lo contrario, N.$ es un nombre de espacio de nombres o de tipo no v(lido Oinvalid na%espace-or-
t#pe-na%eR y se produce un error en tiempo de compilaci-n.
.e permite ?ue un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR O[1".1.1.3R =aga
re0erencia a una clase est(tica s-lo si
El nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR es 1 en un nombre de espacio de
nombres o de tipo Ona%espace-or-t#pe-na%eR con la estructura 1.$, o bien
El nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR es 1 en una expresi-n typeo0
Ot#peof-e2pressionR O[*..11R con la estructura ty&eo-(1).
3.-.1 1ombres completos
Todos los espacios de nombres y todos los tipos tienen un no/re copleto, ?ue los identi0ica de 0orma
exclusiva. El nombre completo de un espacio de nombres o un tipo N se determina como sigueG
.i N es un miembro del espacio de nombres global, su nombre completo es N.
2e lo contrario, su nombre completo es S.N, donde S es el nombre completo del espacio de nombres o el
tipo donde N est( declarado.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. ("
Especificacin del lenguaje C#
Esto es, el nombre completo de N es la ruta de acceso $er(r?uica completa de los identi0icadores ?ue conducen a
N, empe1ando desde el espacio de nombres global. 2ado ?ue todos los miembros de un espacio de nombres o un
tipo deben tener un nombre Hnico, se deduce ?ue el nombre completo de un espacio de nombres o tipo siempre
es Hnico.
En el e$emplo siguiente se muestran varias declaraciones de espacio de nombres y tipo con sus nombres
completos asociados.
class ' {! .. '
names&ace I .. I
{
class : .. I.:
{
class C {! .. I.:.C
!
names&ace ` .. I.`
{
class 6 {! .. I.`.6
!
!
names&ace I.` .. I.`
{
class ) {! .. I.`.)
!
3.. 'dministracin autom)tica de la memoria
C# usa la administraci-n autom(tica de memoria, ?ue exime a los programadores de la asignaci-n manual y la
liberaci-n de la memoria ocupada por ob$etos. 8as directivas de administraci-n autom(tica de la memoria se
implementan mediante un recolector de eleentos no !tili-ados. El ciclo de vida de la administraci-n de la
memoria de un ob$eto esG
1. Cuando se crea el ob$eto, se le asigna memoria, se e$ecuta el constructor y el ob$eto se considera
activo.
2. En caso de ?ue no se pueda obtener acceso al ob$eto o alguna de sus partes por medio de las
posibles continuaciones de la e$ecuci-n, en lugar de iniciar los destructores, el ob$eto de$ar( de considerarse
en uso y ?uedar( expuesto al proceso de destrucci-n. El compilador de C# y el recolector de elementos no
utili1ados pueden optar por anali1ar el c-digo para determinar ?u) re0erencias a un ob$eto podr(n utili1arse
en el 0uturo. 'or e$emplo, si una variable local ?ue se encuentra dentro del (mbito es la Hnica re0erencia
existente a un ob$eto, pero no se =ace ninguna re0erencia a tal variable local en ninguna continuaci-n posible
de la e$ecuci-n desde el punto actual de e$ecuci-n dentro del procedimiento, el recolector de elementos no
utili1ados puede tratar los ob$etos Oaun?ue no necesariamenteR como si ya no estuvieran en uso.
3. Cuando el ob$eto ya es candidato a la destrucci-n, el destructor del ob$eto Osi existeR se e$ecuta en un
momento posterior no especi0icado O[1".13R. .alvo ?ue sea invalidado por llamadas expl5citas, el destructor
del ob$eto s-lo se e$ecutar( una ve1.
4. .i, una ve1 e$ecutado el destructor de un ob$eto, las posibles continuaciones de la e$ecuci-n
Oincluida la e$ecuci-n de los destructoresR no pudieran obtener acceso al ob$eto o a alguna de sus partes, se
considerar( ?ue ya no se encuentra accesible y ?uedar( expuesto al proceso de recolecci-n.
. 'or Hltimo, cuando el ob$eto ya es candidato para la recolecci-n, en un momento posterior, el
recolector de elementos no utili1ados libera la memoria asociada al ob$eto.
El recolector de elementos no utili1ados mantiene in0ormaci-n acerca de la utili1aci-n de ob$etos y la utili1a
para tomar decisiones sobre la administraci-n de memoria. 'or e$emplo, contiene datos como en ?u) parte de la
$' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
memoria se ubica un ob$eto reci)n creado, cu(ndo se reubica un ob$eto y cu(ndo un ob$eto ya no se utili1a o est(
inaccesible.
!gual ?ue otros lengua$es ?ue dan por supuesta la existencia de un recolector de elementos no utili1ados, C# se
=a diseUado para ?ue el recolector de elementos no utili1ados pueda implementar una amplia gama de directivas
de administraci-n de la memoria. 'or e$emplo, C# no exige ?ue se lleve a cabo la e$ecuci-n de destructores ni la
recolecci-n de ob$etos en el momento en ?ue pasen a ser candidatos a ella, ni ?ue los destructores se e$ecuten en
un orden concreto o en un subproceso concreto.
El comportamiento del recolector de elementos no utili1ados puede controlarse, en cierta medida, mediante
m)todos est(ticos de la clase System.SC, una clase ?ue puede utili1arse para solicitar la e$ecuci-n de la
recolecci-n o de los destructores Oo su no e$ecuci-nR, etc.
2ado ?ue el recolector de elementos no utili1ados tiene una amplia libertad para decidir cu(ndo debe recolectar
ob$etos y e$ecutar destructores, una implementaci-n compatible puede producir resultados di0erentes de los
mostrados en el c-digo siguiente. El programa
using System;
class '
{
A'() {
Console.WriteLine("6estruct instance o- '");
!
!
class :
{
object Oe-;
&ublic :(object o) {
Oe- + o;
!
A:() {
Console.WriteLine("6estruct instance o- :");
!
!
class 1est
{
static void Main() {
: b + ne, :(ne, '());
b + null;
SC.Collect();
SC.WaitVor*endingVinali?ers();
!
!
crea una instancia de la clase ' y otra de la clase :. Estos ob$etos se convierten en candidatos a la recolecci-n de
elementos no utili1ados cuando se asigna a la variable b el valor null, puesto ?ue, despu)s de ello, no se puede
obtener acceso a ellos mediante ningHn c-digo escrito por el usuario. El resultado podr5a ser
6estruct instance o- '
6estruct instance o- :
o
6estruct instance o- :
6estruct instance o- '
puesto ?ue el lengua$e no impone restricciones al orden en ?ue se lleva a cabo la recolecci-n de elementos de los
ob$etos no utili1ados.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. $1
Especificacin del lenguaje C#
En casos concretos, la distinci-n entre Pcandidato a la destrucci-nQ y Pcandidato a la recolecci-nQ puede ser
importante. 'or e$emplo,
using System;
class '
{
A'() {
Console.WriteLine("6estruct instance o- '");
!
&ublic void V() {
Console.WriteLine("'.V");
1est.Oe-' + t"is;
!
!
class :
{
&ublic ' Oe-;
A:() {
Console.WriteLine("6estruct instance o- :");
Oe-.V();
!
!
class 1est
{
&ublic static ' Oe-';
&ublic static : Oe-:;
static void Main() {
Oe-: + ne, :();
Oe-' + ne, '();
Oe-:.Oe- + Oe-';
Oe-: + null;
Oe-' + null;
.. ' and : no, eligible -or destruction
SC.Collect();
SC.WaitVor*endingVinali?ers();
.. : no, eligible -or collection but ' is not
i- (Oe-' @+ null)
Console.WriteLine("Oe-' is not null");
!
!
En el programa anterior, si el recolector de elementos no utili1ados decide e$ecutar el destructor de ' antes ?ue
el de :, el resultado de este programa puede serG
6estruct instance o- '
6estruct instance o- :
'.V
Oe-' is not null
2ebe tenerse en cuenta ?ue, aun?ue la instancia de ' no estaba en uso cuando se e$ecut- el destructor de ',
todav5a es posible llamar a los m)todos de ' Oen este caso, VR desde otro destructor. &simismo, no debe
olvidarse ?ue la e$ecuci-n de un destructor puede =acer ?ue un ob$eto vuelva a ser utili1able desde el programa
principal. En este caso, la e$ecuci-n del destructor de : =ace ?ue una instancia de ' ?ue no estaba anteriormente
en uso est) a=ora accesible desde la re0erencia activa 1est.Oe-'. Tras la llamada a
WaitVor*endingVinali?ers, la instancia de : pasa a ?uedar expuesta a la recolecci-n, pero no as5 la
instancia de ', debido a la re0erencia 1est.Oe-'.
$2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
'ara evitar con0usiones y comportamientos inesperados, generalmente es recomendable ?ue los destructores
solamente realicen la limpie1a de los datos almacenados en los campos propios de sus ob$etos, y ?ue no realicen
acciones en los ob$etos a los ?ue se =ace re0erencia o en campos est(ticos.
7na alternativa al uso de destructores consiste en permitir ?ue una clase implemente la inter0a1
System.$6is&osable. &s5 se permite al cliente del ob$eto determinar cu(ndo liberar los recursos del ob$eto,
normalmente mediante el acceso al ob$eto como recurso en una instrucci-n using O[8.13R.
3.10 ,rden de ejecucin
8a e$ecuci-n de los programas de C# se reali1a de tal modo ?ue los e0ectos secundarios de cada subproceso en
e$ecuci-n se van conservando en puntos cr5ticos de e$ecuci-n. 7n efecto sec!ndario se de0ine como la lectura o
escritura de un campo vol(til, la escritura en una variable no vol(til, la escritura en un recurso externo o el inicio
de una excepci-n. 8os puntos de e$ecuci-n cr5ticos en los ?ue deben conservarse tales e0ectos secundarios son
las re0erencias a campos vol(tiles O[1"..3R, las instrucciones de blo?ueo Oloc(R O[8.12R y la creaci-n y
terminaci-n de subprocesos. El entorno de e$ecuci-n puede cambiar el orden de e$ecuci-n de un programa de
C#, con las siguientes restriccionesG
.e conservar( la dependencia de datos dentro de un subproceso de e$ecuci-n. Es decir, el valor de cada
variable se calcular( como si todas las instrucciones del subproceso se e$ecutaran en el orden del programa
original.
.e conservan las reglas de orden de iniciali1aci-n O[1"..4 y [1"..R.
.e conserva el orden de los e0ectos secundarios respecto a las lecturas y escrituras vol(tiles O[1"..3R.
&dem(s, el entorno de e$ecuci-n no necesitar( evaluar parte de una expresi-n si puede deducir ?ue el valor
de esa expresi-n no se utili1a y ?ue no se producen e0ectos secundarios necesarios Oincluidos los causados
por la llamada a un m)todo o el acceso a un campo vol(tilR. Cuando un evento asincr-nico Otal como una
excepci-n iniciada por otro subprocesoR interrumpe la e$ecuci-n de un programa, no =abr( garant5as de ?ue
los e0ectos secundarios observables resulten visibles en el orden del programa original.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. $3
Especificacin del lenguaje C#
!. Tipos
8os tipos del lengua$e C# se dividen en dos categor5as principalesG tipos de valor y tipos de referencia. &mbos,
los tipos de valor y los tipos de re0erencia, pueden ser tipos gen6ricos, ?ue adoptan uno o m(s par(metros de
tipo. 8os par(metros de tipo pueden designar tanto a tipos de valor como a tipos de re0erencia.
t#pe1
vale-t#pe
reference-t#pe
t#pe-para%eter
7na tercera categor5a de tipos, los punteros, s-lo est( disponible en el c-digo no seguro. Esta categor5a se
explica con m(s detalle en la secci-n [18.2.
8os tipos de valor se di0erencian de los tipos de re0erencia en ?ue sus variables contienen directamente sus
datos, mientras ?ue las variables de los tipos de re0erencia contienen referencias a sus datos, ?ue se conocen
como o/1etos. En el caso de los tipos de re0erencia, es posible ?ue dos variables =agan re0erencia al mismo
ob$eto y, por tanto, ?ue las operaciones en una variable a0ecten al ob$eto al ?ue =ace re0erencia la otra variable.
En el caso de los tipos de valor, cada variable tiene su propia copia de los datos, de manera ?ue no es posible
?ue las operaciones de una a0ecten a la otra.
El sistema de tipos de C# est( uni0icado, de manera ?ue n valor de cal6ier tipo pede tratarse co%o n
o->eto. Todos los tipos de C# se derivan directa o indirectamente del tipo de clase object, ?ue es la clase base
de0initiva de todos los tipos. 8os valores de los tipos de re0erencia se tratan como ob$etos consider(ndolos
sencillamente como del tipo object. 8os valores de los tipos de valor se tratan como ob$etos mediante la
reali1aci-n de operaciones de conversi-n boxing y unboxing O[4.3R.
!.1 Tipos de alor
7n tipo de valor es un tipo struct o un tipo enum. C# proporciona un con$unto de tipos struct prede0inidos
denominados tipos siples. 8os tipos simples se identi0ican mediante palabras reservadas.
vale-t#pe1
strct-t#pe
en%-t#pe
strct-t#pe1
t#pe-na%e
si%ple-t#pe
nlla-le-t#pe
si%ple-t#pe1
n%eric-t#pe
bool
n%eric-t#pe1
inte&ral-t#pe
floatin&-point-t#pe
decimal
$# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
inte&ral-t#pe1
sbyte
byte
s"ort
us"ort
int
uint
long
ulong
c"ar
floatin&-point-t#pe1
-loat
double
nlla-le-t#pe1
non-nlla-le-vale-t#pe 7
non-nlla-le-vale-t#pe1
t#pe
en%-t#pe1
t#pe-na%e
& di0erencia de las variables de un tipo de re0erencia, las variables de los tipos de valor pueden contener el valor
null s-lo si el tipo de valor acepta valores 4788. 'ara cada tipo de valor ?ue no acepta valores 4788 =ay un
tipo de valor correspondiente ?ue s5 acepta valores 4788 y ?ue denota el mismo con$unto de valores m(s el
valor null.
8a asignaci-n a una variable de un tipo de valor crea una copia del valor ?ue se asigna, lo cual di0iere de la
asignaci-n a una variable de un tipo de re0erencia, ?ue copia la re0erencia, pero no el ob$eto identi0icado
por ella.
!.1.1 Tipo 4ystem.ValueType
Todos los tipos de valor se =eredan impl5citamente de la clase System.Ualue1y&e, ?ue, a su ve1, se =ereda de
la clase object. 4o es posible ?ue cual?uier tipo se derive de un tipo de valor y, por lo tanto, los tipos de valor
son impl5citamente tipos sealed O[1".1.1.2R.
/bserve ?ue System.Ualue1y&e no es en s5 ningHn tipo de valor Ovale-t#peR. %(s bien, es un tipo de clase
Oclass-t#peR del ?ue se derivan autom(ticamente todos los tipos de valores Ovale-t#pesR.
!.1.2 %onstructores predeterminados
Todos los tipos de valor declaran impl5citamente un constructor de instancia pHblico sin par(metros denominado
constr!ctor predeterinado. El constructor predeterminado devuelve una instancia iniciali1ada en cero
conocida como el valor predeterinado del tipo de valorG
'ara todos los tipos simples Osi%ple-t#pesR, el valor predeterminado es el generado por un modelo de bits de
todo cerosG
o 'ara sbyte, byte, s"ort, us"ort, int, uint, long y ulong, el valor predeterminado es 3.
o 'ara c"ar, el valor predeterminado es WZ#3333W.
o 'ara -loat, el valor predeterminado es 3.3-.
o 'ara double, el valor predeterminado es 3.3d.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. $!
Especificacin del lenguaje C#
o 'ara decimal, el valor predeterminado es 3.3m.
o 'ara bool, el valor predeterminado es -alse.
'ara un tipo enum Oen%-t#peR ) el valor predeterminado es 3, convertido en el tipo ).
'ara un tipo struct Ostrct-t#peR, el valor predeterminado es el ?ue se genera al con0igurar todos los campos
de tipos de valores en su valor predeterminado y todos los tipos de re0erencia en null.
'ara un tipo ?ue acepta valores 4788 Onlla-le-t#peR el valor predeterminado es una instancia para la ?ue
propiedad HasUalue es 0alsa y la propiedad Ualue no est( de0inida. El valor predeterminado tambi)n se
conoce como el valor 2300 del tipo ?ue acepta valores 4788.
!gual ?ue con cual?uier otro constructor de instancia, se llama al constructor predeterminado de un tipo de valor
mediante el operador ne,. 'or ra1ones de e0icacia, el ob$etivo de este re?uisito no es lograr ?ue la
implementaci-n genere una llamada de constructor. En el e$emplo siguiente, las dos variables i y j se
iniciali1an en cero.
class '
{
void V() {
int i + 3;
int j + ne, int();
!
!
2ado ?ue todos los tipos de valor impl5citamente tienen un constructor de instancias pHblico sin par(metros, un
tipo struct no puede contener una declaraci-n expl5cita de un constructor sin par(metros. 4o obstante, en un tipo
struct se pueden declarar constructores de instancia con par(metros O[11.3.8R.
!.1.3 Tipos de estructura
7n tipo struct es un tipo de valor ?ue puede declarar constantes, campos, m)todos, propiedades, indi1adores,
operadores, constructores de instancia, constructores est(ticos y tipos anidados. 8a declaraci-n de los tipos
struct se describe en [11.1.
!.1.! Tipos simples
C# proporciona un con$unto de tipos struct prede0inidos denominados tipos siples. 8os tipos simples se
identi0ican mediante palabras reservadas, pero )stas son sencillamente alias de tipos struct prede0inidos del
espacio de nombres System, como se explica en la tabla siguiente.
$6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
2alabra reser%ada Tipo con alias
sbyte System.S:yte
byte System.:yte
s"ort System.$nt2X
us"ort System.;$nt2X
int System.$nt98
uint System.;$nt98
long System.$ntXJ
ulong System.;$ntXJ
c"ar System.C"ar
-loat System.Single
double System.6ouble
bool System.:oolean
decimal System.6ecimal
Como un tipo simple e?uivale a un tipo struct, todos los tipos simples tienen miembros. 'or e$emplo, int tiene
los miembros declarados en System.$nt98 y los miembros =eredados de System.%bject, y se permiten las
siguientes instruccionesG
int i + int.Ma#Ualue; .. System.$nt98.Ma#Ualue constant
string s + i.1oString(); .. System.$nt98.1oString() instance met"od
string t + 289.1oString(); .. System.$nt98.1oString() instance met"od
8os tipos simples se di0erencian de otros tipos struct en ?ue permiten determinadas operaciones adicionalesG
8a mayor5a de los tipos simples permiten la creaci-n de valores mediante la escritura de literales O[2.4.4R.
'or e$emplo, 289 es un literal del tipo int y WaW es un literal del tipo c"ar. C# no proporciona literales de
tipos struct en general, y los valores no predeterminados de otros tipos struct se crean siempre en Hltimo
t)rmino mediante constructores de instancia de dic=os tipos struct.
Cuando todos los operandos de una expresi-n son constantes de tipo simple, es posible ?ue el compilador
evalHe la expresi-n en tiempo de compilaci-n. 2ic=a expresi-n se conoce por el nombre de expresi-n
constante Oconstant-e2pressionR O[*.18R. 8as expresiones ?ue incluyen operadores de0inidos por otros tipos
struct no se consideran expresiones constantes.
%ediante las declaraciones const es posible declarar constantes de los tipos simples O[1".4R. 4o es posible
tener constantes de otros tipos struct, pero se consigue un e0ecto similar mediante campos static
readonly.
8as conversiones ?ue involucran tipos simples pueden participar en la evaluaci-n de los operadores de
conversi-n de0inidos por otros tipos struct, pero un operador de conversi-n de0inido por el usuario no puede
participar en la evaluaci-n de otros operadores de0inidos por el usuario O[#.4.3R.
!.1.# Tipos integrales
C# admite nueve tipos integralesG sbyte, byte, s"ort, us"ort, int, uint, long ulong y

c"ar. 8os tipos
integrales tienen los siguientes tamaUos e intervalos de valoresG
El tipo sbyte, ?ue representa enteros de 8 bits con signo con valores comprendidos entre W128 y 12*.
El tipo byte, ?ue representa enteros de 8 bits sin signo con valores comprendidos entre " y 2.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. $(
Especificacin del lenguaje C#
El tipo s"ort, ?ue representa enteros de 1# bits con signo con valores comprendidos entre W32*#8 y 32*#*.
El tipo us"ort, ?ue representa enteros de 1# bits sin signo con valores comprendidos entre " y #3.
El tipo int, ?ue representa enteros de 32 bits con signo con valores comprendidos entre W214*483#48 y
214*483#4*.
El tipo uint, ?ue representa enteros de 32 bits sin signo con valores comprendidos entre " y 42+4+#*2+.
El tipo long, ?ue representa enteros de #4 bits con signo con valores comprendidos entre W
+2233*2"3#84**8"8 y +2233*2"3#84**8"*.
El tipo ulong, ?ue representa enteros de #4 bits sin signo con valores comprendidos entre " y
1844#*44"*3*"+1#1.
El tipo c"ar representa enteros sin signo de 1# bits con valores entre " y #3. El con$unto de valores
posibles para el tipo c"ar corresponde al $uego de caracteres 7nicode. &un?ue c"ar tiene la misma
representaci-n ?ue us"ort, no todas las operaciones permitidas en un tipo est(n permitidas en el otro.
8os operadores unarios y binarios de tipos integrales siempre traba$an con precisi-n de 32 bits con signo,
precisi-n de 32 bits sin signo, precisi-n de #4 bits con signo o precisi-n de #4 bits sin signoG
'ara los operadores unarios < y A, el operando se convierte al tipo 1, donde 1 es el primero de int, uint,
long y ulong ?ue puede representar completamente todos los valores posibles del operando. 2espu)s se
e$ecuta la operaci-n con la precisi-n del tipo 1, y el tipo del resultado es 1.
'ara el operador unario C, el operando se convierte al tipo 1, donde 1 es el primero de int y long ?ue
puede representar completamente todos los valores posibles del operando. 2espu)s se e$ecuta la operaci-n
con la precisi-n del tipo 1, y el tipo del resultado es 1. El operador unario C no se puede aplicar a operandos
del tipo ulong.
'ara los operadores binarios <, C, >, ., B, F, G, H, ++, @+, E, D, E+ y D+, los operandos se convierten al tipo
1, donde 1 es el primero de int, uint, long y ulong ?ue puede representar completamente todos los
valores posibles de los dos operandos. 2espu)s se e$ecuta la operaci-n con la precisi-n del tipo 1, y el tipo
del resultado es 1 Oo bool para los operadores relacionalesR. 8os operadores binarios no permiten ?ue un
operando sea de tipo long y el otro de tipo ulong.
'ara los operadores binarios DD y EE, el operando i1?uierdo se convierte al tipo 1, donde 1 es el primero de
int, uint, long y ulong ?ue puede representar completamente todos los valores posibles del operando.
2espu)s se e$ecuta la operaci-n con la precisi-n del tipo 1, y el tipo del resultado es 1.
El tipo c"ar se clasi0ica como un tipo integral, pero di0iere de otros tipos integrales en dos aspectosG
4o existen conversiones impl5citas desde otros tipos al tipo c"ar. En concreto, aun?ue los tipos sbyte,
byte y us"ort tienen intervalos de valores ?ue son totalmente representables mediante el tipo c"ar, las
conversiones impl5citas de sbyte, byte o us"ort a c"ar no existen.
8as constantes de tipo c"ar deben escribirse como literales de caracteres Ocharacter-literalsR o como
literales de enteros Ointe&er-literalsR en combinaci-n con una conversi-n al tipo c"ar. 'or e$emplo,
(c"ar)23 es lo mismo ?ue WZ#333'W.
8os operadores e instrucciones c"ec(ed y unc"ec(ed se utili1an para controlar la comprobaci-n del
desbordamiento para las operaciones y conversiones aritm)ticas de tipos integrales O[*..12R. En un contexto
c"ec(ed, un desbordamiento produce un error de tiempo de compilaci-n o causa una excepci-n
System.%ver-lo,)#ce&tion. En un contexto unc"ec(ed, los desbordamientos no se tienen en cuenta y los
bits de orden superior ?ue no son aceptables para el tipo de destino se descartan.
$$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
!.1.$ Tipos de punto flotante
C# admite dos tipos de punto 0lotanteG -loat y double. 8os tipos -loat y double se representan mediante
los 0ormatos !EEE *4 de 32 bits de precisi-n simple y de #4 bits de precisi-n doble, ?ue proporcionan los
siguientes con$untos de valoresG
Cero positivo y cero negativo. En la mayor5a de las situaciones, cero positivo y cero negativo tienen un
comportamiento id)ntico al del valor simple cero, pero algunas operaciones distinguen entre los dos
O[*.*.2R.
!n0inito positivo e in0inito negativo. 8os in0initos son generados por operaciones como dividir por cero un
nHmero distinto de cero. 'or e$emplo, el resultado de 2.3 . 3.3 es in0inito positivo, y el de C2.3 . 3.3
es in0inito negativo.
El valor no num)rico O2ot-a-2!/erR, abreviado normalmente como 4a4. 8os valores 4a4 se generan por
operaciones de punto 0lotante no v(lidas, como dividir cero por cero.
El con$unto 0inito de valores distintos de cero con el 0ormato s X % X 2
e
, donde s es 1 o Y1, y % y e est(n
determinados por el tipo de punto 0lotante concretoG para -loat, " L % L 2
24
y Y14+ c e c 1"4, y para
double, " L % L 2
3
y Y1"* c e c +*". 8os nHmeros de punto 0lotante sin normali1ar se consideran valores
v(lidos distintos de cero.
El tipo -loat puede representar valores comprendidos entre aproximadamente 1. X 1"
Y4
y 3.4 X 1"
38
con una
precisi-n de * d5gitos.
El tipo double puede representar valores comprendidos entre aproximadamente ." X 1"
Y324
y 1.* X 1"
3"8
con
una precisi-n de 1B1# d5gitos.
.i uno de los operandos de un operador binario es un tipo de punto 0lotante, el otro debe ser un tipo integral o un
tipo de punto 0lotante, y la operaci-n se evalHa como sigueG
.i uno de los operandos es un tipo integral, se convierte al tipo de punto 0lotante del otro operando.
2espu)s, si uno de los operandos es de tipo double, el otro se convierte a double, la operaci-n se e$ecuta
utili1ando por lo menos el intervalo y la precisi-n double, y el tipo del resultado es double Oo bool para
los operadores relacionalesR.
/ bien, la operaci-n se e$ecuta utili1ando por lo menos el intervalo y la precisi-n -loat y el tipo del
resultado es -loat Oo bool para los operadores relacionalesR.
8os operadores de punto 0lotante, incluidos los operadores de asignaci-n, nunca producen excepciones. En lugar
de ello, en situaciones excepcionales, las operaciones de punto 0lotante producen cero, in0inito o 4a4, como se
explica a continuaci-nG
.i el resultado de una operaci-n de punto 0lotante es demasiado pe?ueUo para el 0ormato de destino, el
resultado de la operaci-n es cero positivo o cero negativo.
.i el resultado de una operaci-n de punto 0lotante es demasiado grande para el 0ormato de destino, el
resultado de la operaci-n es in0inito positivo o in0inito negativo.
.i una operaci-n de punto 0lotante no es v(lida, el resultado de la operaci-n es 4a4.
.i uno o los dos operandos de una operaci-n de punto 0lotante es 4a4, el resultado de la operaci-n es 4a4.
8as operaciones de punto 0lotante pueden reali1arse con mayor precisi-n ?ue el tipo de resultado de la
operaci-n. 'or e$emplo, algunas ar?uitecturas de =ard9are admiten el tipo de punto 0lotante PextendedQ o Plong
doubleQ con un intervalo y precisi-n mayores ?ue el tipo double, e impl5citamente reali1an todas las
operaciones de punto 0lotante utili1ando este tipo de mayor precisi-n. .e puede conseguir ?ue las ar?uitecturas
de =ard9are de esta clase realicen operaciones de punto 0lotante con %enor precisi-n s-lo a cambio de un costo
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. $"
Especificacin del lenguaje C#
excesivo en el rendimientoV en ve1 de re?uerir una implementaci-n ?ue penalice tanto el rendimiento como la
precisi-n, C# permite utili1ar un tipo de mayor precisi-n para todas las operaciones de punto 0lotante. &parte de
proporcionar resultados m(s precisos, esto rara ve1 tiene e0ectos medibles. 4o obstante, en expresiones con la
0orma # > y . ?, donde la multiplicaci-n genera un resultado ?ue sale del intervalo de double, pero la siguiente
divisi-n devuelve el resultado temporal al intervalo de double, el =ec=o de ?ue la expresi-n se evalHe en un
0ormato de intervalo mayor puede producir un resultado 0inito en lugar de in0inito.
!.1.+ Tipo decimal
El tipo decimal es un tipo de datos de 128 bits apto para c(lculos 0inancieros y monetarios. El tipo decimal
puede representar valores comprendidos entre aproximadamente 1." X 1"
Y28
y *.+ X 1"
28
con 28B2+ d5gitos
signi0icativos.
El con$unto 0inito de valores de tipo decimal tiene la 0orma OW1R
s
X c X 1"
Be
, donde el signo s es " o 1, el
coe0iciente c viene dado por " c c L 2
+#
y la escala e es " c e c 28. El tipo decimal no admite ceros con signo,
valores in0initos ni valores 4a4. 7n decimal se representa como un entero de +# bits elevado a die1. 'ara
valores decimal con un valor absoluto menor ?ue 2.3m, el valor es exacto s-lo =asta la posici-n decimal 28.
'ara valores decimal con un valor absoluto mayor o igual ?ue 2.3m, el valor es exacto =asta el d5gito 28 o 2+.
&l contrario ?ue los tipos de datos -loat y double, los nHmeros 0raccionarios decimales como ",1 pueden
representarse exactamente en la representaci-n decimal. En las representaciones -loat y double, estos
nHmeros con 0recuencia son 0racciones in0initas, lo ?ue las =ace m(s susceptibles de errores de redondeo.
.i uno de los operandos de un operador binario es de tipo decimal, el otro debe ser un tipo integral o un tipo
decimal. .i est( presente un operando de tipo integral, se convertir( a decimal antes de reali1ar la operaci-n.
El resultado de una operaci-n con valores de tipo decimal es el ?ue resultar5a de calcular un resultado exacto
Oconservando la escala, segHn lo de0inido por cada operadorR y, a continuaci-n, redondearlo para a$ustarse a la
representaci-n. El resultado se redondea =asta el valor representable m(s pr-ximo y, en caso de ?ue un resultado
tenga la misma proximidad con dos valores representables, se redondea al valor ?ue tenga un nHmero par en la
posici-n del d5gito menos signi0icativo Oesto se conoce como Predondeo de bancaQR. 7n resultado cero siempre
tiene un signo " y una escala ".
.i una operaci-n aritm)tica decimal genera un valor menor o igual ?ue X 1"
B2+
en valor absoluto, el resultado
de la operaci-n es cero. .i una operaci-n aritm)tica decimal genera un resultado demasiado grande para el
0ormato decimal, se origina una excepci-n System.%ver-lo,)#ce&tion.
El tipo decimal tiene una precisi-n mayor, pero un intervalo menor, ?ue los tipos de punto 0lotante. 'or lo
tanto, las conversiones de los tipos de punto 0lotante a decimal pueden producir excepciones de
desbordamiento, y las conversiones de decimal a los tipos de punto 0lotante pueden causar una p)rdida de
precisi-n. 'or estos motivos, no existen conversiones impl5citas entre los tipos de punto 0lotante y decimal, y
sin conversiones expl5citas, no es posible combinar operandos de punto 0lotante y decimal en la misma
expresi-n.
!.1.- Tipo bool
El tipo bool representa cantidades l-gicas booleanas. 8os valores posibles del tipo bool son true y -alse.
4o existen conversiones est(ndar entre bool y otros tipos. En concreto, el tipo bool es Hnico y exclusivo de los
tipos integrales, y un valor bool no puede sustituir a un valor integral, ni viceversa.
En los lengua$es C y CSS, un valor integral o de punto 0lotante cero, o un puntero de valor null, pueden
convertirse al valor booleano -alse, y un valor integral o de punto 0lotante distinto de cero o un puntero con un
valor distinto de null pueden convertirse al valor booleano true. En C#, las conversiones de esta categor5a se
llevan a cabo mediante la comparaci-n expl5cita de un valor integral o de punto 0lotante con cero, o mediante la
comparaci-n expl5cita de una re0erencia de ob$eto con null.
"' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
!.1.. Tipos de enumeracin
7n tipo de enumeraci-n es un tipo exclusivo con constantes con nombre. Todos los tipos de enumeraci-n tienen
un tipo subyacente, ?ue debe ser byte, sbyte, s"ort, us"ort, int uint long o ulong. El con$unto de
valores del tipo de enumeraci-n es el mismo ?ue el del con$unto de valores del tipo subyacente. 8os valores del
tipo de la enumeraci-n no se restringen a los valores de las constantes nombradas. 8os tipos de enumeraci-n se
de0inen mediante declaraciones de enumeraci-n O[14.1R.
!.1.10 Tipos ;ue aceptan alores 1566
7n tipo ?ue acepta valores 4788 puede representar todos los valores de su tipo s!/yacente m(s un valor
4788 adicional. 7n tipo 4788 se escribe como 17, donde 1 es el tipo subyacente. Esta sintaxis es la 0orma
abreviada de System.NullableD1E y las dos 0ormas se pueden utili1ar indistintamente.
2e manera inversa, un tipo de valor "!e no acepta valores 2300 es cual?uier tipo de valor distinto de
System.NullableD1E y su 0orma abreviada 17 Opara cual?uier 1R, m(s cual?uier par(metro de tipo
restringido a tipos de valor ?ue no acepten valores 4788 Oes decir, cual?uier par(metro de tipo con una
restricci-n structR. El tipo System.NullableD1E especi0ica la restricci-n de tipo de valor para 1
([1".1.), lo ?ue signi0ica ?ue el tipo de valor subyacente de un tipo ?ue acepta valores 4788 puede ser
cual?uier valor ?ue no acepte valores 4788. El tipo subyacente de un tipo ?ue no acepte valores 4788 no
puede ser un tipo ?ue acepte valores 4788 ni un tipo de re0erencia. 'or e$emplo, int77 y string7 no son
tipos v(lidos.
7na instancia de un tipo 17 ?ue acepta valores 4788 tiene dos propiedades de s-lo lectura pHblicasG
7na propiedad HasUalue del tipo bool
7na propiedad Ualue del tipo 1
7na instancia para la ?ue HasUalue es verdadera no es 4788. 7na instancia ?ue no es 4788 contiene un
valor conocido y Ualue devuelve dic=o valor.
7na instancia para la ?ue HasUalue es 0also se dice ?ue es 4788. 7na instancia 4788 tiene un valor no
de0inido. .i intenta leer Ualue de una instancia 4788 se genera una excepci-n
System.$nvalid%&eration)#ce&tion. El proceso de tener acceso a la propiedad Ualue de una instancia
?ue acepta valores 4788 se conoce como desa1!star.
&dem(s del constructor predeterminado, cada tipo 17 ?ue acepta valores 4788 tiene un constructor pHblico
?ue adopta un argumento Hnico del tipo 1. 2ado un valor # del tipo 1, una invocaci-n de constructor con la
estructura
ne, 17(#)
crea una instancia 17 ?ue no acepta valores 4788 para los ?ue la propiedad Ualue es #. El proceso de crear
una instancia ?ue no acepta valores 4788 de un tipo ?ue s5 acepta valores 4788 para un valor dado se conoce
como a1!star.
Existen conversiones impl5citas desde el literal null a 17 O[R y desde 1 a 17 O[#.1.4R.
!.2 Tipos de referencia
7n tipo de re0erencia es un tipo de clase, un tipo de inter0a1, un tipo de matri1 o un tipo delegado.
reference-t#pe1
class-t#pe
interface-t#pe
arra#-t#pe
dele&ate-t#pe
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. "1
Especificacin del lenguaje C#
class-t#pe1
t#pe-na%e
object
string
interface-t#pe1
t#pe-na%e
arra#-t#pe1
non-arra#-t#pe ran3-specifiers
non-arra#-t#pe1
t#pe
ran3-specifiers1
ran3-specifier
ran3-specifiers ran3-specifier
ran3-specifier1
4 di%-separators
opt
5
di%-separators1

di%-separators
dele&ate-t#pe1
t#pe-na%e
7n valor de tipo de re0erencia es una re0erencia a una instancia del tipo, ?ue se conoce como o/1eto. El valor
especial null es compatible con todos los tipos de re0erencia e indica la ausencia de una instancia.
!.2.1 Tipos de clase
7n tipo de clase de0ine una estructura de datos ?ue contiene miembros de datos Oconstantes y camposR,
miembros de 0unci-n Om)todos, propiedades, eventos, indi1adores, operadores, constructores de instancia,
destructores y constructores est(ticosR y tipos anidados. 8os tipos de clase admiten la =erencia, un mecanismo
mediante el cual una clase derivada puede extender y especiali1ar a las clases base. 8as instancias de los tipos de
clase se crean mediante expresiones de creaci-n de ob$etos Oo->ect-creation-e2pressionsR O[*..1".1R.
8os tipos de clase se describen en [1".
Ciertos tipos de clases prede0inidos tienen un signi0icado especial en el lengua$e C#, tal como se describe en la
siguiente tabla.
Tipo de clase +escripcin
System.%bject
Clase base de0initiva de todos los dem(s tipos. >ea [.
System.String
El tipo de cadena del lengua$e de C#. >ea [.
System.Ualue1y&e
8a clase base de todos los tipos de valor. >ea [.
System.)num
8a clase base de todos los tipos enum. >ea [.
System.'rray
8a clase base de todos los tipos de matri1. >ea [.
System.6elegate
8a clase base de todos los tipos de delegado. >ea [.
System.)#ce&tion
8a clase base de todos los tipos de excepci-n. >ea [.
"2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
!.2.2 Tipo object
El tipo de clase object es la clase base de0initiva de todos los dem(s tipos. Todos los tipos de C# se derivan
directa o indirectamente del tipo de clase object.
8a palabra clave object no es m(s ?ue un alias de la clase prede0inida System.%bject.
!.2.3 Tipo string
El tipo string es un tipo de clase sealed ?ue =ereda directamente de object. 8as instancias de la clase
string representan cadenas de caracteres 7nicode.
8os valores del tipo string pueden escribirse como literales de cadena O[2.4.4.R.
8a palabra clave string no es m(s ?ue un alias de la clase prede0inida System.String.
!.2.! Tipos de interfa8
7na inter0a1 de0ine un contrato. 7na clase o estructura ?ue implementa una inter0a1 debe ad=erirse a su
contrato. 7na inter0a1 puede derivarse de varias inter0aces base, y una clase o estructura puede implementar
varias inter0aces.
8os tipos de inter0a1 se describen en [13.
!.2.# Tipos de matri8
7na matri1 es una estructura de datos ?ue contiene cero o m(s variables, a las ?ue se obtiene acceso a trav)s de
5ndices calculados. 8as variables contenidas en una matri1, tambi)n conocidas como elementos de la matri1, son
todas del mismo tipo, denominado tipo de elemento de la matri1.
8os tipos de matri1 se describen en [12.
!.2.$ Tipos de delegados
7n delegado es una estructura de datos ?ue =ace re0erencia a uno o m(s m)todos. 'ara los m)todos de instancia,
se re0iere tambi)n a sus correspondientes instancias de ob$eto.
El e?uivalente m(s cercano de un delegado en C o CSS es un puntero a una 0unci-n pero, mientras ?ue )ste s-lo
puede =acer re0erencia a 0unciones est(ticas, un delegado puede =acer re0erencia tanto a m)todos est(ticos como
a m)todos de instancia. En este caso, el delegado no s-lo almacena una re0erencia al punto de entrada del
m)todo, sino ?ue tambi)n almacena una re0erencia a la instancia de ob$eto para el ?ue se invoca el m)todo.
8os tipos de delegado se describen en [1.
!.3 %onersiones bo"ing y unbo"ing
El concepto de boxing y unboxing desempeUa un papel central en el sistema de tipos de C#. .irven como enlace
entre los tipos de valor Ovale-t#pesR y los tipos de re0erencia Oreference-t#pesR, al permitir la conversi-n de
cual?uier valor de un tipo de valor Ovale-t#peR al tipo object y viceversa. 8as conversiones boxing y
unboxing =abilitan una visi-n uni0icada del sistema de tipos en la ?ue un valor de cual?uier tipo puede tratarse
b(sicamente como un ob$eto.
!.3.1 %onersiones bo"ing
7na conversi-n boxing permite ?ue un tipo de valor Ovale-t#peR se convierta impl5citamente en un tipo de
re0erencia Oreference-t#peR. Existen los siguientes tipos de conversiones boxingG
2e cual?uier tipo de valor Ovale-t#peR al tipo object.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. "3
Especificacin del lenguaje C#
2e cual?uier tipo de valor Ovale-t#peR al tipo System.Ualue1y&e.
2e cual?uier tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR a cual?uier tipo de
inter0a1 Ointerface-t#peR implementada por el tipo de valor Ovale-t#peR.
2e cualquier tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR a cual?uier tipo
de inter0a1 Ointerface-t#peR implementada por el tipo subyacente del tipo ?ue acepta valores 4788
Onlla-le-t#peR.
2e cual?uier tipo enum Oen%-t#peR al tipo System.)num.
2e cual?uier tipo ?ue acepta valores 4788 Onlla-le-t#peR con un tipo enum Oen%-t#peR subyacente al tipo
System.)num.
Tenga en cuenta ?ue una conversi-n impl5cita desde un par(metro de tipo se e$ecutar( como una conversi-n
boxing si, en tiempo de e$ecuci-n, termina convirti)ndose desde un tipo de valor a un tipo de re0erencia
O[#.1.+R.
8a conversi-n boxing de un tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR consiste en
asignar una instancia del ob$eto y despu)s copiar el tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-
vale-t#peR en esa instancia.
8a conversi-n boxing de un valor de un tipo ?ue acepta valores 4788 Onlla-le-t#peR produce una re0erencia
4788 si se trata de un valor null OHasUalue es -alseR, o el resultado de desa$ustar y reali1ar una conversi-n
boxing en el valor subyacente de lo contrario.
El proceso real de conversi-n boxing del valor de un tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-
vale-t#peR se entiende me$or si uno se imagina la existencia de una clase /o.ing gen)rica, ?ue se comporta
como si estuviera declarada de la siguiente 0ormaG
sealed class :o#D1E/ System.Ualue1y&e
{
1 value;
&ublic :o#(1 t) {
value + t;
!
!
8a conversi-n boxing de un valor v de tipo 1 consiste a=ora en e$ecutar la expresi-n :o#D1E(v) y devolver la
instancia resultante como un valor de tipo object. 'or lo tanto, las instrucciones
int i + 289;
object bo# + i;
conceptualmente se corresponden con
int i + 289;
object bo# + ne, :o#DintE(i);
8a conversi-n boxing de una clase como :o#D1E no existe en realidad y el tipo din(mico de un valor al ?ue se
=a aplicado la conversi-n boxing no es realmente un tipo de clase. En lugar de ello, un valor convertido
mediante boxing de tipo 1 tiene el tipo din(mico 1, y una comprobaci-n de tipo din(mico ?ue usa el operador
is sencillamente puede =acer re0erencia al tipo 1. 'or e$emploG
int i + 289;
object bo# + i;
i- (bo# is int) {
Console.Write(":o# contains an int");
!
devolver( la cadena P:o# contains an intQ en la consola.
"# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
7na conversi-n boxing implica la creaci/n de na copia del valor al ?ue se aplica la conversi-n. Esto es distinto
de la conversi-n de un tipo de re0erencia Oreference-t#peR a un tipo object, en la cual el valor sigue =aciendo
re0erencia a la misma instancia y sencillamente se considera como el tipo object menos derivado. 'or e$emplo,
dada la declaraci-n
struct *oint
{
&ublic int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
las siguientes instrucciones
*oint & + ne, *oint(23 23);
object bo# + &;
&.# + 83;
Console.Write(((*oint)bo#).#);
muestran en la consola el valor 1", por?ue la operaci-n boxing impl5cita ?ue ocurre en la asignaci-n de & a bo#
causa la copia del valor de &. En cambio, si se =ubiera declarado *oint como class, el resultado ser5a 2",
puesto ?ue & y bo# =ar5an re0erencia a la misma instancia.
!.3.2 %onersiones 5nbo"ing
7na conversi-n unboxing permite ?ue un tipo de re0erencia Oreference-t#peR se convierta expl5citamente en un
tipo de valor Ovale-t#peR. Existen los siguientes tipos de conversiones unboxingG
2e cual?uier tipo object a cual?uier tipo de valor Ovale-t#peR.
2e cual?uier tipo System.Ualue1y&e a cual?uier tipo de valor Ovale-t#peR.
2e cual?uier tipo de inter0a1 Ointerface-t#peR a cual?uier tipo de valor ?ue no acepta valores 4788 Onon-
nlla-le-vale-t#peR ?ue implementa el tipo de inter0a1 Ointerface-t#peR.
2e cual?uier tipo de inter0a1 Ointerface-t#peR a cual?uier tipo ?ue acepta valores 4788 Onlla-le-t#peR cuyo
tipo subyacente implementa el tipo de inter0a1 Ointerface-t#peR.
2el tipo System.)num a cual?uier tipo enum Oen%-t#peR.
2e tipo System.)num a cual?uier tipo ?ue acepta valores 4788 Onlla-le-t#peR con un tipo enum Oen%-
t#peR subyacente.
Tenga en cuenta ?ue una conversi-n expl5cita a un par(metro de tipo se e$ecutar( como una conversi-n
unboxing si, en tiempo de e$ecuci-n, termina convirti)ndose desde un tipo de re0erencia a un tipo de valor
O[#.2.#R.
7na operaci-n unboxing a un tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR consiste en
comprobar primero ?ue la instancia del ob$eto es un valor al ?ue se =a aplicado la conversi-n boxing de un tipo
de valor determinado ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR, y copiar despu)s el valor 0uera de
la instancia.
8a conversi-n unboxing a un tipo ?ue acepta valores 4788 Onlla-le-t#peR produce el valor 4788 de dic=o
tipo si el operando de origen es null, o el resultado desa$ustado de reali1ar una conversi-n unboxing en la
instancia de ob$eto al tipo de valor subyacente desde el tipo ?ue acepta valores 4788 Onlla-le-t#peR en caso
contrario.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. "!
Especificacin del lenguaje C#
En cuanto a la clase boxing imaginaria descrita en la secci-n anterior, una conversi-n unboxing de un ob$eto
bo# a un tipo de valor 1 consiste en e$ecutar la expresi-n ((:o#D1E)bo#).value. 'or lo tanto, las
instrucciones
object bo# + 289;
int i + (int)bo#;
conceptualmente se corresponden con
object bo# + ne, :o#DintE(289);
int i + ((:o#DintE)bo#).value;
'ara ?ue una conversi-n unboxing a un tipo de valor dado ?ue no acepta valores 4788 Onon-nlla-le-vale-
t#peR se e$ecute correctamente en tiempo de e$ecuci-n, el valor del operando de origen debe ser una re0erencia a
un ob$eto creado mediante una conversi-n boxing de ese tipo de valor ?ue no acepta valores 4788 Onon-
nlla-le-vale-t#peR. .i el operando de origen tiene valor null, se producir( una excepci-n
System.NullOe-erence)#ce&tion. .i el operando de origen es una re0erencia a un ob$eto incompatible, se
producir( una excepci-n System.$nvalidCast)#ce&tion.
'ara ?ue una conversi-n unboxing a un tipo de valor dado ?ue acepta valores 4788 Onlla-le-t#peR se e$ecute
correctamente en tiempo de e$ecuci-n, el valor del operando de origen debe ser null o una re0erencia a un valor
creado mediante la conversi-n boxing del tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR
subyacente del tipo ?ue acepta valores 4788 nlla-le-t#pe. .i el operando de origen es una re0erencia a un
ob$eto incompatible, se producir( una excepci-n System.$nvalidCast)#ce&tion.
!.! Tipos construidos
7na declaraci-n de tipo gen)rico, por s5 misma, denota un tipo gen6rico sin enla-ar ?ue se utili1a como
P=uellaQ para 0ormar muc=os tipos di0erentes aplicando arg!entos de tipo. 8os argumentos de tipo se escriben
entre corc=etes angulares OD y ER inmediatamente despu)s del nombre de la declaraci-n de tipo gen)rico. 7n
tipo ?ue incluye al menos un argumento de tipo se llama un tipo constr!ido. 7n tipo construido se puede utili1ar
en la mayor5a de lugares en el idioma en el ?ue puede aparecer el nombre del tipo. 7n tipo gen)rico
independiente s-lo se puede utili1ar dentro de una expresi-n typeo0 Ot#peof-e2pressionR O[*..11R.
8os tipos construidos tambi)n se pueden utili1ar en expresiones como nombres simples O[*..2R o cuando se
obtiene acceso a un miembro O[*..4R.
&l evaluar un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR s-lo se tienen en cuenta los
tipos gen)ricos con el nHmero correcto de par(metros tipo. 'or lo tanto, es posible utili1ar el mismo
identi0icador para identi0icar tipos di0erentes siempre y cuando los tipos tengan di0erente nHmero de par(metros
de tipo. Esto resulta Htil al me1clar clases gen)ricas y no gen)ricas en el mismo programaG
names&ace Widgets
{
class ^ueue {...!
class ^ueueD1)lementE {...!
!
names&ace My'&&lication
{
using Widgets;
class I
{
^ueue Q2; .. Non=generic Widgets.^ueue
^ueueDintE Q8; .. Seneric Widgets.^ueue
!
!
Es posible ?ue un nombre de tipo Ot#pe-na%eR identi0i?ue un tipo construido aun?ue )ste no especi0i?ue
directamente par(metros de tipo. Esto puede ocurrir si un tipo est( anidado dentro de una declaraci-n de clase
"6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
gen)rica y el tipo de instancia de la declaraci-n contenedor se utili1a de manera impl5cita para la bHs?ueda de
nombres O[1".3.8.#RG
class %uterD1E
{
&ublic class $nner {...!
&ublic $nner i; .. 1y&e o- i is %uterD1E.$nner
!
En c-digo no seguro, un tipo construido no se puede utili1ar como un tipo no administrado On%ana&ed-t#peR
O[18.2R.
!.!.1 'rgumentos de tipo
Cada argumento de una lista de argumentos de tipo es simplemente un tipo Ot#peR.
t#pe-ar&%ent-list1
D t#pe-ar&%ents E
t#pe-ar&%ents1
t#pe-ar&%ent
t#pe-ar&%ents t#pe-ar&%ent
t#pe-ar&%ent1
t#pe
En c-digo no seguro O[18R, es posible ?ue un argumento de tipo Ot#pe-ar&%entR no sea un tipo de puntero.
Cada argumento de tipo debe respetar todas las restricciones del par(metro tipo correspondiente O[1".1.R.
!.!.2 Tipos cerrados y abiertos
Todos los tipos se pueden clasi0icar como tipos a/iertos o tipos cerrados. 7n tipo abierto es un tipo ?ue implica
par(metros de tipo. ConcretamenteG
7n par(metro de tipo de0ine un tipo abierto.
7n tipo de matri1 es un tipo abierto solamente si su tipo de elemento es un tipo abierto.
7n tipo construido es un tipo abierto s-lo si uno o m(s de sus argumentos de tipo es un tipo abierto. 7n tipo
anidado construido es un tipo abierto s-lo si uno o m(s de sus argumentos de tipo o los argumentos de tipo
de sus tipos contenedores son un tipo abierto.
7n tipo cerrado es un tipo ?ue no es abierto.
En tiempo de e$ecuci-n, todos los c-digos de una declaraci-n de tipo gen)rico se e$ecutan en el contexto de un
tipo construido cerrado creado al aplicar argumentos de tipo a la declaraci-n gen)rica. Cada par(metro de tipo
dentro del tipo gen)rico est( enla1ado a un tipo concreto en tiempo de e$ecuci-n. El proceso en tiempo de
e$ecuci-n de todas las instrucciones y expresiones siempre tiene lugar con tipos cerradosV los tipos abiertos s-lo
tienen lugar durante el proceso en tiempo de compilaci-n.
Cada tipo construido cerrado tiene su propio con$unto de variables est(ticas, ?ue no se comparten con otros tipos
construidos cerrados. 8os tipos abiertos no se dan en tiempo de e$ecuci-n y, por lo tanto, no tienen variables
est(ticas asociadas. 2os tipos construidos cerrados son el mismo tipo si est(n construidos desde el mismo tipo
gen)rico independiente y sus argumentos de tipo correspondientes son el mismo tipo.
!.!.3 Tipos enla8ados y sin enla8ar
El t)rmino tipo sin enla-ar =ace re0erencia a un tipo no gen)rico o a un tipo gen)rico sin enla1ar. El t)rmino
tipo enla-ado =ace re0erencia a un tipo no gen)rico o a un tipo construido.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. "(
Especificacin del lenguaje C#
7n tipo sin enla1ar =ace re0erencia a la entidad declarada por una declaraci-n de tipo. 7n tipo gen)rico sin
enla1ar no es un tipo en s5 mismo, y no se puede usar como tipo de una variable, argumento o valor devuelto, ni
como un tipo base. 8a Hnica construcci-n en la ?ue se puede =acer re0erencia a un tipo gen)rico sin enla1ar es la
expresi-n ty&eo- O[*..11R.
!.!.! %umplimiento de las restricciones
.iempre ?ue se =aga re0erencia a un tipo construido o a un m)todo gen)rico, los argumentos de tipo
suministrados se cote$an con las restricciones de par(metro de tipo declaradas en el tipo o m)todo gen)ricos
O[1".1.R. 'ara cada cl(usula ,"ere, el argumento de tipo ' ?ue corresponde al par(metro de tipo denominado
se cote$a con cada una de las restricciones de la siguiente maneraG
.i la restricci-n es un tipo de clase o de inter0a1, o un par(metro de tipo, C debe representar dic=a restricci-n
con los argumentos de tipo suministrados sustituidos por cual?uier par(metro de tipo ?ue apare1ca en la
restricci-n. 'ara cumplir la restricci-n se debe dar el caso de ?ue el tipo ' se pueda convertir en el tipo C por
uno de los siguientes m)todosG
o 7na conversi-n de identidad O[#.1.1R
o 7na conversi-n de re0erencia impl5cita O[#.1.4R
o 7na conversi-n boxing O[#.1.R, siempre y cuando el tipo & sea un tipo ?ue no acepta valores 4788.
o 7na conversi-n de re0erencia impl5cita, boxing o de par(metro de tipo a partir de un par(metro de tipo '
a C O[R.
.i la restricci-n es la restricci-n de tipo de re0erencia OclassR, el tipo ' debe cumplir las siguientes
condicionesG
o ' es un tipo de inter0a1, de clase, de delegado o de matri1. Tenga en cuenta ?ue System.Ualue1y&e y
System.)num son tipos de re0erencia ?ue cumplen esta restricci-n.
o ' es un par(metro de tipo ?ue es un tipo de re0erencia O[1".1.R.
.i la restricci-n es la restricci-n de tipo de valor OstructR, el tipo ' debe cumplir una de las siguientes
condicionesG
o ' es un tipo struct o un tipo enum, pero no un tipo ?ue acepte valores 4788. Tenga en cuenta ?ue
System.Ualue1y&e y System.)num son tipos de re0erencia ?ue no cumplen esta restricci-n.
o ' es un par(metro de tipo ?ue tiene la restricci-n de tipo de valor O[1".1.R.
.i la restricci-n es la restricci-n del constructor ne,(), el tipo ' no debe ser abstract y debe tener un
constructor pHblico sin par(metros. Esta condici-n se cumple si una de las siguientes a0irmaciones es
verdaderaG
o ' es un tipo de valor puesto ?ue todos los tipos de valor tienen un constructor pHblico predeterminado
O[4.1.2R.
o ' es un par(metro de tipo ?ue tiene la restricci-n de constructor O[1".1.R.
o ' es un par(metro de tipo ?ue tiene la restricci-n de tipo de valor O[1".1.R.
o ' es una clase ?ue no es abstract y contiene un constructor &ublic expl5citamente declarado sin
par(metros.
o ' no es abstract y tiene un constructor predeterminado O[1".1".4R.
.e genera un error en tiempo de compilaci-n si los argumentos de tipo dados no cumplen una o m(s de las
restricciones de un par(metro de tipo.
"$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
'uesto ?ue los par(metros tipo no se =eredan, tampoco se =eredan las restricciones. En el siguiente e$emplo, 6
debe especi0icar la restricci-n en su par(metro de tipo 1 para ?ue 1 cumpla con la restricci-n impuesta por la
clase base :D1E. 'or el contrario, no es necesario ?ue ) especi0i?ue una restricci-n por?ue ListD1E
implementa $)numerable para cual?uier 1.
class :D1E ,"ere 1/ $)numerable {...!
class 6D1E/ :D1E ,"ere 1/ $)numerable {...!
class )D1E/ :DListD1EE {...!
!.# (ar)metros de tipo
7n par(metro de tipo es un identi0icador ?ue designa un tipo de valor o tipo de re0erencia al ?ue el par(metro
est( enla1ado en tiempo de e$ecuci-n.
t#pe-para%eter1
identificador
'uesto ?ue se puede crear una instancia para un par(metro de tipo con muc=os argumentos de tipo reales
di0erentes, los par(metros de tipo tienen operaciones y restricciones ligeramente di0erentes a las de otros tipos.
& continuaci-n se enumeran algunas de ellasG
7n par(metro de tipo no se puede utili1ar directamente para declarar una inter0a1 o una clase base O[1".2.4R.
8as reglas para la bHs?ueda de miembros en par(metros de tipo dependen de las restriccionesV si existe
alguna, se aplica al par(metro de tipo. En la secci-n [*.3 se proporcionan m(s detalles.
8as conversiones disponibles para un par(metro de tipo dependen de las restricciones, si existen, ?ue se
apli?uen al par(metro de tipo. En las secciones [ y [ se proporcionan m(s detalles.
El literal null no se puede convertir a un tipo dado por un par(metro de tipo a menos ?ue el par(metro de
tipo sea un tipo de re0erencia O[#.1.+R. .in embargo, se puede utili1ar en su lugar una expresi-n de-ault
O[*..13R. &dem(s, un valor con un tipo dado por un par(metro de tipo se pede comparar con null
utili1ando ++ y @+ O[*.+.#R, a menos ?ue el par(metro de tipo tenga la restricci-n de tipo de valor.
7na expresi-n ne, O[*..1".1R s-lo se puede utili1ar con un par(metro de tipo si el par(metro de tipo est(
restringido por una restricci-n de constructor Oconstrctor-constraintR o la restricci-n del tipo de valor
O[1".1.R.
7n par(metro de tipo no se puede utili1ar en cual?uier parte dentro de un atributo.
7n par(metro de tipo no se puede utili1ar en un acceso a miembros O[*..4R ni en un nombre de tipo O[3.8R
para identi0icar un miembro static o un tipo anidado.
En c-digo no seguro, un par(metro de tipo no se puede utili1ar como un tipo n%ana&ed-t#pe O[18.2R.
Como un tipo, los par(metros de tipo son una construcci-n en tiempo de compilaci-n. En tiempo de e$ecuci-n,
cada par(metro de tipo est( vinculado a un tipo en tiempo de e$ecuci-n ?ue se especi0ica al proporcionar un
argumento de tipo a la declaraci-n de tipo gen)rico. 'or lo tanto, el tipo de una variable declarado con un
par(metro de tipo ser( un tipo construido cerrado en tiempo de e$ecuci-n O[4.4.2R. 8a e$ecuci-n en tiempo de
e$ecuci-n de todas las instrucciones y expresiones ?ue implican los par(metros de tipo utili1a el tipo real ?ue se
proporcion- como el argumento de tipo para dic=o par(metro.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. ""
Especificacin del lenguaje C#
!.$ Tipos de )rbol de e"presiones
8os 5r/oles de e.presiones permiten ?ue las 0unciones an-nimas sean representadas como estructuras de datos
en lugar de como c-digo e$ecutable. 8os (rboles de expresiones son valores de tipos de 5r/ol de e.presiones
con la estructura System.LinQ.)#&ressions.)#&ressionD6E, donde 6 es cual?uier tipo delegado. En
adelante =aremos re0erencia a estos tipos mediante la 0orma abreviada )#&ressionD6E.
.i existe una conversi-n desde una 0unci-n an-nima a un tipo delegado 6, tambi)n existe una conversi-n al tipo
de (rbol expresiones )#&ressionD6E. %ientras ?ue la conversi-n de una 0unci-n an-nima a un tipo delegado
genera un delegado ?ue =ace re0erencias a c-digo e$ecutable para la 0unci-n an-nima, la conversi-n a un tipo de
(rbol de expresiones crea una representaci-n de (rbol de expresiones de la 0unci-n an-nima.
8os (rboles de expresiones son representaciones e0icientes de datos en memoria de 0unciones an-nimas y =acen
?ue la estructura de la 0unci-n an-nima sea transparente y expl5cita.
&l igual ?ue un tipo delegado 6, se considera ?ue )#&ressionD6E tiene tipos devueltos y de par(metro, ?ue
son los mismos de 6.
En el e$emplo siguiente se representa una 0unci-n an-nima como c-digo e$ecutable y como (rbol de
expresiones. 2ado ?ue existe una conversi-n a VuncDintintE, tambi)n existe una conversi-n a
)#&ressionDVuncDintintEEG
VuncDintintE del + # +E # < 2; .. Code
)#&ressionDVuncDintintEE e#& + # +E # < 2; .. 6ata
.iguiendo estas asignaciones, el delegado del =ace re0erencia a un m)todo ?ue devuelve # < 2, y el (rbol de
expresiones e#& =ace re0erencia a la estructura de datos ?ue describe la expresi-n # +E # < 2.
Tanto la de0inici-n exacta del tipo gen)rico )#&ressionD6E como las reglas precisas para construir un (rbol
de expresiones cuando una 0unci-n an-nima se convierte a un tipo de (rbol de expresiones superan el (mbito de
este documento, por lo ?ue se describen en otros.
Es importante seUalar dos cosas.
4o todas las 0unciones an-nimas se pueden representar como (rboles de expresiones. 'or e$emplo, no se
pueden representar 0unciones an-nimas con cuerpos de instrucci-n, ni 0unciones an-nimas ?ue
contengan expresiones de asignaciones. !ncluso en estos casos existe una conversi-n, pero no se
producir( correctamente en tiempo de compilaci-n.
)#&ressionD6E o0rece un m)todo de instancia Com&ile ?ue produce un delegado de tipo 6G
VuncDintintE del8 + e#&.Com&ile();
&l invocar a este delegado se provoca la e$ecuci-n del c-digo representado por el (rbol de expresiones.
&s5, dadas las de0iniciones anteriores, del y del2 son e?uivalentes, y las dos instrucciones siguientes
tendr(n el mismo e0ectoG
int i2 + del(2);
int i8 + del8(2);
2espu)s de e$ecutar este c-digo, tanto i2 como i8 tendr(n el valor 8.
1'' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
#. Variables
8as variables representan ubicaciones de almacenamiento. Toda variable tiene un tipo, ?ue determina los valores
?ue pueden almacenarse en ella. C# es un lengua$e con seguridad de tipos, y el compilador de C# garanti1a ?ue
los valores almacenados en variables siempre son del tipo apropiado. El valor de una variable puede modi0icarse
mediante una asignaci-n o con el uso de los operadores << y ==.
7na variable debe estar definitivaente asignada O[.3R para ?ue pueda obtenerse su valor.
Como se explica en las secciones siguientes, las variables pueden ser asignadas inicialente o no asignadas
inicialente. 7na variable asignada inicialmente tiene un valor inicial bien de0inido y siempre se considera
asignada de0initivamente. 7na variable no asignada inicialmente no tiene un valor inicial. 'ara ?ue una variable
no asignada inicialmente se considere asignada de0initivamente en una ubicaci-n determinada, debe ocurrir una
asignaci-n de la variable en todas las rutas de e$ecuci-n posibles ?ue condu1can a dic=a ubicaci-n.
#.1 %ategor2as de ariables
C# de0ine siete categor5as de variablesG variables est(ticas, variables de instancia, elementos de matri1,
par(metros de valores, par(metros de re0erencia, par(metros de salida y variables locales. En las pr-ximas
secciones se describen estas categor5as.
En el e$emplo
class '
{
&ublic static int #;
int y;
void V(int45 v int a re- int b out int c) {
int i + 2;
c + a < b<<;
!
!
# es una variable est(tica, y es una variable de instancia, v435 es un elemento de matri1, a es un par(metro de
valores, b es un par(metro de re0erencias, c es un par(metro de salida e i es una variable local.
#.1.1 Variables est)ticas
7n campo declarado con el modi0icador static se denomina varia/le est5tica. 7na variable est(tica se genera
antes de la e$ecuci-n del constructor est(tico O[1".12R de su tipo contenedor, y de$a de existir a la ve1 ?ue el
dominio de aplicaci-n asociado.
El valor inicial de una variable est(tica es el valor predeterminado O[.2R del tipo de la variable.
'ara los 0ines de comprobaci-n de asignaci-n de0initiva, una variable est(tica se considera asignada
inicialmente.
#.1.2 Variables de instancia
7n campo declarado sin el modi0icador static se denomina varia/le de instancia.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1'1
Especificacin del lenguaje C#
.1.2.1 .ariables de instancia en clases
7na variable de instancia de una clase se genera cuando se crea una nueva instancia de esa clase, y de$a de
existir cuando no =ay re0erencias a esa instancia y se =a e$ecutado el destructor de la instancia Osi existeR.
El valor inicial de una variable de instancia de una clase es el valor predeterminado O[.2R del tipo de la variable.
'ara los 0ines de comprobaci-n de asignaci-n de0initiva, una variable de instancia de una clase se considera
asignada inicialmente.
.1.2.2 .ariables de instancia en estructuras
7na variable de instancia de una estructura tiene exactamente el mismo per5odo de duraci-n ?ue la variable de
estructura a la ?ue pertenece. Es decir, cuando se genera o de$a de existir una variable de tipo de estructura, le
ocurre lo mismo a las variables de instancia de la estructura.
El estado de asignaci-n inicial de una variable de instancia de una estructura es el mismo ?ue el de la variable
?ue contiene la estructura. Es decir, si una variable de estructura se considera asignada inicialmente, lo mismo le
ocurre a sus variables de instancia, y si una variable de estructura se considera no asignada inicialmente, sus
variables de instancia tampoco lo est(n.
#.1.3 Elementos matriciales
8os elementos de una matri1 comien1an a existir cuando se crea una instancia de la matri1 y cesa su existencia
cuando de$an de existir re0erencias a dic=a instancia.
El valor inicial de los elementos de una matri1 es el valor predeterminado O[.2R del tipo de los elementos de la
matri1.
'ara los 0ines de comprobaci-n de asignaci-n de0initiva, un elemento de matri1 se considera asignado
inicialmente.
#.1.! (ar)metros de alor
7n par5etro de valor es un par(metro ?ue se declara sin re- u out.
7n par(metro de valor se genera al invocar el miembro de 0unci-n Om)todo, constructor de instancia, descriptor
de acceso u operadorR o la 0unci-n an-nima a la ?ue pertenece el par(metro, y se iniciali1a con el valor del
argumento especi0icado en la invocaci-n. 7n par(metro de valores normalmente de$a de existir tras la
devoluci-n del miembro de 0unci-n o la 0unci-n an-nima. .in embargo, si una 0unci-n an-nima captura el
par(metro de valor O[*.14R, su duraci-n se extiende al menos =asta ?ue el (rbol de expresiones o el delegado
creados a partir de esa 0unci-n an-nima son susceptibles de recolecci-n de elementos no utili1ados.
'ara los 0ines de comprobaci-n de asignaci-n de0initiva, un par(metro de valores se considera asignado
inicialmente.
#.1.# (ar)metros de referencia
7n par5etro de referencia es un par(metro ?ue se declara con un modi0icador re-.
7n par(metro de re0erencia no crea una nueva ubicaci-n de almacenamiento. En lugar de ello, un par(metro de
re0erencia representa la misma ubicaci-n de almacenamiento ?ue la variable especi0icada como argumento en la
invocaci-n de la 0unci-n an-nima o del miembro de 0unci-n. 'or lo tanto, el valor de un par(metro de re0erencia
siempre es el mismo ?ue el de la variable subyacente.
.e aplican las siguientes reglas de asignaci-n de0initiva a los par(metros de re0erencia. 2eben tenerse en cuenta
las distintas reglas de los par(metros de resultados explicadas en [.1.#.
1'2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
7na variable debe estar asignada de0initivamente O[.3R para ?ue pueda pasarse como par(metro de
re0erencia en la invocaci-n de un miembro de 0unci-n o un delegado.
2entro de un miembro de 0unci-n o una 0unci-n an-nima, un par(metro de re0erencia se considera asignado
inicialmente.
2entro de un m)todo de instancia o un descriptor de acceso de instancia de tipo struct, la palabra clave t"is
tiene exactamente el mismo comportamiento ?ue un par(metro de re0erencia de tipo struct O[*..*R.
#.1.$ (ar)metros de salida
7n par5etro de salida es un par(metro ?ue se declara con un modi0icador out.
7n par(metro de salida no crea una nueva ubicaci-n de almacenamiento. En lugar de ello, un par(metro de
salida representa la misma ubicaci-n de almacenamiento ?ue la variable especi0icada como argumento en la
invocaci-n del delegado o del miembro de 0unci-n. 'or lo tanto, el valor de un par(metro de salida siempre es el
mismo ?ue el de la variable subyacente.
.e aplican las siguientes reglas de asignaci-n de0initiva a los par(metros de salida. 2eben tenerse en cuenta las
distintas reglas de los par(metros de re0erencia explicadas en [.1..
7na variable no tiene por ?u) estar asignada de0initivamente para poder pasarla como par(metro de salida
en una invocaci-n de delegado o miembro de 0unci-n.
Tras la 0inali1aci-n normal de la invocaci-n de un delegado o miembro de 0unci-n, cada variable ?ue se
pase como par(metro de salida se considera asignada en esa ruta de e$ecuci-n.
2entro de un miembro de 0unci-n o una 0unci-n an-nima, un par(metro de salida se considera asignado
inicialmente.
Cada par(metro de salida de un miembro de 0unci-n o de una 0unci-n an-nima se debe estar asignado
de0initivamente O[.3R para poder obtener la salida del miembro de 0unci-n o la 0unci-n an-nima con
normalidad.
2entro de un constructor de instancia del tipo struct, la palabra clave t"is tiene exactamente el mismo
comportamiento ?ue un par(metro de salida de tipo struct O[*..*R.
#.1.+ Variables locales
7na varia/le local se declara mediante una declaraci-n de variable local Olocal-varia-le-declarationR, lo cual
puede ocurrir en un blo?ue O-loc3R, una instrucci-n 0or Ofor-state%entR, una instrucci-n s9itc= Oswitch-
state%entRo una instrucci-n using Osin&-state%entR, o mediante una instrucci-n 0oreac= Oforeach-state%entR o
una cl(usula catc= espec50ica Ospecific-catch-claseR en una instrucci-n try Otr#-state%entR.
8a vigencia de una variable local representa la parte de la e$ecuci-n del programa durante la cual se garanti1a
?ue =ay un espacio de almacenamiento reservado para ella. Esta vigencia se prolonga al menos desde la entrada
en el blo?ue O-loc3R, instrucci-n 0or Ofor-state%entR, instrucci-n s9itc= Oswitch-state%entR, instrucci-n using
Osin&-state%entR, instrucci-n 0oreac= Oforeach-state%entR, o cl(usula catc= espec50ica Ospecific-catch-claseR a
los ?ue est( asociada, =asta ?ue la e$ecuci-n de dic=o blo?ue, instrucci-n 0or, instrucci-n s9itc=, instrucci-n
using, instrucci-n 0oreac=, o cl(usula catc= espec50ica 0inali1a de cual?uier modo. O8a entrada en un blo?ue
contenedor o la llamada a un m)todo suspende, aun?ue no 0inali1a, la e$ecuci-n del blo?ue, instrucci-n 0or,
instrucci-n s9itc=, instrucci-n using, instrucci-n 0oreac=, o cl(usula catc= espec50ica actuales.R .i una 0unci-n
an-nima captura la variable local O[*.14.4.1R, su duraci-n se extiende al menos =asta ?ue el (rbol de expresiones
o el delegado creados a partir de esa 0unci-n an-nima, $unto con cual?uier otro ob$eto ?ue =aga re0erencia a la
variable capturada, sean susceptibles de recolecci-n de elementos no utili1ados.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1'3
Especificacin del lenguaje C#
.i se entra de manera recursiva en el blo?ue primario, la instrucci-n 0or, la instrucci-n s9itc=, la instrucci-n
using, la instrucci-n 0oreac=, o la cl(usula catc= espec50ica, se crear( una instancia nueva de la variable local
cada ve1, y su iniciali1ador de variable local Olocal-varia-le-initiali0erR, si existe, se evaluar( en cada ocasi-n.
7na variable local introducida por una declaraci-n de variable local Olocal-varia-le-declarationR no se iniciali1a
autom(ticamente y, por lo tanto, no tiene un valor predeterminado. 'ara los 0ines de comprobaci-n de
asignaci-n de0initiva, una variable local se considera no asignada inicialmente. 7na declaraci-n de variable
local Olocal-varia-le-declarationR puede incluir un iniciali1ador de variable local Olocal-varia-le-initiali0erR, en
cuyo caso la variable se considera asignada de0initivamente en todo su (mbito, a excepci-n de la expresi-n
suministrada en el iniciali1ador de la variable local.
En el (mbito de una variable local introducida por una declaraci-n de variable local, es un error en tiempo de
compilaci-n =acer re0erencia a esa variable local en una posici-n textual ?ue preceda al declarador de la variable
local Olocal-varia-le-declaratorR. .i la declaraci-n de variable local est( impl5cita O[8..1R, tambi)n se considera
un error =ace re0erencia a la variable local dentro de un declarador de variable local Olocal-varia-le-declaratorR.
7na variable local introducida por una instrucci-n 0oreac= Oforeach-state%entR o una cl(usula catc= espec50ica
Ospecific-catch-claseR se considera asignada de 0orma de0initiva en todo su (mbito.
8a duraci-n real de una variable local depende de la implementaci-n. 'or e$emplo, un compilador puede
determinar est(ticamente ?ue una variable local de un blo?ue s-lo se utili1a para una pe?ueUa parte del blo?ue,
y usar este an(lisis para ?ue el compilador genere un c-digo ?ue d) como resultado ?ue el almacenamiento de la
variable tenga una duraci-n m(s corta ?ue la de su blo?ue contenedor.
El almacenamiento a ?ue se re0iere una variable de re0erencia local se reclama independientemente de la
duraci-n de esa variable de re0erencia local O[3.+R.
#.2 Valores predeterminados
8as categor5as de variables siguientes se iniciali1an de 0orma autom(tica a sus valores predeterminadosG
>ariables est(ticas.
>ariables de instancia de instancias de clase.
Elementos matriciales.
El valor predeterminado de una variable depende de su tipo y se determina como sigueG
'ara una variable de un tipo de valor Ovale-t#peR, el valor predeterminado es el mismo ?ue el valor
calculado por el constructor predeterminado del tipo de valor Ovale-t#peR O[4.1.2R.
'ara una variable de tipo de re0erencia Oreference-t#peR, el valor predeterminado es null.
8a iniciali1aci-n a valores predeterminados, la suelen llevar a cabo el administrador de la memoria o el
recolector de elementos no utili1ados, ?ue iniciali1an la memoria a todos los bits cero antes de asignarla para su
uso. 'or este motivo, es conveniente utili1ar todos los bits cero para representar la re0erencia nula.
#.3 Estado de asignacin definitia
En una ubicaci-n dada dentro del c-digo e$ecutable de un miembro de 0unci-n, se dice ?ue una variable est(
asignada definitivaente si el compilador puede probar, mediante un an(lisis de 0lu$o est(tico concreto O[R, ?ue
la variable se =a iniciali1ado autom(ticamente o =a sido el destino de por lo menos una asignaci-n. 2ic=o de una
manera in0ormal, las reglas de la asignaci-n de0initiva sonG
7na variable asignada inicialmente O[.3.1R siempre se considera asignada de0initivamente.
1'# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
7na variable no asignada inicialmente O[.3.2R se considera asignada de0initivamente en una ubicaci-n dada
si todas las rutas de e$ecuci-n posibles ?ue llevan a ella contienen por lo menos uno de los siguientes
elementosG
o 7na asignaci-n simple O[*.1#.1R en la cual la variable es el operando i1?uierdo.
o 7na expresi-n de invocaci-n O[*..R o una expresi-n de creaci-n de ob$eto O[*..1".1R ?ue pasa la
variable como par(metro de salida.
o 'ara una variable local, una declaraci-n de variable local O[8..1R ?ue incluye un iniciali1ador de
variable.
8a especi0icaci-n 0ormal subyacente a las reglas in0ormales anteriores se describe en los apartados [.3.1, [.3.2
y [.3.3.
El estado de asignaci-n de0initiva de las variables de instancia de una variable de tipo struct Ostrct-t#peR puede
tener un seguimiento individual y tambi)n colectivo. &dem(s de las reglas anteriores, se aplican las reglas
siguientes a las variables de tipo struct Ostrct-t#peR y a sus variables de instanciaG
7na variable de instancia se considera asignada de0initivamente si la variable de tipo struct Ostrct-t#peR ?ue
la contiene se considera asignada de0initivamente.
7na variable de tipo struct Ostrct-t#peR se considera asignada de0initivamente si todas sus variables de
instancia se consideran asignadas de0initivamente.
8a asignaci-n de0initiva es un re?uisito obligatorio en los contextos siguientesG
7na variable debe estar asignada de0initivamente en cada ubicaci-n donde se obtenga su valor. Esto asegura
?ue nunca puedan ocurrir valores no de0inidos. .e considera ?ue la ocurrencia de una variable en una
expresi-n obtiene el valor de la variable, excepto cuandoG
o la variable es el operando i1?uierdo de una asignaci-n simple,
o la variable se pasa como un par(metro de salida, o
o la variable es de tipo struct Ostrct-t#peR y opera como el operando i1?uierdo de un acceso a miembros.
7na variable debe estar asignada de0initivamente en cada ubicaci-n donde se pase como un par(metro de
re0erencia. Esto asegura ?ue el miembro de 0unci-n ?ue se invoca puede considerar al par(metro de
re0erencias como asignado inicialmente.
Todos los par(metros de resultado de un miembro de 0unci-n deben estar asignados de0initivamente en cada
ubicaci-n donde se producen devoluciones del miembro de 0unci-n Omediante una instrucci-n return o
cuando la e$ecuci-n llega al 0inal del cuerpo del miembro de 0unci-nR. Esto asegura ?ue los miembros de
0unci-n no devuelven valores no de0inidos en los par(metros de salida, lo ?ue permite al compilador
considerar la invocaci-n de un miembro de 0unci-n ?ue llame a una variable como un par(metro de salida
e?uivalente a una asignaci-n de la variable.
8a variable t"is de un constructor de instancia de tipo struct Ostrct-t#peR debe estar asignada
de0initivamente en cada ubicaci-n donde se produ1can devoluciones del constructor de instancia.
#.3.1 Variables asignadas inicialmente
8as siguientes categor5as de variables se clasi0ican como asignadas inicialmenteG
>ariables est(ticas.
>ariables de instancia de instancias de clase.
>ariables de instancia de variables de estructura asignadas inicialmente.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1'!
Especificacin del lenguaje C#
Elementos matriciales.
'ar(metros de valor.
'ar(metros de re0erencia.
>ariables declaradas en una cl(usula catc" o en una instrucci-n -oreac".
#.3.2 Variables no asignadas inicialmente
8as siguientes categor5as de variables se clasi0ican como no asignadas inicialmenteG
>ariables de instancia de variables de estructura no asignadas inicialmente.
'ar(metros de salida, incluida la variable t"is de constructores de instancia de estructuras.
>ariables locales, excepto a?uellas declaradas en una cl(usula catc" o en una instrucci-n -oreac".
#.3.3 9eglas precisas para determinar asignaciones definitias
'ara determinar ?ue cada variable utili1ada est( asignada de0initivamente, el compilador debe utili1ar un
proceso e?uivalente al descrito en esta secci-n.
El compilador procesa el cuerpo de cada miembro de 0unci-n ?ue tenga una o m(s variables no asignadas
inicialmente. El compilador determina un estado de asignaci,n definitiva para cada variable v no asignada
inicialmente, en cada uno de los siguientes puntos del miembro de 0unci-nG
&l principio de cada instrucci-n
En el punto 0inal O[8.1R de cada instrucci-n
En cada arco ?ue trans0iere el control a otra instrucci-n o al punto 0inal de una instrucci-n
&l principio de cada expresi-n
&l 0inal de cada expresi-n
El estado de asignaci-n de0initiva de v puede serG
&signada de0initivamente. !ndica ?ue en todos los posibles 0lu$os de control para este punto, a v se le =a
asignado un valor.
4o asignada de0initivamente. 'ara el estado de una variable al 0inal de una expresi-n de tipo bool, el estado
de una variable ?ue no se =a asignado de0initivamente puede caer Oaun?ue no necesariamenteR en uno de los
siguientes subestadosG
o &signada de0initivamente despu)s de una expresi-n true. Este estado indica ?ue si la expresi-n booleana
se evalHa como true, v estar( asignada de0initivamente, pero si la expresi-n booleana se evalHa como
0alse, no tiene por ?u) estar asignada.
o &signada de0initivamente despu)s de una expresi-n 0alse. Este estado indica ?ue si la expresi-n
booleana se evalHa como 0alse, v estar( asignada de0initivamente, pero si la expresi-n booleana se
evalHa como true, no tiene por ?u) estar asignada.
8as reglas siguientes rigen la 0orma en la ?ue se determina el estado de una variable v en cada posici-n.
.3.3.1 /e"las "enerales para instrucciones
v no se asigna de0initivamente al principio del cuerpo de un miembro de 0unci-n.
v se asigna de0initivamente al principio de cual?uier instrucci-n inalcan1able.
1'6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
El estado de asignaci-n de0initiva de v al principio de cual?uier otra instrucci-n se determina mediante la
comprobaci-n del estado de asignaci-n de0initiva de v en todas las trans0erencias de 0lu$o de control ?ue
apunten al principio de esa instrucci-n. .i Oy s-lo en este casoR v se asigna de0initivamente en todas estas
trans0erencias de 0lu$o de control, v se asigna tambi)n de0initivamente al principio de la instrucci-n. El
con$unto de posibles trans0erencias de 0lu$o de control se determina del mismo modo ?ue en la
comprobaci-n del alcance de la instrucci-n O[8.1R.
El estado de asignaci-n de0initiva de v en el punto 0inal de una instrucci-n de blo?ue, c"ec(ed,
unc"ec(ed, i-, ,"ile, do, -or, -oreac", loc(, using o s,itc" se determina mediante la
comprobaci-n del estado de asignaci-n de0initiva de v en todas las trans0erencias de 0lu$o de control ?ue
apunten al punto 0inal de esa instrucci-n. .i v se asigna de0initivamente en todas estas trans0erencias de 0lu$o
de control, entonces v se asigna de0initivamente en el punto 0inal de la instrucci-n. 2e lo contrario, v no se
asigna de0initivamente en el punto 0inal de la instrucci-n. El con$unto de posibles trans0erencias de 0lu$o de
control se determina del mismo modo ?ue en la comprobaci-n del alcance de la instrucci-n O[8.1R.
.3.3.2 $nstrucciones de blo0ues e instrucciones c-ec1ed y unc-ec1ed
El estado de asignaci-n de0initiva de v en la trans0erencia de control a la primera instrucci-n de la lista de
instrucciones del blo?ue Oo al punto 0inal del blo?ue, si la lista de instrucciones est( vac5aR, es el mismo ?ue el
de la instrucci-n de asignaci-n de0initiva de v antes de la instrucci-n de blo?ue c"ec(ed o unc"ec(ed.
.3.3.3 $nstrucciones de e2presiones
'ara una instrucci-n de expresi-n st%t ?ue consta de la expresi-n e2prG
v tiene el mismo estado de asignaci-n de0initiva al principio de e2pr ?ue al principio de st%t.
.i v se asigna de0initivamente al 0inal de e2pr, tambi)n lo =ar( en el punto 0inal de st%tV de lo contrario, este
punto no recibir( tal asignaci-n.
.3.3.4 $nstrucciones de declaracin
.i st%t es una instrucci-n de declaraci-n sin iniciali1adores, entonces v tiene el mismo estado de asignaci-n
de0initiva en el punto 0inal de st%t ?ue al principio de st%t.
.i st%t es una instrucci-n de declaraci-n con iniciali1adores, el estado de asignaci-n de0initiva de v se
determina como si st%t 0uera una lista de instrucciones, con una instrucci-n de asignaci-n para cada
declaraci-n con un iniciali1ador Oen el orden de la declaraci-nR.
.3.3. $nstrucciones $3
'ara una instrucci-n i- st%t con la estructuraG
i- ( e2pr ) then-st%t else else-st%t
v tiene el mismo estado de asignaci-n de0initiva al principio de e2pr ?ue al principio de st%t.
.i v est( de0initivamente asignada al 0inal de e2pr, tambi)n lo estar( en la trans0erencia de 0lu$o de control a
then-st%t y a else-st%t, o bien al punto 0inal de st%t si no =ay cl(usula else.
.i v est( Pde0initivamente asignada despu)s de una expresi-n trueQ al 0inal de e2pr, entonces tambi)n lo
estar( en la trans0erencia de 0lu$o de control a then-st%tV si no =ay cl(usula else, no estar( de0initivamente
asignada en la trans0erencia de 0lu$o de control a else-st%t o al punto 0inal de st%t.
.i v tiene el estado Pde0initivamente asignada despu)s de expresi-n 0alseQ al 0inal de e2pr, entonces est(
de0initivamente asignada en la trans0erencia de 0lu$o de control a else-st%t y no lo est( a then-st%t en la
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1'(
Especificacin del lenguaje C#
trans0erencia de 0lu$o de control. Est( de0initivamente asignada al punto 0inal de st%t solamente si est(
tambi)n de0initivamente asignada al punto 0inal de then-st%t.
2e lo contrario, v se considera no asignada de0initivamente a then-st%t o a else-st%t en la trans0erencia de
0lu$o de control o, si no =ay cl(usula else, al punto 0inal de st%t.
.3.3.6 $nstrucciones !,itc-
En una instrucci-n s,itc", st%t con una expresi-n de control e2prG
El estado de asignaci-n de0initiva de v al principio de e2pr es el mismo ?ue el estado de v al principio de
st%t.
El estado de asignaci-n de0initiva de v en la trans0erencia de 0lu$o de control a una lista de instrucciones de
blo?ue s9itc= alcan1able es el mismo ?ue al 0inal de e2pr.
.3.3.# $nstrucciones 4-ile
'ara una instrucci-n ,"ile st%t con la siguiente estructuraG
,"ile ( e2pr ) while--od#
v tiene el mismo estado de asignaci-n de0initiva al principio de e2pr ?ue al principio de st%t.
.i v est( asignada de0initivamente al 0inal de e2pr, entonces est( de0initivamente asignada en la
trans0erencia de 0lu$o de control a while--od# y al punto 0inal de st%t.
.i el estado de v al 0inal de e2pr es Pde0initivamente asignada despu)s de una expresi-n trueQ, est(
de0initivamente asignada en la trans0erencia de 0lu$o de control a while--od#, pero no en el punto 0inal de
st%t.
.i el estado de v al 0inal de e2pr es Pde0initivamente asignada despu)s de una expresi-n 0alseQ, est(
de0initivamente asignada en la trans0erencia de 0lu$o de control al punto 0inal de st%t, pero no a while--od#
en la trans0erencia de 0lu$o de control.
.3.3.+ $nstrucciones (o
'ara una instrucci-n do st%t con la siguiente estructuraG
do do--od# ,"ile ( e2pr ) ;
v tiene el mismo estado de asignaci-n de0initiva en la trans0erencia de 0lu$o de control, desde el principio de
st%t a do--od#, ?ue al principio de st%t.
v tiene el mismo estado de asignaci-n de0initiva al principio de e2pr ?ue en el punto 0inal de do--od#.
.i v est( asignada de0initivamente al 0inal de e2pr, tambi)n lo est( en la trans0erencia de 0lu$o de control al
punto 0inal de st%t.
.i el estado de v al 0inal de e2pr es Pasignada de0initivamente despu)s de una expresi-n 0alseQ, entonces est(
de0initivamente asignada en la trans0erencia de 0lu$o de control al punto 0inal de st%t.
.3.3.5 $nstrucciones 6or
8a comprobaci-n de asignaci-n de0initiva de una instrucci-n -or con la estructura
-or ( for-initiali0er ; for-condition ; for-iterator ) e%-edded-state%ent
se reali1a como si la instrucci-n estuviera escrita de la siguiente 0ormaG
1'$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
{
for-initiali0er ;
,"ile ( for-condition ) {
e%-edded-state%ent ;
for-iterator ;
!
!
.i se omite la condici-n 0or Ofor-conditionR en la instrucci-n -or, la evaluaci-n o la asignaci-n de0initiva
continuar( como si se sustituyera la condici-n 0or por true en la expansi-n anterior.
.3.3.17 $nstrucciones 8rea1, Continue y 9oto
El estado de asignaci-n de0initiva de v en la trans0erencia de 0lu$o de control causada por una instrucci-n
brea(, continue o goto es el mismo ?ue el de v al principio de la instrucci-n.
.3.3.11 $nstrucciones :-ro,
'ara una instrucci-n st%t con la estructuraG
t"ro, e2pr ;
El estado de asignaci-n de0initiva de v al principio de e2pr es el mismo ?ue el de v al principio de st%t.
.3.3.12 $nstrucciones /eturn
'ara una instrucci-n st%t con la estructuraG
return e2pr ;
El estado de asignaci-n de0initiva de v al principio de e2pr es el mismo ?ue el de v al principio de st%t.
.i v es un par(metro de salida, debe asignarse de0initivamenteG
o despu)s de e2pr
o o bien al 0inal del blo?ue -inally de try=-inally o try=catc"=-inally ?ue incluya la
instrucci-n return.
'ara una instrucci-n st%t con la estructuraG
return ;
.i v es un par(metro de salida, debe asignarse de0initivamenteG
o antes de st%t
o o bien al 0inal del blo?ue -inally de try=-inally o try=catc"=-inally ?ue incluya la
instrucci-n return.
.3.3.13 $nstrucciones :ry;catc-
'ara una instrucci-n st%t con la estructuraG
try tr#--loc3
catc"(...) catch--loc3-1
...
catc"(...) catch--loc3-n
El estado de asignaci-n de0initiva de v al principio de tr#--loc3 es igual al de v al principio de st%t.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1'"
Especificacin del lenguaje C#
El estado de asignaci-n de0initiva de v al principio de catch--loc3-i Opara cual?uier iR es el mismo ?ue el de
v al principio de st%t.
El estado de asignaci-n de0initiva de v en el punto 0inal de st%t est( asignado de0initivamente si Oy s-lo siR
v est( de0initivamente asignada en el punto 0inal de tr#--loc3 y de todos los catch--loc3-i Opara cada i
de 1 a nR.
.3.3.14 $nstrucciones :ry;3inally
'ara una instrucci-n try st%t con la siguiente estructuraG
try tr#--loc3 -inally finall#--loc3
El estado de asignaci-n de0initiva de v al principio de tr#--loc3 es igual al de v al principio de st%t.
El estado de asignaci-n de0initiva de v al principio de finall#--loc3 es igual al de v al principio de st%t.
v estar( de0initivamente asignada en el punto 0inal de st%t si Oy s-lo siR al menos una de las siguientes
a0irmaciones es verdaderaG
o v est( asignada de0initivamente en el punto 0inal de tr#--loc3
o v est( asignada de0initivamente en el punto 0inal de finall#--loc3
.i se reali1a una trans0erencia de 0lu$o de control Opor e$emplo, una instrucci-n gotoR ?ue se inicia dentro de un
blo?ue try Otr#--loc3R y termina 0uera del blo?ue try, entonces v tambi)n se considerar( asignada
de0initivamente en esa trans0erencia de 0lu$o de control si tambi)n lo est( en el punto 0inal del blo?ue 0inally
Ofinall#--loc3R. OEsta condici-n no es exclusivaG si v est( asignada de0initivamente por otra ra1-n en esta
trans0erencia de 0lu$o de control, se considerar( asignada de0initivamenteR.
.3.3.1 $nstrucciones :ry;3inally;catc-
El an(lisis de asignaci-n de0initiva de una instrucci-n tryBcatc"B-inally con la estructuraG
try tr#--loc3
catc"(...) catch--loc3-1
...
catc"(...) catch--loc3-n
-inally finall#--loc3
se reali1a como si la instrucci-n 0uera una instrucci-n try=-inally ?ue incluyera una instrucci-n try=
catc"G
try {
try tr#--loc3
catc"(...) catch--loc3-1
...
catc"(...) catch--loc3-n
!
-inally finall#--loc3
El e$emplo siguiente demuestra c-mo a0ectan los di0erentes blo?ues de una instrucci-n try O[8.1"R a la
asignaci-n de0initiva.
11' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class '
{
static void V() {
int i j;
try {
goto L':)L;
.. neit"er i nor j de-initely assigned
i + 2;
.. i de-initely assigned
!
catc" {
.. neit"er i nor j de-initely assigned
i + 9;
.. i de-initely assigned
!
-inally {
.. neit"er i nor j de-initely assigned
j + K;
.. j de-initely assigned
!
.. i and j de-initely assigned
L':)L/;
.. j de-initely assigned
!
!
.3.3.16 $nstrucciones 6oreac-
'ara una instrucci-n -oreac" st%t con la siguiente estructuraG
-oreac" ( t#pe identificador in e2pr ) e%-edded-state%ent
El estado de asignaci-n de0initiva de v al principio de e2pr es el mismo ?ue el estado de v al principio
de st%t.
El estado de asignaci-n de0initiva de v en la trans0erencia de 0lu$o de control a una instrucci-n incrustada
Oe%-edded-state%entR o al punto 0inal de st%t es el mismo ?ue el estado de v al 0inal de e2pr.
.3.3.1# $nstrucciones <sin"
'ara una instrucci-n using st%t con la siguiente estructuraG
using ( resorce-ac6isition ) e%-edded-state%ent
El estado de asignaci-n de0initiva de v al principio de ad?uisici-n de recurso Oresorce-ac6isitionR es igual
al estado de v al principio de st%t.
El estado de asignaci-n de0initiva de v en la trans0erencia de 0lu$o de control a una instrucci-n incrustada
Oe%-edded-state%entR es igual al de v al 0inal de la ad?uisici-n de recurso Oresorce-ac6isitionR.
.3.3.1+ $nstrucciones *oc1
'ara una instrucci-n loc( st%t con la siguiente estructuraG
loc( ( e2pr ) e%-edded-state%ent
El estado de asignaci-n de0initiva de v al principio de e2pr es el mismo ?ue el estado de v al principio
de st%t.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 111
Especificacin del lenguaje C#
El estado de asignaci-n de0initiva de v en la trans0erencia de 0lu$o de control a una instrucci-n incrustada
Oe%-edded-state%entR es igual ?ue el estado de v al 0inal de la expresi-n Oe2prR.
.3.3.15 $nstrucciones yield
'ara una instrucci-n yield return st%t con la estructuraG
yield return e2pr ;
El estado de asignaci-n de0initiva de v al principio de e2pr es el mismo ?ue el estado de v al principio de
st%t.
El estado de asignaci-n de0initiva de v al principio de st%t es el mismo ?ue el estado de v al principio de
e2pr.
7na instrucci-n yield brea( no tiene ningHn e0ecto sobre el estado de asignaci-n de0initiva.
.3.3.27 /e"las "enerales para e2presiones simples
8a siguiente regla se aplica a estos tipos de expresionesG literales O[*..1R, nombres simples O[*..2R,
expresiones de acceso a miembros O[*..4R, expresiones de acceso a bases no indi1adas O[*..8R, expresiones
ty&eo- O[*..11R y expresiones de valor predeterminadas O[*..13R.
El estado de asignaci-n de0initiva de v al 0inal de una expresi-n de este tipo es igual ?ue el de v al principio
de la expresi-n.
.3.3.21 /e"las "enerales para e2presiones con e2presiones incrustadas
8as reglas siguientes se aplican a estos tipos de expresionesG expresiones entre par)ntesis O[*..3R, expresiones
de acceso a elementos O[*..#R, expresiones de acceso a bases con indi1aci-n O[*..8R, expresiones de
incremento y decremento O[*..+, [*.#.R, expresiones de conversi-n de tipos O[*.#.#R, expresiones unarias <, =,
A, >, expresiones binarias <, =, >, ., B, DD, EE, D, D+, E, E+, ++, @+, is, as, F, H, G O[*.*, [*.8, [*.+, [*.1"R,
expresiones de asignaci-n compuestas O[*.1#.2R, expresiones c"ec(ed y unc"ec(ed O[*..12R, y expresiones
de creaci-n de matrices y de delegados O[*..1"R.
Cada una de estas expresiones tiene una o m(s subexpresiones ?ue se evalHan incondicionalmente en un orden
0i$o. 'or e$emplo, el operador binario B evalHa el lado i1?uierdo del operador y, a continuaci-n, el lado derec=o.
7na operaci-n de indi1aci-n evalHa la expresi-n indi1ada y, a continuaci-n, cada una de las expresiones de
5ndice por orden, de i1?uierda a derec=a. 'ara una expresi-n e2pr ?ue tiene las subexpresiones e2pr1, e2pr2, ...,
e2prn, evaluadas en ese ordenG
El estado de asignaci-n de0initiva de v al principio de e2pr1 es igual ?ue el estado de asignaci-n de0initiva al
principio de e2pr.
El estado de asignaci-n de0initiva de v al principio de e2pri Osiendo i mayor ?ue unoR es igual ?ue el estado
al 0inal de e2pr
i-1
.
El estado de asignaci-n de0initiva de v al principio de e2pr es igual ?ue el estado al 0inal de e2pr
n
.
.3.3.22 &2presiones de invocacin y e2presiones de creacin de ob=etos
'ara una expresi-n de invocaci-n e2pr con la estructuraG
pri%ar#-e2pression ( ar&
1
ar&
2
b ar&
n
)
o una expresi-n de creaci-n de ob$eto con la estructuraG
ne, t#pe ( ar&
1
ar&
2
b ar&
n
)
112 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
'ara una expresi-n de invocaci-n, el estado de asignaci-n de0initiva de v antes de la expresi-n primaria
Opri%ar#-e2pressionR es igual ?ue el estado de v antes de e2pr.
'ara una expresi-n de invocaci-n, el estado de asignaci-n de0initiva de v antes de ar&
1
es igual ?ue el estado
de v despu)s de la expresi-n primaria Opri%ar#-e2pressionR.
'ara una expresi-n de creaci-n de ob$eto, el estado de asignaci-n de0initiva de v antes de ar&
1
es igual ?ue
el estado de v antes de e2pr.
'ara cada argumento ar&
i
, el estado de asignaci-n de0initiva de v despu)s de ar&
i
est( determinado por las
reglas de expresi-n normales omitiendo los modi0icadores re- u out.
'ara cada argumento arg
i
, siendo i mayor ?ue uno, el estado de asignaci-n de0initiva de v antes de ar&
i
es el
mismo ?ue el de v despu)s de ar&
i-1
.
.i se pasa la variable v como un argumento out Oes decir, un argumento de 0orma ^out v^R en cual?uiera de
los argumentos, el estado de v despu)s de e2pr se asigna de0initivamente. 2e lo contrario, el estado de v
despu)s de e2pr es el mismo ?ue el estado de v despu)s de ar&
n
.
'ara los iniciali1adores de matri1 O[*..1".4R, iniciali1adores de ob$etos O[*..1".2R, iniciali1adores de
colecci-n O[*..1".3R e iniciali1adores de ob$etos an-nimos O[*..1".#R, el estado de asignaci-n de0initiva
est( determinado por la expansi-n en cuyos t)rminos est(n de0inidos estos constructores.
.3.3.23 &2presiones de asi"nacin simples
'ara una expresi-n e2pr con la estructura w + e2pr-rhsG
El estado de asignaci-n de0initiva de v antes de e2pr-rhs es igual ?ue el de v antes de e2pr.
.i w es la misma variable ?ue v, el estado de asignaci-n de0initiva de v despu)s de e2pr se asigna
de0initivamente. 2e lo contrario, el estado de asignaci-n de0initiva de v despu)s de e2pr ser( igual ?ue el de
v despu)s de e2pr-rhs.
.3.3.24 &2presiones >>
'ara una expresi-n e2pr con la estructura e2pr-first FF e2pr-secondG
El estado de asignaci-n de0initiva de v antes de e2pr-first es igual ?ue el de v antes de e2pr.
El estado de asignaci-n de0initiva de v antes de la segunda expresi-n Oe2pr-secondR se asigna
de0initivamente, si el estado de v despu)s de la primera expresi-n Oe2pr-firstR se asigna de0initivamente o es
Pasignado de0initivamente despu)s de una expresi-n trueQ. En cual?uier otro caso, no se asigna
de0initivamente.
El estado de asignaci-n de0initiva de v despu)s de e2pr se determina de la siguiente 0ormaG
o .i el estado de v despu)s de e2pr-first se asigna de0initivamente, tambi)n lo =ar( el estado de v despu)s
de e2pr.
o 2e lo contrario, si el estado de v despu)s de la segunda expresi-n Oe2pr-secondR se asigna
de0initivamente, y el estado de v despu)s de la primera expresi-n Oe2pr-firstR es Pasignado
de0initivamente despu)s de una expresi-n 0alseQ, entonces el estado de v despu)s de la expresi-n Oe2prR
se asigna de0initivamente.
o 2e lo contrario, si el estado de v despu)s de la segunda expresi-n Oe2pr-secondR se asigna
de0initivamente o es Pasignado de0initivamente despu)s de expresi-n trueQ, entonces el estado de v
despu)s de la expresi-n Oe2prR es Pasignado de0initivamente despu)s de una expresi-n trueQ.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 113
Especificacin del lenguaje C#
o 2e lo contrario, si el estado de v despu)s de la primera expresi-n Oe2pr-firstR es Pasignado
de0initivamente despu)s de una expresi-n 0alseQ y el estado de v despu)s de segunda expresi-n Oe2pr-
secondR es Pasignado de0initivamente despu)s de una expresi-n 0alseQ, entonces el estado de v despu)s
de la expresi-n Oe2prR es Pasignado de0initivamente despu)s de una expresi-n 0alseQ.
o 2e lo contrario, el estado de v despu)s de e2pr no se asignar( de0initivamente.
En el e$emplo
class '
{
static void V(int # int y) {
int i;
i- (# E+ 3 FF (i + y) E+ 3) {
.. i de-initely assigned
!
else {
.. i not de-initely assigned
!
.. i not de-initely assigned
!
!
la variable i se considera asignada de0initivamente en una de las instrucciones incrustadas de una instrucci-n i-
pero no en la otra. En la instrucci-n i- del m)todo V, la variable i est( asignada de0initivamente en la primera
instrucci-n incrustada por?ue la e$ecuci-n de la expresi-n (i + y) siempre precede a la e$ecuci-n de esta
instrucci-n incrustada. 'or el contrario, la variable i no est( asignada de0initivamente en la segunda instrucci-n
incrustada, puesto ?ue # E+ 3 podr5a dar como resultado 0alse y =acer ?ue la variable i no se asignara.
.3.3.2 &2presiones ??
'ara una expresi-n e2pr con la estructura e2pr-first HH e2pr-secondG
El estado de asignaci-n de0initiva de v antes de e2pr-first es igual ?ue el de v antes de e2pr.
El estado de asignaci-n de0initiva de v antes de la segunda expresi-n Oe2pr-secondR se asigna
de0initivamente si el estado de v despu)s de la primera expresi-n Oe2pr-firstR se asigna de0initivamente o es
Pasignado de0initivamente despu)s de una expresi-n 0alseQ. En cual?uier otro caso, no se asigna
de0initivamente.
8a instrucci-n de asignaci-n de0initiva de v despu)s de e2pr se determina de la siguiente 0ormaG
o .i el estado de v despu)s de e2pr-first se asigna de0initivamente, tambi)n lo =ar( el estado de v despu)s
de e2pr.
o 2e lo contrario, si el estado de v despu)s de la segunda expresi-n Oe2pr-secondR se asigna
de0initivamente, y el estado de v despu)s de la primera expresi-n Oe2pr-firstR es Pasignado
de0initivamente despu)s de una expresi-n trueQ, entonces el estado de v despu)s de e2pr se asignar(
de0initivamente.
o 2e lo contrario, si el estado de v despu)s de la segunda expresi-n Oe2pr-secondR se asigna
de0initivamente o es Pasignado de0initivamente despu)s de una expresi-n 0alseQ, entonces el estado de v
despu)s de la expresi-n Oe2prR es Pasignado de0initivamente despu)s de una expresi-n 0alseQ.
o 2e lo contrario, si el estado de v despu)s de la primera expresi-n Oe2pr-firstR es Pasignado
de0initivamente despu)s de una expresi-n trueQ, y el estado de v despu)s de la segunda expresi-n
Oe2pr-secondR es Pasignado de0initivamente despu)s de una expresi-n trueQ, entonces el estado de v
despu)s de e2pr es Pasignado de0initivamente despu)s de una expresi-n trueQ.
o 2e lo contrario, el estado de v despu)s de e2pr no se asignar( de0initivamente.
11# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En el e$emplo
class '
{
static void S(int # int y) {
int i;
i- (# E+ 3 HH (i + y) E+ 3) {
.. i not de-initely assigned
!
else {
.. i de-initely assigned
!
.. i not de-initely assigned
!
!
la variable i se considera asignada de0initivamente en una de las instrucciones incrustadas de una instrucci-n i-
pero no en la otra. En la instrucci-n i- del m)todo S, la variable i est( asignada de0initivamente en la segunda
instrucci-n incrustada por?ue la e$ecuci-n de la expresi-n (i + y) siempre precede a la e$ecuci-n de esta
instrucci-n incrustada. 'or el contrario, la variable i no est( asignada de0initivamente en la primera instrucci-n
incrustada, puesto ?ue # E+ 3 podr5a dar como resultado true y =ace ?ue la variable i no se asigne.
.3.3.26 &2presiones @
'ara una expresi-n e2pr con la estructura @ e2pr-operandG
El estado de asignaci-n de0initiva de v antes de e2pr-operand es igual ?ue el estado de asignaci-n de0initiva
de v antes de e2pr.
El estado de asignaci-n de0initiva de v despu)s de e2pr se determina de la siguiente 0ormaG
o .i el estado de v despu)s de e2pr-operand se asigna de0initivamente, el estado de v despu)s de e2pr se
asigna de0initivamente.
o .i el estado de v despu)s de e2pr-operand no se asigna de0initivamente, el estado de v despu)s de e2pr
no se asigna de0initivamente.
o .i el estado de v despu)s del operando de la expresi-n Oe2pr-operand5 es Pasignado de0initivamente
despu)s de una expresi-n 0alseQ, entonces el estado de v despu)s de la expresi-n Oe2prR es Pasignado
de0initivamente despu)s de una expresi-n trueQ.
o .i el estado de v despu)s del operando de la expresi-n Oe2pr-operand5 es Pasignado de0initivamente
despu)s de una expresi-n trueQ, entonces el estado de v despu)s de la expresi-n Oe2prR es Pasignado
de0initivamente despu)s de una expresi-n 0alseQ.
.3.3.2# &2presiones AA
'ara una expresi-n e2pr con la estructura e2pr-first 77 e2pr-secondG
El estado de asignaci-n de0initiva de v antes de e2pr-first es igual ?ue el de v antes de e2pr.
El estado de asignaci-n de0initiva de v antes de e2pr-second es el mismo ?ue el de v despu)s de e2pr-first.
8a instrucci-n de asignaci-n de0initiva de v despu)s de e2pr se determina de la siguiente 0ormaG
o .i e2pr-first es una expresi-n constante O[*.18R con valor null, entonces el estado de v despu)s de la
expresi-n Oe2prR es el mismo ?ue el estado de v despu)s de e2pr-second.
2e lo contrario, el estado v despu)s de e2pr ser( igual ?ue el estado de asignaci-n de0initiva de v despu)s de
e2pr-first.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 11!
Especificacin del lenguaje C#
.3.3.2+ &2presiones AB
'ara una expresi-n e2pr con la estructura e2pr-cond 7 e2pr-tre / e2pr-falseG
El estado de asignaci-n de0initiva de v antes de e2pr-cond es igual al estado de v antes de e2pr.
El estado de asignaci-n de0initiva de v antes de la expresi-n para true Oe2pr-treR se asigna de0initivamente
solamente en el caso de ?ue el estado de v despu)s de la expresi-n condicional Oe2pr-cond5 se asigne
de0initivamente o sea Pasignado de0initivamente despu)s de una expresi-n trueQ.
El estado de asignaci-n de0initiva de v antes de la expresi-n para 0alse Oe2pr-false5 se asigna de0initivamente
solamente en el caso de ?ue el estado de v despu)s de la expresi-n condicional Oe2pr-cond5 se asigne
de0initivamente o sea Pasignado de0initivamente despu)s de una expresi-n 0alseQ.
El estado de asignaci-n de0initiva de v despu)s de e2pr se determina de la siguiente 0ormaG
o .i la expresi-n condicional Oe2pr-condR es una expresi-n constante O[R con valor true, entonces el
estado de v despu)s de la expresi-n Oe2prR es el mismo ?ue el estado de v despu)s de la expresi-n para
true Oe2pr-treR.
o 2e lo contrario, si la expresi-n condicional Oe2pr-condR es una expresi-n constante O[*.18R con valor
-alse, entonces el estado de v despu)s de la expresi-n Oe2prR es el mismo ?ue el estado de v despu)s de
la expresi-n para 0alse Oe2pr-falseR.
o 2e lo contrario, si el estado de v despu)s de e2pr-tre y el estado de v despu)s de e2pr-false se asignan
de0initivamente, entonces el estado de v despu)s de e2pr tambi)n se asignar( de0initivamente.
o 2e lo contrario, el estado de v despu)s de e2pr no se asignar( de0initivamente.
.3.3.25 6unciones annimas
'ara una expresi-n lambda Ola%-da-e2pressionR o una expresi-n de m)todo an-nimo Oanon#%os-%ethod-
e2pression e2prR con un cuerpo Oya sea -loc3 o e2pressionR -od#G
El estado de asignaci-n de0initiva de una variable externa v antes del cuerpo O-od#R es igual ?ue el estado de
v antes de e2pr. Es decir, el estado de asignaci-n de0initiva de variables externas se =ereda desde el contexto
de la 0unci-n an-nima.
El estado de asignaci-n de0initiva de una variable externa v despu)s de e2pr ser( igual ?ue el estado de v
antes de e2pr.
En el e$emplo
delegate bool Vilter(int i);
void V() {
int ma#;
.. )rror ma# is not de-initely assigned
Vilter - + (int n) +E n D ma#;
ma# + K;
6oWor((-);
!
se genera un error en tiempo de compilaci-n ya ?ue ma# no se asigna de manera de0initiva donde se declara la
0unci-n an-nima. En el e$emplo
delegate void 6();
void V() {
int n;
6 d + () +E { n + 2; !;
116 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
d();
.. )rror n is not de-initely assigned
Console.WriteLine(n);
!
tambi)n se genera un error en tiempo de compilaci-n puesto ?ue la asignaci-n a n en la 0unci-n an-nima no
a0ecta al estado de asignaci-n de0initivo de n 0uera de la 0unci-n an-nima.
#.! 9eferencias de ariables
7na re0erencia de variable Ovaria-le-referenceR es una expresi-n Oe2pressionR ?ue se clasi0ica como una
variable. 7na re0erencia de variable Ovaria-le-referenceR es una ubicaci-n de almacenamiento a la ?ue se puede
obtener acceso, tanto para obtener el valor actual, como para almacenar un valor nuevo.
varia-le-reference1
e2pression
En C y CSS, una re0erencia de variable Ovaria-le-referenceR se conoce como lvale.
#.# 'tomicidad de las referencias de ariable
8as lecturas y escrituras de los siguientes tipos de datos son at-micasG bool, c"ar, byte, sbyte, s"ort,
us"ort, uint, int, -loat y tipos de re0erencia. &dem(s, las lecturas y escrituras de tipos enum cuyo tipo
subyacente est( en la lista anterior son tambi)n at-micas. 4o se garanti1a ?ue las lecturas y escrituras de otros
tipos Ocomo long, ulong, double o decimal, as5 como los tipos de0inidos por el usuarioR sean at-micas.
&parte de las 0unciones de biblioteca diseUadas para este prop-sito, no =ay garant5a de lectura, modi0icaci-n ni
escritura at-micas, como en el caso de incrementos o decrementos.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 11(
Especificacin del lenguaje C#
$. %onersiones
7na conversi,n permite ?ue una expresi-n sea tratada como parte de un tipo determinado. 7na conversi-n
puede =acer ?ue una expresi-n de un tipo dado sea tratada como si tuviera un tipo di0erente, o ?ue una expresi-n
sin un tipo lo consiga. 8as conversiones pueden ser iplcitas o e.plcitas, y esto determina si se re?uiere una
conversi-n de tipo expl5cita. 'or e$emplo, la conversi-n del tipo int al tipo long es impl5cita, por lo ?ue las
expresiones de tipo int pueden tratarse impl5citamente como del tipo long. 8a conversi-n opuesta, del tipo
long a int, es expl5cita y, por ello, se re?uiere una conversi-n expl5cita.
int a + 289;
long b + a; .. im&licit conversion -rom int to long
int c + (int) b; .. e#&licit conversion -rom long to int
&lgunas conversiones est(n de0inidas por el lengua$e. 8os programas tambi)n pueden de0inir sus propias
conversiones O[#.4R.
$.1 %onersiones impl2citas
8as siguientes conversiones se clasi0ican como conversiones impl5citasG
Conversiones de identidad
Conversiones num)ricas impl5citas
Conversiones de enumeraci-n impl5citas
Conversiones impl5citas ?ue aceptan valores 4788
Conversiones de literal 4788
Conversiones de re0erencia impl5citas
Conversiones boxing
Conversiones impl5citas de expresi-n constante
Conversiones de0inidas por el usuario impl5citas
Conversiones de 0unci-n an-nima
Conversiones de grupo de m)todos
8as conversiones impl5citas pueden ocurrir en distintas situaciones, incluyendo las invocaciones de miembros de
0unci-n O[*.4.4R, las expresiones de conversi-n O[*.#.#R y las asignaciones O[*.1#R.
8as conversiones impl5citas prede0inidas siempre tienen )xito y nunca causan excepciones. 8as conversiones
impl5citas de0inidas por el usuario correctamente diseUadas tambi)n deben ex=ibir estas caracter5sticas.
$.1.1 %onersiones de identidad
7na conversi-n de identidad convierte de cual?uier tipo al mismo tipo. Esta conversi-n existe solamente para
?ue una entidad ?ue ya sea de un tipo re?uerido pueda considerarse convertible a dic=o tipo.
$.1.2 %onersiones num*ricas impl2citas
8as conversiones impl5citas num)ricas sonG
11$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
2e sbyte a s"ort, int, long, -loat, double o decimal.
2e byte a s"ort, us"ort, int, uint, long, ulong, -loat, double o decimal.
2e s"ort a int, long, -loat, double o decimal.
2e us"ort a int, uint, long, ulong, -loat, double o decimal.
2e int a long, -loat, double o decimal.
2e uint a long, ulong, -loat, double o decimal.
2e long a -loat, double o decimal.
2e ulong a -loat, double o decimal.
2e c"ar a us"ort, int, uint, long, ulong, -loat, double o decimal.
2e -loat a double.
8as conversiones de int, uint, long o ulong a ulong o -loat y de long o ulong a double pueden
producir una p)rdida de precisi-n, pero no una p)rdida de magnitud. En las dem(s conversiones impl5citas
num)ricas nunca se pierde in0ormaci-n.
4o =ay conversiones impl5citas al tipo c"ar, por tanto los valores de otros tipos integrales no se convierten
autom(ticamente al tipo c"ar.
$.1.3 %onersiones de enumeracin impl2citas
7na conversi-n de enumeraci-n impl5cita permite convertir el literal entero decimal Odeci%al-inte&er-literalR 3
al tipo enum Oen%-t#peR y a cual?uier tipo ?ue acepte valores 4788 Onlla-le-t#peR cuyo tipo subyacente sea
enum Oen%-t#peR. En este Hltimo caso, la conversi-n se evalHa mediante la conversi-n al tipo enum Oen%-
t#peR subyacente y el a$uste del resultado O[4.1.1"R.
$.1.! %onersiones impl2citas ;ue aceptan alores 1566
8as conversiones impl5citas prede0inidas ?ue 0uncionan en tipos de valores ?ue no aceptan valores 4788
tambi)n se pueden utili1ar con 0ormas ?ue aceptan valores 4788 de dic=os tipos. 'ara cada una de las
conversiones num)ricas y de identidad impl5citas ?ue se convierten de un tipo de valor S ?ue no acepta valores
4788 a un tipo de valor 1 ?ue no acepta valores 4788, existen las siguientes conversiones impl5citas ?ue
aceptan valores 4788G
7na conversi-n impl5cita desde S7 a 17.
7na conversi-n impl5cita de S a 17.
8a evaluaci-n de una conversi-n impl5cita ?ue acepta valores 4788 basada en una conversi-n subyacente de S
a 1 se reali1a de la siguiente maneraG
.i la conversi-n ?ue acepta valores 4788 se reali1a de S7 a 17G
o .i el valor de origen es 4788 Ola propiedad HasUalue es 0alsaR, el resultado es el valor 4788 del
tipo 17.
o 2e lo contrario, la conversi-n se evalHa como un desa$uste de S7 a S, seguido de la conversi-n
subyacente de S a 1, seguido de un a$uste O[4.1.1"R de 1 a 17.
.i la conversi-n ?ue acepta valores 4788 se reali1a de S a 17, la conversi-n se evalHa como la conversi-n
subyacente de S a 1 seguida de un a$uste de 1 a 17.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 11"
Especificacin del lenguaje C#
$.1.# %onersiones de literal 1566
Existe una conversi-n impl5cita desde el literal null a cual?uier tipo ?ue acepte valores 4788. Esta conversi-n
genera el valor 4788 O[4.1.1"R del tipo ?ue admite valores 4788.
$.1.$ %onersiones de referencia impl2citas
8as conversiones impl5citas de re0erencia sonG
2e cual?uier tipo de re0erencia Oreference-t#peR a object.
2e cual?uier tipo de clase Oclass-t#peR S a cual?uier tipo de clase 1, a condici-n de ?ue S se derive de 1.
2e cual?uier tipo de clase Oclass-t#peR S a cual?uier tipo de inter0a1 Ointerface-t#peR 1, a condici-n de ?ue S
implemente a 1.
2e cual?uier tipo de inter0a1 Ointerface-t#peR S a cual?uier tipo de inter0a1 1, a condici-n de ?ue S se derive
de 1.
2e un tipo de matri1 Oarra#-t#peR S con un tipo de elemento S) a un tipo de matri1 1 con un tipo de
elemento 1), siempre ?ue se cumpla todo lo siguienteG
o S y 1 di0ieren solamente en el tipo de elemento. Esto es, S y 1 tienen el mismo nHmero de dimensiones.
o Tanto S) como 1) son tipos de re0erencia Oreference-t#pesR.
o Existe una conversi-n impl5cita de re0erencia de S) a 1).
2esde cual?uier tipo de matri1 Oarra#-t#peR a System.'rray y las inter0aces ?ue implementa.
2esde un tipo de matri1 unidimensional S45 a System.Collections.Seneric.$ListD1E y sus
inter0aces base, siempre ?ue =aya una identidad impl5cita o una conversi-n de re0erencia de S a 1.
2esde cual?uier tipo delegado Odele&ate-t#peR a System.6elegate y las inter0aces ?ue implementa.
2el literal nulo a cual?uier tipo de re0erencia Oreference-t#peR.
Conversiones impl5citas ?ue impli?uen par(metros de tipo ?ue se sabe ?ue son tipos de re0erencia. >ea la
secci-n [ para obtener m(s datos acerca de las conversiones impl5citas ?ue implican par(metros de tipo.
8as conversiones impl5citas de re0erencia son a?uellas entre tipos de re0erencia Oreference-t#pesR ?ue se puede
demostrar ?ue siempre se reali1an correctamente y, por lo tanto, no re?uieren comprobaciones en tiempo de
e$ecuci-n.
8as conversiones de re0erencia, tanto impl5citas como expl5citas, nunca cambian la identidad re0erencial del
ob$eto ?ue se convierte. Es decir, si bien una conversi-n de re0erencia puede cambiar el tipo de la re0erencia,
nunca cambia el tipo o el valor del ob$eto al ?ue se re0iere.
&l contrario de lo ?ue ocurre con los tipos de matrices, los tipos de re0erencia construidos no muestran
conversiones PcovariantesQ. Esto signi0ica ?ue un tipo ListD:E no tiene conversi-n Oya sea impl5cita o
expl5citaR a ListD'E incluso si : deriva de '. 2e manera similar, no existe una conversi-n de ListD:E a
ListDobjectE.
$.1.+ %onersiones bo"ing
7na conversi-n boxing permite ?ue un tipo de valor Ovale-t#peR se convierta impl5citamente en un tipo de
re0erencia. Existe una conversi-n boxing de cual?uier tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-
vale-t#peR al tipo object, a System.Ualue1y&e, y a cual?uier tipo de inter0a1 Ointerface-t#peR
implementado por el tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR. Es m(s, un tipo enum
Oen%-t#peR se puede convertir al tipo System.)num.
12' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Existe una conversi-n boxing de cual?uier tipo de valor ?ue acepta valores 4788 Onlla-le-vale-t#peR a un
tipo de re0erencia, si y s-lo si existe una conversi-n boxing del tipo de valor ?ue no acepta valores 4788 Onon-
nlla-le-vale-t#peR subyacente al tipo de re0erencia.
8a conversi-n boxing de un tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR consiste en
asignar una instancia del ob$eto y despu)s copiar el tipo de valorOvale-t#peR en esa instancia. .e puede aplicar a
una estructura la conversi-n boxing al tipo System.Ualue1y&e, puesto ?ue )sa es una clase base para todas las
estructuras O[11.3.2R.
7na conversi-n boxing desde un tipo ?ue acepta valores 4788 Onlla-le-t#peR se procesa de la siguiente
maneraG
.i el valor de origen es 4788 Ola propiedad HasUalue es 0alsaR, el resultado es una re0erencia 4788 del
tipo de destino.
2e lo contrario, el resultado es una re0erencia a un tipo 1 producido por el desa$uste y la conversi-n boxing
del valor de origen.
8as conversiones boxing se describen m(s detalladamente en [4.3.1.
$.1.- %onersiones impl2citas de e"presin constante
7na conversi-n impl5cita de expresi-n constante permite las siguientes conversionesG
7na expresi-n constante Oconstant-e2pressionR O[*.18R de tipo int se puede convertir al tipo sbyte, byte,
s"ort, us"ort, uint o ulong, siempre ?ue el valor de la expresi-n constante Oconstant-e2pressionR ?uede
dentro del intervalo del tipo de destino.
7na expresi-n constante Oconstant-e2pressionR de tipo long se puede convertir al tipo ulong, a condici-n
de ?ue el valor de la expresi-n constante no sea negativo.
$.1.. %onersiones impl2citas con par)metros de tipo
'ara un par(metro de tipo 1 dado, existen las siguientes conversiones impl5citasG
2esde 1 a su clase base e0ectiva C, desde 1 a cual?uier clase base de C, y desde 1 a cual?uier inter0a1
implementada por C. En tiempo de e$ecuci-n, si 1 es un tipo de valor, la conversi-n se e$ecuta como una
conversi-n boxing. 2e lo contrario, la conversi-n se e$ecuta como una conversi-n de re0erencia impl5cita o
una conversi-n de identidad.
2esde 1 a un tipo de inter0a1 en el con$unto de inter0aces e0ectivas de 1, y desde 1 a cual?uier inter0a1 base
de $. En tiempo de e$ecuci-n, si 1 es un tipo de valor, la conversi-n se e$ecuta como una conversi-n boxing.
2e lo contrario, la conversi-n se e$ecuta como una conversi-n de re0erencia impl5cita o una conversi-n de
identidad.
2esde 1 a un par(metro de tipo ;, siempre ?ue 1 dependa de ; O[1".1.R. En tiempo de e$ecuci-n, si ; es un
tipo de valor, entonces 1 y ; son necesariamente el mismo tipo y no se reali1a una conversi-n boxing. 2e lo
contrario, si 1 es un tipo de re0erencia, ; tambi)n lo es y la conversi-n se e$ecuta como una conversi-n de
re0erencia impl5cita o una conversi-n de identidad.
2esde el literal nulo a 1, siempre y cuando 1 sea un tipo de re0erencia.
.i 1 es un tipo de re0erencia O[1".1.R, todas las conversiones anteriores se clasi0ican como conversiones de
re0erencia impl5citas O[R. .i 1 no es un tipo de re0erencia, las conversiones anteriores se clasi0ican como
conversiones boxing O[R.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 121
Especificacin del lenguaje C#
$.1.10 %onersiones definidas por el usuario impl2citas
7na conversi-n impl5cita de0inida por el usuario consta de una conversi-n impl5cita opcional est(ndar, seguida
por la e$ecuci-n de un operador de conversi-n impl5cita de0inido por el usuario, seguido por otra conversi-n
impl5cita opcional est(ndar. 8as reglas exactas para la evaluaci-n de conversiones impl5citas de0inidas por el
usuario se describen en [#.4.4.
$.1.11 %onersiones de funcin annima y conersiones de grupo de m*todos
8as 0unciones an-nimas y los grupos de m)todos no tienen tipos de por s5, pero se pueden convertir
impl5citamente en tipos delegados o tipos de (rbol de expresiones. 8as conversiones de 0unci-n an-nima y las
conversiones de grupo de m)todos se describen en m(s detalle en la secci-n [#..
$.2 %onersiones e"pl2citas
8as siguientes conversiones se clasi0ican como conversiones expl5citasG
Todas las conversiones impl5citas.
Conversiones expl5citas num)ricas.
Conversiones expl5citas de enumeraci-n.
Conversiones expl5citas ?ue aceptan valores 4788.
Conversiones expl5citas de re0erencia.
Conversiones expl5citas de inter0a1.
Conversiones 7nboxing.
Conversiones expl5citas de0inidas por el usuario.
8as conversiones expl5citas pueden producirse en las expresiones de conversi-n de tipos O[*.#.#R.
El con$unto de conversiones expl5citas incluye todas las conversiones impl5citas. Esto ?uiere decir ?ue est(n
permitidas las expresiones de conversi-n de tipos redundantes.
8as conversiones expl5citas son conversiones ?ue no se puede demostrar ?ue siempre se reali1an correctamente,
conversiones en las ?ue se sabe ?ue se puede producir p)rdida de in0ormaci-n y conversiones en dominios de
tipos ?ue, por sus di0erencias, merecen una menci-n expl5cita.
$.2.1 %onersiones e"pl2citas num*ricas
8as conversiones num)ricas expl5citas son las conversiones de un tipo num)rico On%eric-t#peR a otro tipo
num)rico para el ?ue no existe ya una conversi-n de tipo num)rico impl5cita O[#.1.2RG
2e sbyte a byte, us"ort, uint, ulong o c"ar.
2e byte a sbyte y c"ar.
2e s"ort a sbyte, byte, us"ort, uint, ulong o c"ar.
2e us"ort a sbyte, byte, s"ort o c"ar.
2e int a sbyte, byte, s"ort, us"ort, uint, ulong o c"ar.
2e uint a sbyte, byte, s"ort, us"ort, int o c"ar.
2e long a sbyte, byte, s"ort, us"ort, int, uint, ulong o c"ar.
2e ulong a sbyte, byte, s"ort, us"ort, int, uint, long o c"ar.
122 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
2e c"ar a sbyte, byte o s"ort.
2e -loat a sbyte, byte, s"ort, us"ort, int, uint, long, ulong, c"ar o decimal.
2e double a sbyte, byte, s"ort, us"ort, int, uint, long, ulong, c"ar, -loat o decimal.
2e decimal a sbyte, byte, s"ort, us"ort, int, uint, long, ulong, c"ar, -loat o double.
2ado ?ue las conversiones expl5citas incluyen todas las conversiones num)ricas impl5citas y expl5citas, siempre
es posible convertir de cual?uier tipo num)rico On%eric-t#peR a cual?uier otro tipo num)rico mediante una
expresi-n de conversi-n de tipos O[*.#.#R.
8as conversiones expl5citas num)ricas pueden producir p)rdida de in0ormaci-n o incluso provocar excepciones.
7na conversi-n expl5cita num)rica se procesa como se explica a continuaci-nG
'ara una conversi-n de un tipo integral a otro tipo integral, el procesamiento depende del contexto de
comprobaci-n de desbordamiento O[*..12R en el ?ue tiene lugar la conversi-nG
o En un contexto c"ec(ed, la conversi-n termina correctamente si el valor del operando de origen ?ueda
dentro del intervalo del tipo de destino, pero inicia una excepci-n System.%ver-lo,)#ce&tion si
?ueda 0uera de dic=o intervalo.
o En un contexto unc"ec(ed, la conversi-n siempre termina correctamente y se procesa como sigue.
.i el tipo de origen es mayor ?ue el de destino, el valor de origen se trunca descartando sus bits
PextraQ m(s signi0icativos. 2espu)s el resultado se trata como un valor del tipo de destino.
.i el tipo de origen es menor ?ue el tipo de destino, el valor de origen se ampl5a con un signo o con
ceros, de 0orma ?ue tenga el mismo tamaUo ?ue el tipo de destino. 8a ampliaci-n con signo se
utili1a si el tipo de origen tiene signoV se utili1a la ampliaci-n con ceros si el tipo de origen no lleva
signo. 2espu)s el resultado se trata como un valor del tipo de destino.
.i el tipo del origen tiene el mismo tamaUo ?ue el tipo de destino, el valor de origen se trata como
un valor del tipo de destino.
Cuando se convierte un valor de tipo decimal a un tipo integral, el valor de origen se redondea =acia cero
=asta el valor entero m(s pr-ximo, y este valor integral pasa a ser el resultado de la conversi-n. .i el valor
integral resultante ?ueda 0uera del intervalo del tipo de destino, se produce una excepci-n
System.%ver-lo,)#ce&tion.
'ara la conversi-n de un tipo -loat o double a otro tipo integral, el procesamiento depende del contexto
de comprobaci-n de desbordamiento O[*..12R en el ?ue tiene lugar la conversi-nG
o En un contexto c"ec(ed, la conversi-n sigue este procedimientoG
.i el valor del operando es 4a4 o in0inito, se inicia una excepci-n System.%ver-lo,)#ce&tion.
2e lo contrario, el operando de origen se redondea =acia cero, =asta el valor integral m(s cercano.
.i dic=o valor se encuentra dentro del intervalo del tipo de destino, pasar( a ser el resultado de la
conversi-n.
2e lo contrario, se inicia una excepci-n System.%ver-lo,)#ce&tion.
o En un contexto unc"ec(ed, la conversi-n siempre termina correctamente y se procesa como sigue.
.i el valor del operando es 4a4 o in0inito, el resultado de la conversi-n es un valor no especi0icado
del tipo de destino.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 123
Especificacin del lenguaje C#
2e lo contrario, el operando de origen se redondea =acia cero, =asta el valor integral m(s cercano.
.i dic=o valor se encuentra dentro del intervalo del tipo de destino, pasar( a ser el resultado de la
conversi-n.
2e no ser as5, el resultado de la conversi-n ser( un valor no especi0icado del tipo de destino.
'ara una conversi-n de double a -loat, el valor double se redondea al valor -loat m(s pr-ximo. .i el
valor double es demasiado pe?ueUo para representarlo como -loat, el resultado se convierte en cero
positivo o cero negativo. .i el valor double es demasiado grande para representarlo como -loat, el
resultado se convierte en in0inito positivo o in0inito negativo. .i el valor double es 4a4, el resultado
tambi)n es 4a4.
'ara una conversi-n de -loat o double a decimal, el valor de origen se convierte a la representaci-n
decimal y se redondea =asta el nHmero m(s pr-ximo despu)s de la posici-n decimal 28 si es necesario
O[4.1.*R. .i el valor de origen es demasiado pe?ueUo para representarlo como decimal, el resultado es cero.
.i el valor de origen es 4a4, in0inito o demasiado grande para representarlo como decimal, se inicia una
excepci-n System.%ver-lo,)#ce&tion.
'ara una conversi-n de decimal a -loat o double, el valor decimal se redondea al valor -loat o
double m(s pr-ximo. &un?ue esta conversi-n puede perder precisi-n, nunca produce una excepci-n.
$.2.2 %onersiones de enumeracin e"pl2citas
8as conversiones expl5citas de enumeraci-n sonG
2e sbyte, byte, s"ort, us"ort, int, uint, long, ulong, c"ar, -loat, double o decimal a
cual?uier tipo enum Oen%-t#peR.
2e cual?uier tipo enum Oen%-t#peR a sbyte, byte, s"ort, us"ort, int, uint, long, ulong, c"ar,
-loat, double o decimal.
2e un tipo enum Oen%-t#peR a cual?uier otro tipo enum.
7na conversi-n expl5cita de enumeraci-n entre dos tipos se procesa tratando a uno de los tipos enum Oen%-
t#peR como tipo subyacente del otro, y reali1ando, a continuaci-n, una conversi-n num)rica impl5cita o expl5cita
entre los tipos resultantes. 'or e$emplo, dado un tipo enum Oen%-t#peR ) con un tipo subyacente de int, una
conversi-n de ) a byte se trata como una conversi-n expl5cita num)rica O[#.2.1R de int a byte, y una
conversi-n de byte a ) se procesa como una conversi-n impl5cita num)rica O[#.1.2R de byte a int.
$.2.3 %onersiones e"pl2citas ;ue aceptan alores 1566
8as conversiones e.plcitas "!e aceptan valores 2300 permiten prede0inir conversiones expl5citas ?ue
0uncionan en tipos de valor ?ue no aceptan valores 4788 para ?ue sean utili1ados tambi)n con estructuras ?ue
aceptan valores 4788 de dic=os tipos. 'ara cada una de las conversiones prede0inidas ?ue se convierten de un
tipo de valor S ?ue no acepta valores 4788 a un tipo de valor 1 ?ue no acepta valores 4788 O[#.1.1, [#.1.2,
[#.1.3, [#.2.1 y [#.2.2R, existen las siguientes conversiones ?ue aceptan valores 4788G
7na conversi-n expl5cita de S7 a 17.
7na conversi-n expl5cita de S a 17.
7na conversi-n expl5cita de S7 a 1.
8a evaluaci-n de una conversi-n ?ue acepta valores 4788 se basa en una conversi-n subyacente de S a 1 se
reali1a de la siguiente maneraG
.i la conversi-n ?ue acepta valores 4788 se reali1a de S7 a 17G
12# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
o .i el valor de origen es 4788 Ola propiedad HasUalue es 0alsaR, el resultado es el valor 4788 del
tipo 17.
o 2e lo contrario, la conversi-n se evalHa como un desa$uste de S7 a S, seguido de la conversi-n
subyacente de S a 1, seguida de un a$uste de 1 a 17.
.i la conversi-n ?ue acepta valores 4788 se reali1a de S a 17, la conversi-n se evalHa como la conversi-n
subyacente de S a 1 seguida de un a$uste de 1 a 17.
.i la conversi-n ?ue acepta valores 4788 se reali1a de S7 a 1, la conversi-n se evalHa como un desa$uste
de S7 a S seguida de la conversi-n subyacente de S a 1.
Tenga en cuenta ?ue cual?uier intento por desa$ustar un valor ?ue acepta valores 4788 producir( una
excepci-n si el valor es null.
$.2.! %onersiones e"pl2citas de referencia
8as conversiones expl5citas de re0erencia sonG
2e object a cual?uier otro tipo de re0erencia Oreference-t#peR.
2e cual?uier tipo de clase Oclass-t#peR S a cual?uier tipo de clase Oclass-t#peR 1, siempre ?ue S sea una clase
base de 1.
2e cual?uier tipo de clase Oclass-t#peR S a cual?uier tipo de inter0a1 Ointerface-t#peR 1, siempre ?ue S no sea
sealed y ?ue S no implemente a 1.
2e cual?uier tipo de inter0a1 Ointerface-t#peR S a cual?uier tipo de clase Oclass-t#peR 1, siempre ?ue 1 no sea
sealed ni implemente a S.
2e cual?uier tipo de inter0a1 Ointerface-t#peR S a cual?uier tipo de inter0a1 Ointerface-t#peR 1, a condici-n de
?ue S no se derive de 1.
2e un tipo de matri1 Oarra#-t#peR S con un tipo de elemento S) a un tipo de matri1 1 con un tipo de
elemento 1), siempre ?ue se cumpla todo lo siguienteG
o S y 1 di0ieren solamente en el tipo de elemento. Esto es, S y 1 tienen el mismo nHmero de dimensiones.
o Tanto S) como 1) son tipos de re0erencia Oreference-t#pesR.
o Existe una conversi-n expl5cita de re0erencia de S) a 1).
2esde System.'rray y las inter0aces ?ue implementa, a cual?uier tipo de matri1 Oarra#-t#peR.
2esde un tipo de matri1 unidimensional S45 a System.Collections.Seneric.$ListD1E y sus
inter0aces base, siempre ?ue =aya una identidad expl5cita o una conversi-n de re0erencia de S a 1.
2esde System.Collections.Seneric.$ListDSE y sus inter0aces base a un tipo de matri1
unidimensional 145, siempre ?ue =aya una identidad expl5cita o una conversi-n de re0erencia de S a 1.
2e System.6elegate y las inter0aces ?ue implementa a cual?uier tipo delegado Odele&ate-t#peR.
Conversiones expl5citas ?ue impli?uen par(metros de tipo ?ue se sabe ?ue son tipos de re0erencia. 'ara
obtener m(s datos acerca de las conversiones expl5citas ?ue implican par(metros de tipo ve la secci-n
[#.2.#.
8as conversiones expl5citas de re0erencia son a?uellas conversiones entre tipos de re0erencias ?ue re?uieren
comprobaciones en tiempo de e$ecuci-n para asegurar ?ue son correctas.
'ara ?ue una conversi-n expl5cita de re0erencia se realice correctamente en tiempo de e$ecuci-n, el valor del
operando de origen debe ser una re0erencia null, o el tipo real del ob$eto al ?ue =ace re0erencia el operando de
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 12!
Especificacin del lenguaje C#
origen debe ser un tipo convertible al tipo de destino mediante una conversi-n impl5cita de re0erencia O[#.1.#R.
.i una conversi-n expl5cita de re0erencia produce un error, se inicia una excepci-n
System.$nvalidCast)#ce&tion.
8as conversiones de re0erencia, tanto impl5citas como expl5citas, nunca cambian la identidad re0erencial del
ob$eto ?ue se convierte. Es decir, si bien una conversi-n de re0erencia puede cambiar el tipo de la re0erencia,
nunca cambia el tipo o el valor del ob$eto al ?ue se re0iere.
$.2.# %onersiones 5nbo"ing
7na conversi-n unboxing permite ?ue un tipo de re0erencia Oreference-t#peR se convierta expl5citamente en un
tipo de valor Ovale-t#peR. Existe una conversi-n unboxing de los tipos object y System.Ualue1y&e a
cual?uier tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR, y de cual?uier tipo de inter0a1
Ointerface-t#peR a cual?uier tipo de valor ?ue no acepta valores 4788 Onon-nlla-le-vale-t#peR ?ue
implementa el tipo de inter0a1 Ointerface-t#peR. Es m(s, se puede aplicar una conversi-n unboxing en un tipo
System.)num para convertirlo en un tipo enum Oen%-t#peR.
Existe una conversi-n unboxing de cual?uier tipo de re0erencia a un tipo ?ue acepta valores 4788 Onlla-le-
vale-t#peR, si existe una conversi-n unboxing del tipo de re0erencia al tipo de valor ?ue no acepta valores
4788 Onon-nlla-le-vale-t#peR subyacente del tipo ?ue acepta valores 4788 Onlla-le-t#peR.
7na operaci-n unboxing consiste en comprobar primero ?ue la instancia del ob$eto es un valor al ?ue se =a
aplicado la conversi-n boxing del tipo de valor Ovale-t#peR dado, y copiar despu)s el valor 0uera de la instancia.
8a conversi-n unboxing de un valor de re0erencia a un tipo ?ue acepta valores 4788 Onlla-le-t#peR produce
una el valor 4788 del tipo ?ue acepta valores 4788 Onlla-le-t#peR. .e puede aplicar a una estructura una
conversi-n unboxing desde el tipo System.Ualue1y&e, por?ue )sa es una clase base para todas las
estructuras O[11.3.2R.
8as conversiones unboxing se explican m(s detalladamente en [4.3.2.
$.2.$ %onersiones e"pl2citas con par)metros de tipo
'ara un par(metro de tipo 1 dado, existen las siguientes conversiones impl5citasG
2esde la clase base e0ectiva C de 1 a 1, y desde cual?uier clase base de C a 1. En tiempo de e$ecuci-n, si 1
es un tipo de valor, la conversi-n se e$ecuta como una conversi-n unboxing. 2e lo contrario, la conversi-n
se e$ecuta como una conversi-n de re0erencia expl5cita o una conversi-n de identidad.
2esde cual?uier tipo de inter0a1 a 1. En tiempo de e$ecuci-n, si 1 es un tipo de valor, la conversi-n se
e$ecuta como una conversi-n unboxing. 2e lo contrario, la conversi-n se e$ecuta como una conversi-n de
re0erencia expl5cita o una conversi-n de identidad.
2esde 1 a cual?uier $ de tipo de inter0a1 Ointerface-t#peR siempre y cuando no exista ya una conversi-n
impl5cita de 1 a $. En tiempo de e$ecuci-n, si 1 es un tipo de valor, la conversi-n se e$ecuta como una
conversi-n boxing seguida de una conversi-n de re0erencia expl5cita. 2e lo contrario, la conversi-n se
e$ecuta como una conversi-n de re0erencia expl5cita o una conversi-n de identidad.
2esde un par(metro de tipo ; o 1, siempre ?ue 1 dependa de ; O[1".1.R. En tiempo de e$ecuci-n, si ; es un
tipo de valor, entonces 1 y ; son necesariamente el mismo tipo y no se reali1a una conversi-n boxing. 2e lo
contrario, si 1 es un tipo de re0erencia, necesariamente ; tambi)n lo es y la conversi-n se e$ecuta como una
conversi-n de re0erencia expl5cita o una conversi-n de identidad.
.i 1 es un tipo de re0erencia, las conversiones anteriores se clasi0ican como conversiones de re0erencia
expl5citas O[R. .i T no es un tipo de re0erencia, las conversiones anteriores se clasi0ican como
conversiones unboxing O[R.
126 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8as reglas anteriores no permiten una conversi-n expl5cita directa desde un par(metro de tipo sin restricciones a
un tipo de inter0a1, lo ?ue puede resultar sorprendente. El motivo es evitar la con0usi-n y =acer m(s 0(cil la
sem(ntica de dic=as conversiones. 'or e$emplo, en la siguiente declaraci-nG
class ID1E
{
&ublic static long V(1 t) {
return (long)t; .. )rror
!
!
.i se permitiese la conversi-n expl5cita directa de t a int, el resultado esperado de IDintE.V(M) ser5a ML. .in
embargo, no es as5 por?ue las conversiones num)ricas est(ndar s-lo se consideran cuando los tipos son
num)ricos en tiempo de compilaci-n. 'ara ?ue la sem(ntica sea m(s clara, el e$emplo anterior se debe escribir
de la siguiente maneraG
class ID1E
{
&ublic static long V(1 t) {
return (long)(object)t; .. %( but ,ill only ,or( ,"en 1 is long
!
!
Este c-digo se compilar(, pero si se e$ecuta IDintE.V(M) se iniciar( una excepci-n en tiempo de e$ecuci-n,
puesto ?ue int, al ?ue se =a aplicado una conversi-n boxing, no se puede convertir directamente en long.
$.2.+ %onersiones e"pl2citas definidas por el usuario
7na conversi-n expl5cita de0inida por el usuario consta de una conversi-n expl5cita opcional est(ndar, seguida
por la e$ecuci-n de un operador de conversi-n impl5cita o expl5cita de0inida por el usuario, seguido por otra
conversi-n expl5cita opcional est(ndar. 8as reglas exactas para la evaluaci-n de conversiones expl5citas
de0inidas por el usuario se describen en [#.4..
$.3 %onersiones est)ndar
8as conversiones est(ndar son conversiones prede0inidas ?ue pueden ocurrir como parte de una conversi-n
de0inida por el usuario.
$.3.1 %onersiones impl2citas est)ndar
8as siguientes conversiones impl5citas se clasi0ican como conversiones impl5citas est(ndarG
Conversiones de identidad O[#.1.1R
Conversiones num)ricas impl5citas O[#.1.2R
Conversiones impl5citas ?ue aceptan valores 4788 O[#.1.4R
Conversiones impl5citas de re0erencia O[#.1.#R
Conversiones boxing O[#.1.*R
Conversiones impl5citas de expresi-n constante O[#.1.8R
Conversiones impl5citas con par(metros de tipo O[#.1.+R
8as conversiones impl5citas est(ndar excluyen de 0orma espec50ica las conversiones impl5citas de0inidas por el
usuario.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 12(
Especificacin del lenguaje C#
$.3.2 %onersiones e"pl2citas est)ndar
8as conversiones expl5citas est(ndar son todas las conversiones impl5citas est(ndar m(s el subcon$unto de las
conversiones expl5citas para las cuales existe una conversi-n impl5cita est(ndar opuesta. Es decir, si existe una
conversi-n impl5cita est(ndar de un tipo ' a un tipo :, eso signi0ica ?ue existe una conversi-n expl5cita est(ndar
del tipo ' al tipo : y del tipo : al tipo '.
$.! %onersiones definidas por el usuario
C# permite la ampliaci-n de las conversiones expl5citas e impl5citas prede0inidas mediante conversiones
definidas por el !s!ario. 8as conversiones de0inidas por el usuario se introducen mediante la declaraci-n de
operadores de conversi-n O[1".1".3R en tipos de clase y struct.
$.!.1 %onersiones permitidas definidas por el usuario
C# s-lo permite la declaraci-n de algunas conversiones de0inidas por el usuario. En concreto, no es posible
rede0inir una conversi-n expl5cita o impl5cita ya existente.
'ara un tipo de origen S y de destino 1 dados, si S o 1 son tipos ?ue aceptan valores 4788, S3 y 13 =acen
re0erencia a sus tipos subyacentes, en caso contrario S3 y 13 son iguales ?ue S y 1 respectivamente. 7na clase o
estructura tiene permitido declarar una conversi-n de un tipo de origen S a un tipo de destino 1 solamente si son
verdaderos todos los puntos siguientesG
S3 y 13 son tipos di0erentes.
S3 o 13 es el tipo de clase o estructura en el ?ue tiene lugar la declaraci-n del operador.
4i S3 ni 13 es un tipo de inter0a1 Ointerface-t#peR.
Excluyendo las conversiones de0inidas por el usuario, una conversi-n no existe de S a 1 ni de 1 a S.
8as restricciones aplicables a las conversiones de0inidas por el usuario se explican en [1".1".3.
$.!.2 ,peradores de conersin de eleacin
2ado un operador de conversi-n de0inida por el usuario ?ue reali1a conversiones de un tipo de valor ?ue no
acepta valores 4788 S a un tipo de valor ?ue no acepta valores 4788 1, existe un operador de conversi,n de
elevaci,n ?ue convierte de S7 a 17. Este operador de conversi-n de elevaci-n reali1a un desa$uste de S7 a S
seguido de una conversi-n de0inida por el usuario de S a 1 seguida de un a$uste de 1 a 17, con la excepci-n de
?ue S7 con valor 4788 se convierte directamente en 17 con valor 4788.
7n operador de conversi-n de elevaci-n tiene la misma clasi0icaci-n impl5cita o expl5cita ?ue su operador de
conversi-n de0inido por el usuario. El t)rmino Pconversi-n de0inida por el usuarioQ se aplica al uso tanto de
operadores de conversi-n de0inida por el usuario como a operadores de conversi-n de elevaci-n.
$.!.3 Ealuacin de conersiones definidas por el usuario
7na conversi-n de0inida por el usuario convierte un valor de su tipo, denominado tipo de origen, a otro tipo,
denominado tipo de destino. 8a evaluaci-n de una conversi-n de0inida por el usuario se centra en descubrir el
operador de conversi-n de0inida por el usuario 5s especfico para los tipos de origen y de destino concretos.
Esta determinaci-n se divide en varios pasosG
Auscar el con$unto de clases y estructuras a partir del cual se consideran los operadores de conversi-n
de0inida por el usuario. Este con$unto consta del tipo de origen y sus clases base y el tipo de destino y sus
clases base Ocon los supuestos impl5citos de ?ue s-lo las clases y estructuras pueden declarar operadores
de0inidos por el usuario y de ?ue los tipos no de clase no tienen clases baseR. 'ara este procedimiento, si el
12$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
tipo de origen o el de destino es un tipo ?ue acepta valores 4788 Onlla-le-t#peR, se usa su tipo subyacente
en su lugar.
& partir del con$unto de tipos, determinar ?u) operadores de conversi-n de0inida por el usuario o de
elevaci-n son aplicables. 'ara ?ue un operador de conversi-n sea aplicable, debe ser posible reali1ar una
conversi-n est(ndar O[#.3R del tipo de origen al tipo de operando del operador, y debe ser posible reali1ar
una conversi-n est(ndar del tipo del resultado del operador al tipo de destino.
& partir del con$unto de operadores de0inidos por el usuario ?ue puedan aplicarse, determinar ?u) operador
es el m(s espec50ico sin ninguna ambigIedad. En t)rminos generales, el operador m(s espec50ico es a?u)l
cuyo tipo de operando es el Pm(s pr-ximoQ al tipo de origen y cuyo tipo de resultado es el Pm(s pr-ximoQ al
tipo de destino. .e pre0ieren los operadores de conversi-n de0inida por el usuario a los operadores de
conversi-n de elevaci-n. En las pr-ximas secciones se de0inen las reglas exactas para establecer el operador
de conversi-n de0inido por el usuario m(s espec50ico.
7na ve1 identi0icado un operador de conversi-n de0inido por el usuario m(s espec50ico, la e$ecuci-n de la
conversi-n de0inida por el usuario implica =asta tres pasosG
'rimero, si se re?uiere, reali1ar una conversi-n est(ndar del tipo de origen al tipo de operando del operador
de conversi-n de0inida por el usuario o de elevaci-n.
2espu)s, invocar al operador de conversi-n de0inida por el usuario o de elevaci-n para ?ue realice la
conversi-n.
'or Hltimo, si se re?uiere, reali1ar una conversi-n est(ndar del tipo del resultado del operador de conversi-n
de0inida por el usuario o de elevaci-n al tipo de destino.
8a evaluaci-n de una conversi-n de0inida por el usuario nunca necesita m(s de un operador de conversi-n
de0inida por el usuario o de elevaci-n. Esto es, una conversi-n del tipo S al tipo 1 nunca e$ecuta en primer lugar
una conversi-n de0inida por el usuario de S a I y despu)s una conversi-n de0inida por el usuario de I a 1.
En las pr-ximas secciones se o0recen las de0iniciones exactas de la evaluaci-n de conversiones impl5citas o
expl5citas de0inidas por el usuario. En las de0iniciones se usan los siguientes t)rminosG
.i existe una conversi-n impl5cita est(ndar O[#.3.1R de un tipo ' a un tipo :, y si ni ' ni : are son tipos de
inter0a1 Ointerface-t#pesR, entonces se dice ?ue ' est( a/arcado por :, y ?ue : a/arca '.
El tipo "!e 5s a/arca de un con$unto de tipos es a?u)l ?ue abarca a todos los dem(s tipos del con$unto. .i
ninguno de los tipos abarca a todos los dem(s, entonces el con$unto no tiene tipo ?ue m(s abarca. En
t)rminos m(s intuitivos, el tipo ?ue m(s abarca es el PmayorQ del con$unto, el tipo al ?ue pueden convertirse
impl5citamente todos los dem(s tipos.
El tipo 5s a/arcado de un con$unto de tipos es a?u)l al ?ue abarcan todos los dem(s tipos del con$unto. .i
ninguno de los tipos es abarcado por todos los dem(s, entonces el con$unto no tiene un tipo m(s abarcado.
En t)rminos m(s intuitivos, el tipo m(s abarcado es el PmenorQ del con$unto, a?u)l ?ue puede convertirse
impl5citamente a todos los dem(s tipos.
$.!.! %onersiones e"pl2citas definidas por el usuario
7na conversi-n impl5cita de0inida por el usuario del tipo S al tipo 1 se procesa como sigueG
2eterminar los tipos S3 y 13. .i S o 1 son tipos ?ue aceptan valores 4788, S3 y 13 =acen re0erencia a sus
tipos subyacentes, en caso contrario S3 y 13 son iguales ?ue S y 1 respectivamente.
.e busca un con$unto de tipos, 6, a partir del cual se consideran los operadores de conversi-n de0inida por el
usuario. Este con$unto est( 0ormado por S3 Osi S3 es una clase o una estructuraR, las clases base de S3 Osi S3 es
una claseR y 13 Osi 13 es una clase o una estructuraR.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 12"
Especificacin del lenguaje C#
.e busca el con$unto de operadores de conversi-n de0inida por el usuario o de elevaci-n aplicables, ;. Este
con$unto est( 0ormado por los operadores de0inidos por el usuario y operadores de conversi-n impl5cita de
elevaci-n declarados por las clases o estructuras en 6 ?ue reali1an la conversi-n de un tipo ?ue abarca S a
un tipo abarcado por 1. .i ; est( vac5a, la conversi-n no estar( de0inida y se producir( un error en tiempo de
e$ecuci-n.
.e busca el tipo de origen m(s espec50ico, SI, de los operadores de ;G
o .i uno de los operadores de ; se convierte desde S, entonces SI es S.
o 2e lo contrario, SI es el tipo m(s abarcado del con$unto combinado de tipos de origen de los operadores
de ;. .i no se puede encontrar exactamente el tipo m(s abarcado, la conversi-n es ambigua y se genera
un error en tiempo de compilaci-n.
.e busca el tipo de destino m(s espec50ico, 1I, de los operadores de ;G
o .i uno de los operadores de ; se convierte a 1, entonces 1I es 1.
o 2e lo contrario, 1I es el tipo ?ue m(s abarca del con$unto combinado de tipos de destino de los
operadores de ;. .i no se puede encontrar exactamente el tipo ?ue m(s abarca, la conversi-n es ambigua
y se genera un error en tiempo de compilaci-n.
.e buscar el operador de conversi-n m(s espec50icoG
o .i ; contiene exactamente un operador de conversi-n de0inida por el usuario ?ue convierte de SI a 1I,
)ste es el operador de conversi-n m(s espec50ico.
o 2e lo contrario, si ; contiene exactamente un operador de conversi-n de elevaci-n ?ue reali1a la
conversi-n de SI a 1I, )ste es el operador de conversi-n m(s espec50ico.
o 2e lo contrario, la conversi-n es ambigua y se genera un error en tiempo de compilaci-n.
'or Hltimo, se aplica la conversi-nG
o .i S no es SI, se reali1a una conversi-n impl5cita est(ndar de S a SI.
o El operador de conversi-n m(s espec50ico se invoca para reali1ar la conversi-n de SI a 1I.
o .i 1I no es 1, se reali1a una conversi-n impl5cita est(ndar de 1I a 1.
$.!.# %onersiones e"pl2citas definidas por el usuario
7na conversi-n expl5cita de0inida por el usuario del tipo S al tipo 1 se procesa como sigueG
2eterminar los tipos S3 y 13. .i S o 1 son tipos ?ue aceptan valores 4788, S3 y 13 =acen re0erencia a sus
tipos subyacentes, en caso contrario S3 y 13 son iguales ?ue S y 1 respectivamente.
.e busca un con$unto de tipos, 6, a partir del cual se consideran los operadores de conversi-n de0inida por el
usuario. Este con$unto consta de S3 Osi S3 es una clase o estructuraR, las clases base de S3 Osi S3 es una claseR,
13 Osi 13 es una clase o estructuraR y las clases base de 13 Osi 13 es una claseR.
.e busca el con$unto de operadores de conversi-n de0inida por el usuario o de elevaci-n aplicables, ;. Este
con$unto est( 0ormado por los operadores de0inidos por el usuario y los operadores de conversi-n expl5cita
de elevaci-n declarados por las clases o estructuras en 6 ?ue reali1an la conversi-n de un tipo abarcado o
?ue abarca S a un tipo abarcado o ?ue abarca 1. .i ; est( vac5a, la conversi-n no estar( de0inida y se
producir( un error en tiempo de e$ecuci-n.
.e busca el tipo de origen m(s espec50ico, SI, de los operadores de ;G
o .i uno de los operadores de ; se convierte desde S, entonces SI es S.
13' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
o 2e lo contrario, si uno de los operadores de ; convierte de los tipos ?ue abarca S, entonces SI es el tipo
m(s abarcado del con$unto combinado de tipos de origen de estos operadores. .i no se encuentra un tipo
m(s abarcado, la conversi-n ser( ambigua y se producir( un error en tiempo de compilaci-n.
o 2e lo contrario, SI es el tipo ?ue m(s abarca del con$unto combinado de tipos de origen de los
operadores de ;. .i no se puede encontrar exactamente el tipo ?ue m(s abarca, la conversi-n es ambigua
y se genera un error en tiempo de compilaci-n.
.e busca el tipo de destino m(s espec50ico, 1I, de los operadores de ;G
o .i uno de los operadores de ; se convierte a 1, entonces 1I es 1.
o 2e lo contrario, si uno de los operadores de ; convierte a los tipos abarcados por 1, entonces 1I es el
tipo ?ue m(s abarca del con$unto combinado de tipos de origen de estos operadores. .i no se puede
encontrar exactamente el tipo m(s abarcado, la conversi-n es ambigua y se genera un error en tiempo de
compilaci-n.
o 2e lo contrario, 1I es el tipo m(s abarcado del con$unto combinado de tipos de destino de los
operadores de ;. .i no se puede encontrar exactamente el tipo m(s abarcado, la conversi-n puede ser
ambigua y se genera un error en tiempo de compilaci-n.
.e buscar el operador de conversi-n m(s espec50icoG
o .i ; contiene exactamente un operador de conversi-n de0inida por el usuario ?ue convierte de SI a 1I,
)ste es el operador de conversi-n m(s espec50ico.
o 2e lo contrario, si ; contiene exactamente un operador de conversi-n de elevaci-n ?ue reali1a la
conversi-n de SI a 1I, )ste es el operador de conversi-n m(s espec50ico.
o 2e lo contrario, la conversi-n es ambigua y se genera un error en tiempo de compilaci-n.
'or Hltimo, se aplica la conversi-nG
o .i S no es SI, se reali1a una conversi-n expl5cita est(ndar de S a SI.
o .e llama al operador de conversi-n m(s espec50ico de0inido por el usuario para convertir de SI a 1I.
o .i 1I no es 1, se reali1a una conversi-n expl5cita est(ndar de 1I a 1.
$.# %onersiones de funcin annima
7na expresi-n de m)todo an-nimo Oanon#%os-%ethod-e2pressionR o expresi-n lambda Ola%-da-e2pressionR se
clasi0ica como una 0unci-n an-nima O[R. 8a expresi-n no tiene un tipo, pero se puede convertir de manera
impl5cita en un tipo de (rbol de expresiones o un tipo delegado compatible. En concreto, un tipo delegado 6 es
compatible con una 0unci-n an-nima V siempre ?ueG
.i V contiene una 0irma de 0unci-n an-nima Oanon#%os-fnction-si&natreR, 6 y V tienen el mismo nHmero
de par(metros.
.i V no contiene una 0irma de 0unci-n an-nima Oanon#%os-fnction-si&natreR, 6 puede no tener ningHn
par(metro o tener par(metros de cual?uier tipo siempre y cuando ninguno de ellos tenga el modi0icador de
par(metros out.
.i V tiene una lista de par(metros escritos expl5citamente, cada par(metro de 6 tiene el mismo tipo y los
mismos modi0icadores ?ue el par(metro correspondiente en V.
.i V tiene una lista de par(metros escritos impl5citamente, 6 no tiene ningHn par(metro re- u out.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 131
Especificacin del lenguaje C#
.i 6 tiene un tipo de valor devuelto void y el cuerpo de V es una expresi-n, cuando se da a cada par(metro
de V el tipo del par(metro correspondiente en 6, el cuerpo de V es una expresi-n v(lida O9rt [*R ?ue se
permitir5a como expresi-n de instrucci-n Ostate%ent-e2pressionR O[8.#R.
.i 6 tiene un tipo de valor devuelto void y el cuerpo de V es un blo?ue de instrucciones, cuando se da a
cada par(metro de V el tipo del par(metro correspondiente en 6, el cuerpo de V es un blo?ue de instrucci-n
v(lido O9rt [*R en el ?ue ninguna instrucci-n return especi0ica una expresi-n.
.i 6 tiene un tipo de valor devuelto ?ue no es void y el cuerpo de V es una expresi-n, cuando se da a cada
par(metro de V el tipo del par(metro correspondiente en 6, el cuerpo de V es una expresi-n v(lida O9rt [*R
?ue es impl5citamente convertible al tipo de valor devuelto de 6.
.i 6 tiene un tipo de valor devuelto ?ue no es void y el cuerpo de V es un blo?ue de instrucciones, cuando se
da a cada par(metro de V el tipo del par(metro correspondiente en 6, el cuerpo de V es un blo?ue de
instrucci-n v(lido O9rt [8.2R con un punto 0inal ?ue no es alcan1able en el ?ue cada instrucci-n return
especi0ica una expresi-n ?ue es impl5citamente convertible al tipo de 6.
7n tipo de (rbol de expresiones )#&ressionD6E es compatible con una 0unci-n an-nima V si el tipo delegado
6 es compatible con V.
En el e$emplo siguiente se utili1a un tipo delegado gen)rico VuncD'OE ?ue representa una 0unci-n ?ue toma
un argumento del tipo ' y devuelve un valor de tipo OG
delegate O VuncD'OE(' arg);
En las asignaciones
VuncDintintE -2 + # +E # < 2; .. %(
VuncDintdoubleE -8 + # +E # < 2; .. %(
VuncDdoubleintE -9 + # +E # < 2; .. )rror
el par(metro y los tipos de valor devuelto de cada 0unci-n an-nima se determinan a partir del tipo de la variable
a la ?ue la 0unci-n an-nima se asigna.
8a primera asignaci-n convierte correctamente la 0unci-n an-nima en el tipo delegado VuncDintintE
por?ue, cuando se da a # el tipo int, # < 2 es una expresi-n v(lida ?ue es impl5citamente convertible al tipo
int.
2el mismo modo, la segunda asignaci-n convierte correctamente la 0unci-n an-nima en el tipo delegado
VuncDintdoubleE por?ue el resultado de # < 2 Ode tipo intR es impl5citamente convertible al tipo double.
.in embargo, la tercera asignaci-n es un error en tiempo de compilaci-n por?ue, cuando se da a # el tipo
double, el resultado de # < 2 Ode tipo doubleR no es impl5citamente convertible al tipo int.
8as 0unciones an-nimas pueden in0luenciar la resoluci-n de sobrecargas y participar en la in0erencia de tipos.
Consulte la [*.4 para obtener m(s detalles.
$.#.1 Ealuacin de conersiones de funcin annima a tipos delegados
8a conversi-n de una 0unci-n an-nima a un tipo delegado genera una instancia de delegado ?ue =ace re0erencia
a la 0unci-n an-nima y al con$unto Oposiblemente vac5oR de variables externas capturadas y activas en el
momento de la evaluaci-n. .i se invoca el delegado, se e$ecuta el cuerpo de la 0unci-n an-nima. El c-digo del
cuerpo se e$ecuta con el con$unto de variables externas capturadas al ?ue el delegado =ace re0erencia.
8a lista de invocaci-n de un delegado producida desde una 0unci-n an-nima contiene una sola entrada. 4o se
especi0ican el ob$eto y el m)todo de destino exactos del delegado. En concreto, no se especi0ica si el ob$eto de
destino del delegado es null, el valor t"is del miembro de 0unci-n envolvente o algHn otro ob$eto.
132 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8as conversiones de 0unciones an-nimas de sem(nticas id)nticas con el mismo con$unto Oposiblemente vac5oR
de instancias de variables externas capturadas a los mismos tipos delegados pueden devolver Oaun?ue no es
obligatorioR la misma instancia de delegado. En este contexto, sem(ntica id)ntica =ace re0erencia a ?ue la
e$ecuci-n de 0unciones an-nimas generar( en todos los casos los mismos e0ectos si se dan los mismos
argumentos. Esta regla permite optimi1ar c-digo como el siguiente.
delegate double Vunction(double #);
class 1est
{
static double45 '&&ly(double45 a Vunction -) {
double45 result + ne, double4a.Lengt"5;
-or (int i + 3; i D a.Lengt"; i<<) result4i5 + -(a4i5);
return result;
!
static void V(double45 a double45 b) {
a + '&&ly(a (double #) +E Mat".Sin(#));
b + '&&ly(b (double y) +E Mat".Sin(y));
...
!
!
'uesto ?ue los dos delegados de 0unci-n an-nima tienen el mismo con$unto Ovac5oR de variables externas
capturadas y puesto ?ue las 0unciones an-nimas son sem(nticamente id)nticas, el compilador puede tener
delegados ?ue =agan re0erencia al mismo m)todo de destino. 2e =ec=o, el compilador puede devolver la misma
instancia de delegado de ambas expresiones de 0unci-n an-nima.
$.#.2 Ealuacin de conersiones de funcin annima a tipos delegados de )rbol de
e"presiones
8a conversi-n de una 0unci-n an-nima a un tipo de (rbol de expresiones produce un (rbol de expresiones O[4.#R.
%(s concretamente, la evaluaci-n de la conversi-n de 0unci-n an-nima conduce a la construcci-n de una
estructura de ob$etos ?ue representa la estructura de la 0unci-n an-nima en s5. 8a estructura precisa del (rbol de
expresiones, as5 como el proceso exacto de su creaci-n se de0inen en otro lugar.
$.#.3 Ejemplo de implementacin
En esta secci-n se describe una posible implementaci-n de conversiones de 0unciones an-nimas en t)rminos de
otras construcciones del lengua$e C#. 8a implementaci-n a?u5 descrita se basa en los mismos principios
utili1ados por el compilador de %icroso0t C#, pero no es una implementaci-n obligatoria ni tampoco la Hnica
posible. .-lo se mencionan brevemente los (rboles de expresiones, ya ?ue su sem(ntica exacta est( 0uera del
(mbito de este documento.
En el resto de esta secci-n se proporcionan varios e$emplos de c-digo ?ue incluye 0unciones an-nimas con
di0erentes caracter5sticas. En cada uno de los e$emplos se proporciona la traducci-n correspondiente al c-digo
?ue s-lo utili1a otras construcciones est(ndar del lengua$e C#. En los e$emplos, se asume ?ue el identi0icador 6
representa el siguiente tipo delegadoG
&ublic delegate void 6();
8a estructura m(s sencilla de una 0unci-n an-nima es la ?ue no captura variables externasG
class 1est
{
static void V() {
6 d + () +E { Console.WriteLine("test"); !;
!
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 133
Especificacin del lenguaje C#
Esto se puede traducir en una creaci-n de instancias de delegado ?ue =ace re0erencia a un m)todo est(tico
generado por compilador en el ?ue se sitHa la 0unci-n an-nimaG
class 1est
{
static void V() {
6 d + ne, 6(\\Met"od2);
!
static void \\Met"od2() {
Console.WriteLine("test");
!
!
En el siguiente e$emplo, la 0unci-n an-nima =ace re0erencia a miembros de instancia de t"isG
class 1est
{
int #;
void V() {
6 d + () +E { Console.WriteLine(#); !;
!
!
.e puede traducir en un m)todo de instancia generado por compilador ?ue contiene el c-digo de la 0unci-n
an-nimaG
class 1est
{
int #;
void V() {
6 d + ne, 6(\\Met"od2);
!
void \\Met"od2() {
Console.WriteLine(#);
!
!
En este e$emplo, la 0unci-n an-nima captura una variable localG
class 1est
{
void V() {
int y + 289;
6 d + () +E { Console.WriteLine(y); !;
!
!
&=ora, el per5odo de duraci-n de la variable local se debe extender al menos al per5odo de duraci-n del delegado
de la 0unci-n an-nima. Esto se puede lograr PactivandoQ la variable local en un campo de una clase generada por
compilador. Entonces, la creaci-n de instancias de la variable local O[*.14.4.2R corresponde a la creaci-n de una
instancia de la clase generada por compilador y el acceso a la variable local corresponde al acceso a un campo
en la instancia de la clase generada por compilador. 8a 0unci-n an-nima se convierte en un m)todo de instancias
de la clase generada por compiladorG
class 1est
{
void V() {
\\Locals2 \\locals2 + ne, \\Locals2();
\\locals2.y + 289;
6 d + ne, 6(\\locals2.\\Met"od2);
!
13# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class \\Locals2
{
&ublic int y;
&ublic void \\Met"od2() {
Console.WriteLine(y);
!
!
!
:inalmente, la siguiente 0unci-n an-nima captura t"is as5 como dos variables locales con di0erentes per5odos
de duraci-nG
class 1est
{
int #;
void V() {
int y + 289;
-or (int i + 3; i D 23; i<<) {
int ? + i > 8;
6 d + () +E { Console.WriteLine(# < y < ?); !;
!
!
!
&?u5 se crea una clase generada por compilador para cada blo?ue de instrucciones en los ?ue se capturan valores
locales para ?ue los valores locales de blo?ues di0erentes tengan per5odos de duraci-n independientes. 7na
instancia de \\Locals8, la clase generada por compilador para el blo?ue interior de instrucciones, contiene la
variable local ? y un campo ?ue =ace re0erencia a una instancia de \\Locals2. 7na instancia de \\Locals2,
la clase generada por compilador para el blo?ue exterior de instrucciones, contiene la variable local y y un
campo ?ue =ace re0erencia a t"is del miembro de 0unci-n envolvente. Con estas estructuras de datos es posible
alcan1ar todas las variables externas capturadas mediante una instancia de \\Local8 y el c-digo de la 0unci-n
an-nima se puede implementar como un m)todo de una instancia de dic=a clase.
class 1est
{
void V() {
\\Locals2 \\locals2 + ne, \\Locals2();
\\locals2.\\t"is + t"is;
\\locals2.y + 289;
-or (int i + 3; i D 23; i<<) {
\\Locals8 \\locals8 + ne, \\Locals8();
\\locals8.\\locals2 + \\locals2;
\\locals8.? + i > 8;
6 d + ne, 6(\\locals8.\\Met"od2);
!
!
class \\Locals2
{
&ublic 1est \\t"is;
&ublic int y;
!
class \\Locals8
{
&ublic \\Locals2 \\locals2;
&ublic int ?;
&ublic void \\Met"od2() {
Console.WriteLine(\\locals2.\\t"is.# < \\locals2.y < ?);
!
!
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 13!
Especificacin del lenguaje C#
8a misma t)cnica aplicada a?u5 para capturar variables locales tambi)n se puede utili1ar a la =ora de convertir
0unciones an-nimas a (rboles de expresionesG las re0erencias a los ob$etos generados por el compilador se
pueden almacenar en el (rbol de expresiones, y el acceso a las variables locales se puede representar como
acceso a campos en esos ob$etos. 8a venta$a de este m)todo es ?ue permite ?ue las variables locales de
Pelevaci-nQ sean compartidas entre (rboles de expresiones y delegados.
$.$ %onersiones de grupo de m*todos
Existe una conversi-n impl5cita O[#.1R desde un grupo de m)todos O[*.1R a un tipo delegado compatible. 2ado
un tipo delegado 6 y una expresi-n ) clasi0icada como un grupo de m)todos, existe una conversi-n impl5cita de
) a 6 si ) contiene al menos un m)todo aplicable en su estructura normal O[R a una lista de argumentos
construidos por el uso de tipos de par(metro y modi0icadores de 6, tal como se describe a continuaci-n.
8a aplicaci-n en tiempo de compilaci-n de una conversi-n desde un grupo de m)todos ) a un tipo delegado 6 se
describe a continuaci-n. Tenga en cuenta ?ue la existencia de una conversi-n impl5cita de ) a 6 no garanti1a ?ue
la aplicaci-n en tiempo de compilaci-n de la conversi-n se reali1ar( sin errores.
.e selecciona un Hnico m)todo M, correspondiente a una invocaci-n de m)todo O[*...1R con la estructura
)('), con las siguientes modi0icacionesG
o 8a lista de argumentos ' es una lista de expresiones, cada una clasi0icada con una variable y con el tipo
y el modi0icador Ore- u outR del par(metro correspondiente en la lista de par(metros 0ormales Ofor%al-
para%eter-listR de 6.
o 8os m)todos de candidatos considerados s-lo son los ?ue se aplican en su estructura normal O[*.4.3.1R,
no los ?ue se aplican s-lo en su estructura expandida.
.i el algoritmo de [*...1 genera un error, se produce un error en tiempo de compilaci-n. 2e lo contrario,
el algoritmo genera un m)todo individual me$or M con el mismo nHmero de par(metros ?ue 6 y se considera
?ue existe conversi-n.
El m)todo M seleccionado debe ser compatible O[R con el tipo delegado 6 o, de lo contrario, se generar( un
error en tiempo de compilaci-n.
.i el m)todo seleccionado M es un m)todo de instancia, la expresi-n de instancia asociada a ) determina el
ob$eto de destino del delegado.
.i el m)todo seleccionado M es un m)todo de extensi-n ?ue se denota mediante un acceso a miembros en
una expresi-n de instancia, esa expresi-n de instancia determina el ob$eto de destino del delegado.
El resultado de la conversi-n es un valor del tipo 6, un delegado reci)n creado ?ue =ace re0erencia al
m)todo seleccionado y al ob$eto de destino.
Tenga en cuenta ?ue este proceso puede conducir a la creaci-n de un delegado para un m)todo de extensi-n,
si el algoritmo de [*...1 no logra encontrar un m)todo de instancia pero s5 logra culminar con )xito el
procesamiento de la invocaci-n de )(') como una invocaci-n del m)todo de extensi-n O[*...2R. &s5, el
delegado =a creado capturas del m)todo de extensi-n as5 como su primer argumento.
En el siguiente e$emplo se demuestran las conversiones de grupo de m)todosG
delegate string 62(object o);
delegate object 68(string s);
delegate object 69();
delegate string 6J(object o &arams object45 a);
delegate string 6K(int i);
136 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class 1est
{
static string V(object o) {...!
static void S() {
62 d2 + V; .. %(
68 d8 + V; .. %(
69 d9 + V; .. )rror C not a&&licable
6J dJ + V; .. )rror C not a&&licable in normal -orm
6K dK + V; .. )rror C a&&licable but not com&atible
!
!
8a asignaci-n a d2 convierte de manera impl5cita el grupo de m)todos V en un valor del tipo 62.
8a asignaci-n a d8 muestra c-mo es posible crear un delegado para un m)todo ?ue tiene menos par(metros
derivados OcontravariantesR y m(s tipos de valor devuelto OcovariantesR derivados.
8a asignaci-n a d9 muestra c-mo no existe ninguna conversi-n si el m)todo no es aplicable.
8a asignaci-n a dJ muestra c-mo el m)todo debe ser aplicable en su estructura 0ormal.
8a asignaci-n a dK muestra la manera en ?ue par(metros y tipos de valor devuelto del delegado y del m)todo
pueden di0erenciarse s-lo por los tipos de re0erencia.
&l igual ?ue ocurre con otras conversiones impl5citas y expl5citas, el operador de conversi-n se puede utili1ar
para reali1ar de manera expl5cita una conversi-n de grupo de m)todos. 'or lo tanto, el siguiente e$emploG
object obj + ne, )ventHandler(my6ialog.%(Clic();
se puede escribir de la siguiente manera
object obj + ()ventHandler)my6ialog.%(Clic(;
8os grupos de m)todo pueden in0luenciar la resoluci-n de sobrecargas y participar en la in0erencia de tipos.
Consulte la [*.4 para obtener m(s detalles.
8a evaluaci-n en tiempo de e$ecuci-n de una conversi-n de grupo de m)todos se reali1a de la siguiente 0ormaG
.i el m)todo seleccionado en tiempo de compilaci-n es un m)todo de instancia, o es un m)todo de extensi-n
al ?ue se tiene acceso como m)todo de instancia, el ob$eto de destino del delegado se determina a partir de
la expresi-n de instancia asociada con )G
o .e evalHa la expresi-n de instancia. .i esta evaluaci-n da lugar a una excepci-n, no se e$ecutan nuevos
pasos.
o .i la expresi-n de instancia es de un tipo de re0erencia Oreference-t#peR, el valor calculado por la
expresi-n de instancia es el ob$eto de destino. .i el ob$eto de destino es null, se inicia una excepci-n
System.NullOe-erence)#ce&tion y no se e$ecutan m(s pasos.
o .i la expresi-n de instancia es de un tipo de valor Ovale-t#peR, se reali1a una operaci-n boxing O[4.3.1R
para convertir el valor en un ob$eto, ?ue pasa a ser el ob$eto de destino.
2e lo contrario, el m)todo seleccionado es parte de una llamada a m)todo est(tico, y el ob$eto de destino del
delegado es null.
.e asigna una nueva instancia del tipo delegado 6. .i no =ay memoria disponible su0iciente para asignar la
nueva instancia, se inicia una excepci-n System.%ut%-Memory)#ce&tion y no se e$ecutan m(s pasos.
.e iniciali1a la nueva instancia de delegado con una re0erencia al m)todo ?ue se determin- en tiempo de
compilaci-n y una re0erencia al ob$eto de destino antes calculado.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 13(
Especificacin del lenguaje C#
+. E"presiones
7na expresi-n es una secuencia de operadores y operandos. En este cap5tulo se de0inen la sintaxis, el orden de
evaluaci-n de los operandos y los operadores, as5 como el signi0icado de las expresiones.
+.1 %lasificaciones de e"presin
7na expresi-n se puede clasi0icar comoG
7n valor. Todos los valores tienen asociado un tipo.
7na variable. Todas variables tienen un tipo asociado, esto es, el tipo declarado de la variable.
7n espacio de nombres. 7na expresi-n con su clasi0icaci-n s-lo puede aparecer como el miembro i1?uierdo
de un acceso a miembro O%e%-er-accessR O[*..4R. En cual?uier otro contexto, una expresi-n ?ue se
clasi0ica como un espacio de nombres produce un error en tiempo de compilaci-n.
Tipo. 7na expresi-n con esta clasi0icaci-n s-lo puede aparecer como el lado i1?uierdo de un acceso a
miembro O%e%-er-accessR O[*..4R, o como un operando para el operador as O[*.+.11R, el operador is
O[*.+.1"R o el operador ty&eo- O[*..11R. En cual?uier otro contexto, una expresi-n ?ue se clasi0ica como
un tipo produce un error en tiempo de compilaci-n.
7n grupo de m)todos, ?ue es un con$unto de m)todos sobrecargados producidos por una bHs?ueda de
miembros O[*.3R. 7n grupo de m)todos puede tener asociada una expresi-n de instancia y una lista de
argumentos de tipo asociados. Cuando se invoca un m)todo de instancia, el resultado de la evaluaci-n de la
expresi-n de instancia se convierte en la instancia representada por t"is O[*..*R. .e permite un grupo de
m)todos en una expresi-n de invocaci-n Oinvocation-e2pressionR O[*..R, una expresi-n de creaci-n de
delegados Odele&ate-creation-e2pressionR O[*..1".R y como la parte i1?uierda de un operador is, y se
puede convertir impl5citamente en un tipo delegado compatible O[#.#R. En cual?uier otro contexto, una
expresi-n ?ue se clasi0ica como un grupo de m)todos produce un error en tiempo de compilaci-n.
7n literal 4788. 7na expresi-n con esta clasi0icaci-n se puede convertir de manera impl5cita en un tipo de
re0erencia o un tipo ?ue acepta valores 4788.
7na 0unci-n an-nima. 7na expresi-n con esta clasi0icaci-n se puede convertir de manera impl5cita en un
tipo delegado compatible o un tipo de (rbol de expresiones.
7n acceso de propiedad. Todos los accesos de propiedades tienen un tipo asociado, esto es, el tipo declarado
de la propiedad. &dem(s, un acceso a propiedad puede tener asociada una expresi-n de instancia. .i se
llama a un descriptor de acceso Oel blo?ue get o setR de un acceso a propiedad de una instancia, el
resultado de la evaluaci-n de la expresi-n de instancia se convierte en la instancia representada por t"is
O[*..*R.
7n acceso a evento. Todos los accesos de evento tienen un tipo asociado, el tipo declarado del evento.
&dem(s, un acceso de evento puede tener asociada una expresi-n de instancia. 7n acceso a evento puede
aparecer como el operando i1?uierdo de los operadores <+ y =+ O[*.1#.3R. En cual?uier otro contexto, una
expresi-n ?ue se clasi0ica como un acceso a evento produce un error en tiempo de compilaci-n.
7n acceso a indi1ador. Todos los accesos a indi1adores tienen un tipo asociado, el tipo declarado del
indi1ador. &dem(s, un acceso a indi1ador tiene asociadas una expresi-n de instancia y una lista de
argumentos. .i se llama a un descriptor de acceso Oel blo?ue get o setR de un indi1ador, el resultado de la
13$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
evaluaci-n de la expresi-n de instancia pasa a ser la instancia representada por t"is O[*..*R, y el resultado
de la evaluaci-n de la lista de argumentos se convierte en la lista de par(metros de la invocaci-n.
4ada. Esto ocurre cuando la expresi-n es una invocaci-n de un m)todo con el tipo de valor devuelto void.
7na expresi-n clasi0icada como nada s-lo es v(lida en el contexto de una expresi-n de instrucci-n
Ostate%ent-e2pressionR O[8.#R.
El resultado 0inal de una expresi-n nunca es un espacio de nombres, un tipo, un grupo de m)todos o un acceso
de evento. En lugar de ello, como se =a mencionado antes, estas categor5as de expresiones son construcciones
intermedias ?ue s-lo est(n permitidas en determinados contextos.
7n acceso a propiedad o un acceso a indi1ador siempre se reclasi0ican como un valor mediante una llamada del
descriptor de acceso get O&et-accessorR o del descriptor de acceso set Oset-accessorR. El descriptor de acceso
concreto viene determinado por el contexto del acceso a propiedad o del acceso a indi1adorG si el acceso es el
destino de una asignaci-n, se llama al descriptor de acceso set Oset-accessorR para asignar un nuevo valor
O[*.1#.1R. En otro caso, se invoca el descriptor de acceso get O&et-accessorR para obtener el valor actual O[*.1.1R.
+.1.1 Valores de e"presiones
8a mayor5a de las construcciones ?ue involucran una expresi-n re?uieren en de0initiva ?ue la expresi-n denote
un valor. En estos casos, si la expresi-n real denota un espacio de nombres, un tipo, un grupo de m)todos o
nada, se produce un error en tiempo de compilaci-n. 4o obstante, si la expresi-n denota un acceso a propiedad,
un acceso a indi1ador o una variable, el valor de la propiedad, el indi1ador o la variable se sustituyen de 0orma
impl5citaG
El valor de una variable es sencillamente el valor almacenado en la ubicaci-n de almacenamiento ?ue ella
misma identi0ica. 7na variable debe considerarse asignada de0initivamente O[.3R para poder obtener su
valor o, de lo contrario, se produce un error de tiempo de compilaci-n.
El valor de una expresi-n de acceso a propiedad se obtiene mediante una llamada al descriptor de acceso get
O&et-accessorR de la propiedad. .i la propiedad no tiene un descriptor de acceso get O&et-accessorR, se
produce un error durante la compilaci-n. En caso contrario, se reali1a una llamada a un miembro de 0unci-n
O[*.4.4R y el resultado de la llamada pasa a ser el valor de la expresi-n de acceso a propiedad.
El valor de una expresi-n de acceso a indi1ador se obtiene mediante una llamada al descriptor de acceso get
O&et-accessorR del indi1ador. .i el indi1ador no tiene un descriptor de acceso get O&et-accessorR, se produce
un error durante la compilaci-n. En caso contrario, se reali1a una llamada a un miembro de 0unci-n O[*.4.4R
con la lista de argumentos asociada a la expresi-n de acceso al indi1ador, y el resultado de la llamada se
convierte en el valor de la expresi-n de acceso al indi1ador.
+.2 ,peradores
8as expresiones se construyen a partir de operandos y operadores. 8os operadores de una expresi-n indican ?u)
operaciones se aplican a los operandos. Entre los e$emplos de operadores se incluyen <, =, >, . y ne,. .on
e$emplos de operandos los literales, campos, variables locales y expresiones.
Existen tres tipos de operadoresG
/peradores unarios. 8os operadores unarios tienen un operando y utili1an la notaci-n de pre0i$o Ocomo C#R
o de post0i$o Ocomo #<<R.
/peradores binarios. 8os operadores binarios tienen dos operandos y utili1an una notaci-n in0i$a Opor
e$emplo, # < yR.
/perador ternario. .-lo existe un operador ternario, 7/, tiene tres operandos y utili1a notaci-n in0i$a
Oc7 #/ yR.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 13"
Especificacin del lenguaje C#
El orden de evaluaci-n de los operadores de una expresi-n est( determinado por la prioridad y asociatividad de
los operadores O[*.2.1R.
8os operandos de una expresi-n se evalHan de i1?uierda a derec=a. 'or e$emplo, en V(i) < S(i<<) > H(i), se
llama al m)todo V con el valor antiguo de i, despu)s se llama al m)todo S con el valor antiguo de i y, por
Hltimo, se llama al m)todo H con el valor nuevo de i. Esto es aparte y no est( relacionado con la prioridad de los
operadores.
&lgunos operadores no se pueden so/recargar. 8a sobrecarga de operadores permite utili1ar implementaciones
de operadores de0inidas por el usuario en operaciones en las ?ue al menos uno de los operandos es de un tipo
estructura o clase de0inido por el usuario O[*.2.2R.
+.2.1 (rioridad y asociatiidad de los operadores
Cuando una expresi-n contiene varios operadores, la prioridad de los operadores controla el orden de
evaluaci-n de los operadores individuales. 'or e$emplo, la expresi-n # < y > ? se evalHa como # < (y > ?)
por?ue el operador > tiene prioridad sobre el operador binario <. 8a prioridad de un operador est( determinada
por la de0inici-n de su producci-n gramatical asociada. 'or e$emplo, una expresi-n aditiva Oadditive-e2pressionR
consta de una secuencia de expresiones multiplicativas O%ltiplicative-e2pressionsR separadas por los operadores
< o =, lo ?ue da a estos operadores una menor prioridad ?ue a >, . y B.
En la tabla siguiente se resumen todos los operadores, en orden de prioridad de mayor a menorG
3eccin Categor0a 7peradores
*. 'rincipal
#.y -(#) a4#5 #<< #== ne,
ty&eo- de-ault c"ec(ed unc"ec(ed delegate
*.# 7nario
< = @ A <<# ==# (1)#
*.* %ultiplicativo
> . B
*.* .umatorio
< =
*.8 2espla1amiento
DD EE
*.+ Comprobaci-n de
tipos y relacionales
D E D+ E+ is as
*.+ !gualdad
++ @+
*.1" &42 l-gico
F
*.1" N/; l-gico
G
*.1" /; l-gico
H
*.11 &42 condicional
FF
*.11 /; condicional
HH
*.12 7so combinado de
4ull
77
*.13 Condicional
7/
*.1#,
*.14
&signaci-n y
expresi-n lambda
+ >+ .+ B+ <+ =+ DD+ EE+ F+ G+ H+
+E
1#' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Cuando un operando se encuentra entre dos operadores con igual grado de prioridad, la asociatividad de los
operadores controla el orden en ?ue se e$ecutan las operaciones.
& excepci-n de los operadores de asignaci-n, todos los operadores binarios son asociativos por la
i-"!ierda, lo ?ue signi0ica ?ue las operaciones se reali1an de i1?uierda a derec=a. 'or e$emplo, # < y < ? se
evalHa como (# < y) < ?.
8os operadores de asignaci-n y el operador condicional O7/R son asociativos por la derecha, lo ?ue
signi0ica ?ue las operaciones se e$ecutan de derec=a a i1?uierda. 'or e$emplo, # + y + ? se evalHa como # +
(y + ?).
8a precedencia y asociatividad pueden controlarse mediante el uso de par)ntesis. 'or e$emplo, # < y > ?
primero multiplica y por ? y despu)s suma el resultado a #, pero (# < y) > ? primero suma # e y, y despu)s
multiplica el resultado por ?.
+.2.2 4obrecarga de operadores
Todos los operadores unarios y binarios tienen implementaciones prede0inidas ?ue est(n disponibles
autom(ticamente en cual?uier expresi-n. &dem(s de las implementaciones prede0inidas, pueden introducirse
implementaciones de0inidas por el usuario si se incluyen declaraciones o&erator en las clases y estructuras
O[1".1"R. 8as implementaciones de operador de0inidas por el usuario siempre tienen precedencia sobre las
implementaciones de operador prede0inidasG s-lo se consideran las implementaciones de operador prede0inidas
cuando no existen implementaciones de operador de0inidas por el usuario ?ue puedan aplicarse, como se explica
en [*.2.3 y [*.2.4.
8os operadores !narios so/recarga/les sonG
< = @ A << == true -alse
&un?ue true y -alse no se utili1an expl5citamente en las expresiones Opor lo ?ue no se incluyen en la tabla de
prioridades de [*.2.1R, se consideran operadores por?ue se los llama en varios contextos de expresi-nG
expresiones booleanas O[*.1+R y expresiones ?ue implican el condicional O[*.13R y los operadores l-gicos
condicionales O[*.11R.
8os operadores /inarios so/recarga/les sonG
< = > . B F H G DD EE ++ @+ E D E+ D+
.-lo los operadores mencionados pueden sobrecargarse. En concreto, no es posible sobrecargar accesos a
miembros, llamadas a m)todos o los operadores +, FF, HH, 77, 7/, +E, c"ec(ed, unc"ec(ed, ne,, ty&eo-,
de-ault, as e is.
Cuando se sobrecarga un operador binario, el operador correspondiente de asignaci-n, si lo =ay, tambi)n se
sobrecarga de modo impl5cito. 'or e$emplo, una sobrecarga del operador > tambi)n es una sobrecarga del
operador >+. Esta categor5a se explica con m(s detalle en la secci-n [*.1#.2. 2ebe tenerse en cuenta ?ue el
propio operador de asignaci-n O+R no se puede sobrecargar. 7na asignaci-n siempre reali1a una simple copia bit
a bit de un valor en una variable.
8as operaciones de conversi-n de tipo, como (1)#, se sobrecargan proporcionando conversiones de0inidas por
el usuario O[#.4R.
El acceso a elementos, del tipo a4#5, no se considera un operador sobrecargable. En lugar de ello, se acepta la
indi1aci-n de0inida por el usuario mediante indi1adores O[1".+R.
En las expresiones, las re0erencias a los operadores se reali1an mediante la notaci-n de operadores y, en las
declaraciones, las re0erencias a los operadores se reali1an mediante la notaci-n 0uncional. En la tabla siguiente
se muestra la relaci-n entre las notaciones de operador y 0uncional para los operadores unarios y binarios. En la
primera entrada, op denota cual?uier operador de pre0i$o unario sobrecargable. En la segunda entrada, op denota
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1#1
Especificacin del lenguaje C#
los operadores de su0i$o unarios << y ==. En la primera entrada, op denota cual?uier operador binario
sobrecargable.
4otacin de operador 4otacin funcional
op # o&erator op(#)
# op o&erator op(#)
# op y o&erator op(# y)
8as declaraciones de operador de0inidas por el usuario siempre re?uieren ?ue por lo menos uno de los
par(metros sea del tipo de la clase o estructura ?ue contiene la declaraci-n del operador. 'or lo tanto, no es
posible ?ue un operador de0inido por el usuario tenga la misma 0irma ?ue un operador prede0inido.
8as declaraciones de operador de0inidas por el usuario no pueden modi0icar la sintaxis, precedencia o
asociatividad de un operador. 'or e$emplo, el operador . siempre es un operador binario, siempre tiene el nivel
de precedencia especi0icado en la [*.2.1 y siempre es asociativo por la i1?uierda.
&un?ue es posible ?ue un operador de0inido por el usuario realice cual?uier c(lculo ?ue le interese, no se
recomiendan las implementaciones ?ue generan resultados distintos de los ?ue intuitivamente pueden esperarse.
'or e$emplo, una implementaci-n de o&erator ++ debe comparar la igualdad de los dos operandos y devolver
un resultado bool apropiado.
8as descripciones de los operadores individuales desde la [*. a la [*.11 especi0ican las implementaciones
prede0inidas de los operadores y cual?uier regla adicional aplicable a cada operador. En las descripciones se
utili1an los t)rminos resol!ci,n de so/recarga de operador !nario, resol!ci,n de so/recarga de operador
/inario y prooci,n n!6rica, cuyas de0iniciones se encuentran en las siguientes secciones.
+.2.3 9esolucin de sobrecarga de operador unario
7na operaci-n con la estructura op # o # op, donde op es un operador unario sobrecargable, y # es una
expresi-n de tipo I, se procesa como sigueG
El con$unto de operadores candidatos de0inidos por el usuario suministrados por I para la operaci-n
o&erator op(#) se determina aplicando las reglas de la [*.2..
.i el con$unto de operadores candidatos de0inidos por el usuario no est( vac5o, se convierte en el con$unto de
operadores candidatos para la operaci-n. 2e lo contrario, las implementaciones del o&erator op unario
prede0inidas, incluidos los 0ormatos de elevaci-n, se convierten en el con$unto de operadores candidatos
para la operaci-n. 8as implementaciones prede0inidas de un operador dado se especi0ican en la descripci-n
del operador O[*. y [*.#R.
8as reglas de resoluci-n de las sobrecargas de [*.4.3 se aplican al con$unto de operadores candidatos para
seleccionar el me$or operador con respecto a la lista de argumentos (#), y este operador es el resultado del
proceso de resoluci-n de las sobrecargas. .i la resoluci-n de las sobrecargas no puede seleccionar un
operador Hnico id-neo, se producir( un error en tiempo de compilaci-n.
+.2.! 9esolucin de sobrecarga de operador binario
7na operaci-n con la estructura # op y, donde op es un operador binario sobrecargable, # es una expresi-n de
tipo I e y es una expresi-n de tipo `, se procesa como sigueG
.e determina el con$unto de operadores candidatos de0inidos por el usuario suministrado por I e ` para la
operaci-n o&erator op(# y). El con$unto consta de la uni-n de los operadores candidatos suministrados
por I y los operadores candidatos suministrados por `, cada uno de los cuales se determina mediante las
1#2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
reglas de [*.2.. .i I e ` son del mismo tipo, o si I e ` se derivan de un tipo base comHn, los operadores
candidatos compartidos s-lo se producen una ve1 en el con$unto combinado.
.i el con$unto de operadores candidatos de0inidos por el usuario no est( vac5o, se convierte en el con$unto de
operadores candidatos para la operaci-n. 2e lo contrario, las implementaciones del o&erator op binario
prede0inidas, incluidos los 0ormatos de elevaci-n, se convierten en el con$unto de operadores candidatos
para la operaci-n. 8as implementaciones prede0inidas de un operador dado se especi0ican en la descripci-n
del operador O[*.* a [*.11R.
8as reglas de resoluci-n de las sobrecargas de [*.4.3 se aplican al con$unto de operadores candidatos para
seleccionar el me$or operador con respecto a la lista de argumentos (# y), y este operador es el resultado
del proceso de resoluci-n de las sobrecargas. .i la resoluci-n de las sobrecargas no puede seleccionar un
operador Hnico id-neo, se producir( un error en tiempo de compilaci-n.
+.2.# ,peradores candidatos definidos por el usuario
2ados un tipo 1 y una operaci-n o&erator op('), donde op es un operador sobrecargable y ' es una lista de
argumentos, el con$unto de operadores candidatos de0inidos por el usuario suministrado por 1 para el o&erator
op(') se determina como sigueG
2eterminar el tipo 13. .i 1 es un tipo ?ue acepta valores 4788, 13 es su tipo subyacente, de lo contrario 13
es igual a 1.
'ara todas las declaraciones de o&erator op en 13 y todas los 0ormatos de elevaci-n de dic=os operadores,
si por lo menos un operador es aplicable O[R con respecto a la lista de argumentos ', entonces el con$unto de
operadores candidatos consta de todos los operadores aplicables en 13.
2e lo contrario, si 13 es object, el con$unto de operadores candidatos est( vac5o.
En otros casos, el con$unto de operadores candidatos suministrado por 13 es el con$unto de operadores
candidatos suministrado por la clase base directa de 13, o la clase base e0ectiva de 13 si 13 es un tipo de
par(metro.
+.2.$ (romociones num*ricas
7na promoci-n num)rica consiste en reali1ar de 0orma autom(tica determinadas conversiones impl5citas de los
operandos de los operadores num)ricos unarios y binarios prede0inidos. 8a promoci-n num)rica no es un
mecanismo exclusivo, sino m(s bien un e0ecto de la aplicaci-n de la resoluci-n de las sobrecargas a los
operadores prede0inidos. 8a promoci-n num)rica en concreto no a0ecta a la evaluaci-n de los operadores
de0inidos por el usuario, aun?ue dic=os operadores puedan implementarse de manera ?ue presenten e0ectos
similares.
Como e$emplo de promoci-n num)rica, consideremos las implementaciones prede0inidas del operador
binario >G
int o&erator >(int # int y);
uint o&erator >(uint # uint y);
long o&erator >(long # long y);
ulong o&erator >(ulong # ulong y);
-loat o&erator >(-loat # -loat y);
double o&erator >(double # double y);
decimal o&erator >(decimal # decimal y);
Cuando se aplican las reglas de resoluci-n de las sobrecargas O[*.4.3R a este con$unto de operadores, el e0ecto
?ue se produce es la selecci-n del primero de los operadores para el cual existen conversiones impl5citas de los
tipos de los operandos. 'or e$emplo, para la operaci-n b > s, donde b es un byte y s es s"ort, la resoluci-n de
las sobrecargas selecciona o&erator >(int int) como el me$or operador. 2e esta 0orma, el e0ecto
producido es ?ue b y s se convierten a int, y el tipo del resultado es int. 2e modo similar, para la operaci-n i
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1#3
Especificacin del lenguaje C#
> d, donde i es un int y d es double, la resoluci-n de sobrecargas selecciona o&erator >(double
double) como el me$or operador.
#.2.6.1 Promociones numricas unarias
7na promoci-n num)rica unaria se produce para los operandos de los operadores unarios prede0inidos <, C y A.
7na promoci-n num)rica unaria sencillamente es la conversi-n de operandos de tipo sbyte, byte, s"ort,
us"ort o c"ar al tipo int. &simismo, para el operador unario C, la promoci-n num)rica unaria convierte los
operandos del tipo uint al tipo long.
#.2.6.2 Promociones numricas binarias
8a promoci-n num)rica binaria se produce para los operandos de los operadores binarios prede0inidos <, C, >, .,
B, F, H, G, ++, @+, E, D, E+ y D+. 8a promoci-n num)rica binaria convierte impl5citamente los dos operandos a
un tipo comHn ?ue, en caso de los operadores no relacionales, tambi)n se convierte en el tipo del resultado de la
operaci-n. 7na promoci-n num)rica binaria consiste en aplicar las reglas siguientes, en el orden en ?ue se
exponen a?u5G
.i uno de los operandos es de tipo decimal, el otro se convierte al tipo decimal o se produce un error en
tiempo de compilaci-n si el otro operando es de tipo -loat o double.
/ bien, si uno de los operandos es de tipo double, el otro se convierte al tipo double.
/ bien, si uno de los operandos es de tipo -loat, el otro se convierte al tipo -loat.
/ bien, si uno de los operandos es de tipo ulong, el otro se convierte al tipo ulong o se produce un error en
tiempo de compilaci-n si el otro operando es de tipo sbyte, s"ort int o long.
/ bien, si uno de los operandos es de tipo long, el otro se convierte al tipo long.
/ bien, si uno de los operandos es de tipo uint y el otro es de tipo sbyte, s"ort o int, los dos operandos
se convierten al tipo long.
/ bien, si uno de los operandos es de tipo uint, el otro se convierte al tipo uint.
/ bien, los dos operandos se convierten al tipo int.
T)ngase en cuenta ?ue la primera regla no permite las operaciones ?ue me1clan el tipo decimal con los tipos
double y -loat. 8a regla se basa en ?ue no =ay conversiones impl5citas entre el tipo decimal y los tipos
double y -loat.
Tambi)n debe tenerse en cuenta ?ue un operando no puede ser de tipo ulong si el otro es de un tipo integral con
signo. El motivo es ?ue no existe un tipo integral ?ue pueda representar la gama completa de ulong as5 como
los tipos integrales con signo.
En los dos casos anteriores, puede utili1arse una expresi-n de conversi-n de tipos para convertir de 0orma
expl5cita uno de los operandos a un tipo ?ue sea compatible con el otro.
En el e$emplo
decimal 'dd*ercent(decimal # double &ercent) {
return # > (2.3 < &ercent . 233.3);
!
se produce un error de tiempo de compilaci-n por?ue un decimal no puede multiplicarse por un double. El
error se resuelve mediante la conversi-n expl5cita del segundo operando a decimal, de la manera siguienteG
decimal 'dd*ercent(decimal # double &ercent) {
return # > (decimal)(2.3 < &ercent . 233.3);
!
1## Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
+.2.+ ,peradores de eleacin
8os operadores de elevaci,n permiten utili1ar operadores prede0inidos y de0inidos por el usuario ?ue 0uncionan
en tipos de valor ?ue no aceptan valores 4788 con estructuras ?ue aceptan valores 4788 de dic=os tipos. 8os
operadores de elevaci-n se construyen a partir de operadores prede0inidos y de0inidos por el usuario ?ue
cumplen ciertos re?uisitos como se describe a continuaci-nG
'ara los operadores unarios
< << = == @ A
existe un 0ormato de elevaci-n de un operador si el operando y los tipos de resultado son tipos de valor ?ue
no aceptan valores 4788. El 0ormato de elevaci-n se construye agregando un modi0icador 7 Hnico al
operando y a los tipos de resultado. El operador de elevaci-n genera un valor 4788 si el operando es
4788. 2e lo contrario, el operador de elevaci-n desa$usta el operando, aplica el operador subyacente y
a$usta el resultado.
'ara los operadores binarios
< = > . B F H G DD EE
existe un 0ormato de elevaci-n si el operando y los tipos de resultado son todos tipos de valor ?ue no
aceptan valores 4788. El 0ormato de elevaci-n se construye agregando un modi0icador 7 Hnico a cada
operando y al tipo de resultado. El operador de elevaci-n genera un valor 4788 si uno o varios operandos
son 4788 Ouna de las excepciones son los operadores F y H del tipo bool7 como se describe en la secci-n
[*.1".3R. 2e lo contrario, el operador de elevaci-n desa$usta los operandos, aplica el operador subyacente y
a$usta el resultado.
'ara los operadores de igualdad
++ @+
existe un 0ormato de elevaci-n si los tipos de operando son tipos de valor ?ue no aceptan valores 4788 y si
el tipo de resultado es bool. El 0ormato de elevaci-n se construye agregando un modi0icador 7 Hnico a cada
tipo de operando. El operador de elevaci-n considera ?ue dos valores 4788 son iguales y ?ue un valor
4788 no es igual a un valor ?ue no es 4788. .i ninguno de los operandos es 4788, el operador de
elevaci-n desa$usta los operandos y aplica el operador subyacente para generar el resultado bool.
'ara los operadores relacionales
D E D+ E+
existe un 0ormato de elevaci-n si los tipos de operando son tipos de valor ?ue no aceptan valores 4788 y si
el tipo de resultado es bool. El 0ormato de elevaci-n se construye agregando un modi0icador 7 Hnico a cada
tipo de operando. El operador de elevaci-n genera el valor -alse si uno o ambos operandos es 4788. 2e
lo contrario, el operador de elevaci-n desa$usta los operandos y aplica el operador subyacente para generar
el resultado bool.
+.3 <=s;ueda de miembros
7na bHs?ueda de miembros es el proceso por el cual se determina el signi0icado de un nombre en el contexto de
un tipo. 7na bHs?ueda de miembros puede ocurrir como parte de la evaluaci-n de un nombre simple Osi%ple-
na%eR O[*..2R o un acceso a miembro O%e%-er-accessR O[*..4R en una expresi-n. .i se produce un acceso a
miembros O%e%-er-accessR o un nombre simple Osi%ple-na%eR como la expresi-n simple Osi%ple-e2pressionR
de una expresi-n de invocaci-n Oinvocation-e2pressionR O[*...1R, se dice ?ue el miembro se =a invocado.
.i un miembro es un m)todo o evento, o si es una constante, campo o propiedad de un tipo delegado O[1R, se
dice ?ue el miembro es invoca-le.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1#!
Especificacin del lenguaje C#
8a bHs?ueda de miembros no s-lo tiene en cuenta el nombre de un miembro, sino ?ue tambi)n considera el
nHmero de par(metros de tipo ?ue el miembro tiene independientemente de su accesibilidad. 'ara la bHs?ueda
de miembros, los m)todos gen)ricos y los tipos gen)ricos anidados tienen el nHmero de par(metros de tipo
indicado en sus respectivas declaraciones y el resto de los miembros no tienen ningHn par(metro tipo.
7na bHs?ueda de miembros de un nombre N con par(metros de tipo a en un tipo 1 se procesa como sigueG
En primer lugar, se determina un con$unto de miembros accesibles denominado NG
o .i 1 es un par(metro de tipo, el con$unto es la uni-n de con$untos de miembros accesibles
denominados N en cada uno de los tipos especi0icados como una restricci-n principal o secundaria
O[1".1.R para 1, $unto con el con$unto de miembros accesibles denominado N en object.
o 2e lo contrario, el con$unto est( 0ormado por todos los miembros accesibles O[3.R denominados N en 1,
incluidos los miembros =eredados y los miembros accesibles denominados N en object. .i 1 es un tipo
construido, el con$unto de miembros se obtiene sustituyendo los argumentos de tipo como se describe en
[1".3.2. .e excluyen del con$unto los miembros ?ue incluyen un modi0icador override.
& continuaci-n, si a es cero, se ?uitan todos los tipos anidados cuyas declaraciones incluyan par(metros de
tipo. .i a no es cero, se ?uitan todos los miembros con un nHmero di0erente de par(metros de tipo. Tenga en
cuenta ?ue cuando a es cero, no se ?uitan los m)todos ?ue tienen par(metros de tipo puesto ?ue el proceso
de in0erencia de tipos O[*.4.2R puede in0erir los argumentos de tipo.
& continuaci-n, si el miembro es invocado, se ?uitan del con$unto todos los miembros no invocables.
& continuaci-n, se ?uitan del con$unto los miembros ?ue est(n ocultos por otros miembros. 'or cada miembro
S.M del con$unto, donde S es el tipo en el ?ue se declara el miembro M, se aplican las siguientes reglasG
o .i M es un miembro de constante, campo, propiedad, evento, tipo o enumeraci-n, entonces se ?uitan del
con$unto todos los miembros declarados en un tipo base de S.
o .i M es una declaraci-n de tipo, entonces todos los miembros ?ue no sean declaraciones en un tipo base
de S se ?uitan del con$unto, se eliminar(n todas las declaraciones de tipo con el mismo nHmero de
par(metros de tipo ?ue M declarados en un tipo base de S.
o .i M es un m)todo, se ?uitar(n del con$unto todos los miembros ?ue no son m)todos declarados en un
tipo base de S.
& continuaci-n, se ?uitan del con$unto los miembros de inter0a1 ocultos por miembros de clase. Este paso
s-lo tiene e0ecto si 1 es un par(metro de tipo y 1 tiene una clase base e0ectiva di0erente de object y un
con$unto de inter0aces e0ectivas ?ue no est)n vac5as O[1".1.R. 'or cada miembro S.M del con$unto, donde S
es el tipo en el ?ue se declara el miembro M, se aplican las siguientes reglas si S es una declaraci-n de clase
di0erente de objectG
o .i M es un miembro de constante, campo, propiedad, evento, miembro de enumeraci-n o declaraci-n de
tipo, se ?uitan del con$unto todos los miembros declarados en una declaraci-n de inter0a1.
o .i M es un m)todo, entonces todos los miembros ?ue no son m)todos declarados en una declaraci-n de
inter0a1 se ?uitan del con$unto, as5 como todos los m)todos con la misma 0irma ?ue M declarados en una
declaraci-n de inter0a1.
'or Hltimo, una ve1 ?uitados los miembros ocultos, se determina el resultado de la bHs?uedaG
o .i el con$unto est( 0ormado por un solo miembro ?ue no es un m)todo, entonces este miembro es el
resultado de la bHs?ueda.
1#6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
o / bien, si el con$unto s-lo contiene m)todos, entonces este grupo de m)todos es el resultado de la
bHs?ueda.
o 2e lo contrario, la bHs?ueda es ambigua y se genera un error en tiempo de compilaci-n.
'ara bHs?uedas de miembros en tipos ?ue no sean inter0aces ni par(metros de tipo, y bHs?uedas de miembros en
inter0aces ?ue sean estrictamente de =erencia simple Ocada inter0a1 en la cadena de la =erencia tienen
exactamente cero o una inter0a1 base directaR, el e0ecto de las reglas de bHs?ueda es sencillamente ?ue los
miembros derivados ocultan a los miembros base del mismo nombre o la misma 0irma. Este tipo de bHs?uedas
de =erencia simple nunca son ambiguas. 8as ambigIedades ?ue pueden surgir de las bHs?uedas de miembros en
inter0aces de =erencia mHltiple se describen en la [13.2..
+.3.1 Tipos base
'ara los 0ines de bHs?ueda de miembros, se considera ?ue un tipo 1 tiene los siguientes tipos baseG
.i 1 es object, entonces 1 no tiene tipo base.
.i 1 es un tipo enum Oen%-t#peR, los tipos base de 1 son los tipos de clase System.)num,
System.Ualue1y&e y object.
.i 1 es un tipo struct Ostrct-t#peR, los tipos base de 1 son los tipos de clase System.Ualue1y&e y object.
.i 1 es un tipo de clase Oclass-t#peR, los tipos base de 1 son las clases base de 1, incluido el tipo de clase
object.
.i 1 es un tipo de inter0a1 Ointerface-t#peR, los tipos base de 1 son las inter0aces base de 1 y el tipo de clase
object.
.i 1 es un tipo de matri1 Oarra#-t#peR, los tipos base de 1 son los tipos de clase System.'rray y object.
.i 1 es un tipo delegado Odele&ate-t#peR, los tipos base de 1 son los tipos de clase System.6elegate y
object.
+.! &iembros de funcin
8os miembros de 0unci-n son miembros ?ue contienen instrucciones e$ecutables. .iempre son miembros de
tipos y no pueden ser miembros de espacios de nombres. C# de0ine las siguientes categor5as de miembros de
0unci-nG
%)todos
'ropiedades
Eventos
!ndi1adores
/peradores de0inidos por el usuario
Constructores de instancia
Constructores static
2estructores
Excepto para los destructores y los constructores est(ticos O?ue no se pueden invocar de manera expl5citaR, las
instrucciones contenidas en miembros de 0unci-n se e$ecutan mediante invocaciones de miembros de 0unci-n.
8a sintaxis concreta de la programaci-n de invocaciones de miembros de 0unci-n depende de la categor5a del
miembro concreto.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1#(
Especificacin del lenguaje C#
8a lista de argumentos O[*.4.1R de la invocaci-n de un miembro de 0unci-n proporciona valores reales o
re0erencias de variable a los par(metros del miembro de 0unci-n.
8as llamadas de m)todos, indi1adores, operadores y constructores de instancia utili1an la resoluci-n de
sobrecargas para determinar a ?u) miembro de un con$unto candidato de miembros de 0unci-n se debe llamar.
Este proceso se describe en [*.4.3.
7na ve1 identi0icado un miembro de 0unci-n concreto en tiempo de compilaci-n, posiblemente mediante
resoluci-n de sobrecargas, el proceso exacto de invocar el miembro de 0unci-n en tiempo de e$ecuci-n se
explica en [*.4.4.
En la tabla siguiente se resume el procesamiento ?ue tiene lugar en las construcciones ?ue implican las seis
categor5as de miembros de 0unci-n, ?ue se puede invocar expl5citamente. En la tabla, e, #, y y value indican
expresiones clasi0icadas como variables o valores, 1 indica una expresi-n clasi0icada como un tipo, V es el
nombre simple de un m)todo y * es el nombre simple de una propiedad.
Construccin Eje)plo +escripcin
!nvocaci-n de
m)todo
V(# y)
.e aplica la resoluci-n de sobrecargas para seleccionar el me$or
m)todo V de la clase o estructura contenedora. .e llama al
m)todo con la lista de argumentos (# y). .i el m)todo no es
static, la expresi-n de instancia es t"is.
1.V(# y)
.e aplica la resoluci-n de sobrecargas para seleccionar el me$or
m)todo V de la clase o estructura 1. .e produce un error en
tiempo de compilaci-n si el m)todo no es static. .e llama al
m)todo con la lista de argumentos (# y).
e.V(# y)
.e aplica la resoluci-n de sobrecargas para seleccionar el me$or
m)todo V de la clase, estructura o inter0a1 dada por el tipo de e.
.e produce un error en tiempo de compilaci-n si el m)todo es
static. .e llama al m)todo con la expresi-n de instancia e y
la lista de argumentos (# y).
&cceso a la
propiedad
*
.e invoca al descriptor de acceso get de la propiedad * en la
clase o estructura contenedora. .e produce un error en tiempo
de compilaci-n si * es de s-lo escritura. .i * no es static, la
expresi-n de instancia es t"is.
* + value
.e invoca al descriptor de acceso set de la propiedad * en la
clase o estructura contenedora con la lista de argumentos
(value). .e produce un error en tiempo de compilaci-n si *
es de s-lo lectura. .i * no es static, la expresi-n de instancia
es t"is.
1.*
.e invoca al descriptor de acceso get de la propiedad * en la
clase o estructura 1. .e produce un error en tiempo de
compilaci-n si * no es static o si es de s-lo escritura.
1.* + value
.e invoca al descriptor de acceso set de la propiedad * en la
clase o estructura 1 con la lista de argumentos (value). .e
produce un error en tiempo de compilaci-n si * no es static o
si es de s-lo lectura.
1#$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Construccin Eje)plo +escripcin
e.*
.e invoca al descriptor de acceso get de la propiedad * en la
clase, estructura o inter0a1 dada por el tipo de e con la
expresi-n de instancia e. .e produce un error en tiempo de
compilaci-n si * es static o si es de s-lo escritura.
e.* + value
.e invoca el descriptor de acceso set de la propiedad * en la
clase, estructura o inter0a1 dada por el tipo de e con la
expresi-n de instancia e y la lista de argumentos (value).
.e produce un error en tiempo de compilaci-n si * es static
o si es de s-lo lectura.
&cceso a
evento
) <+ value
.e invoca al descriptor de acceso add del evento ) en la clase
o estructura contenedora. .i ) no es static, la expresi-n de
instancia es t"is.
) =+ value
.e invoca al descriptor de acceso remove del evento ) en la
clase o estructura contenedora. .i ) no es static, la expresi-n
de instancia es t"is.
1.) <+ value
.e invoca al descriptor de acceso add del evento ) en la clase
o estructura 1. .i ) no es est(tico, se produce un error en
tiempo de compilaci-n.
1.) =+ value
.e invoca al descriptor de acceso remove del evento ) en la
clase o estructura 1. .i ) no es est(tico, se produce un error en
tiempo de compilaci-n.
e.) <+ value
.e invoca al descriptor de acceso add del evento ) en la clase,
estructura o inter0a1 dada por el tipo de e con la expresi-n de
instancia e. .i ) es est(tico, se produce un error en tiempo de
compilaci-n.
e.) =+ value
.e invoca al descriptor de acceso remove del evento ) en la
clase, estructura o inter0a1 dada por el tipo de e con la
expresi-n de instancia e. .i ) es est(tico, se produce un error en
tiempo de compilaci-n.
&cceso al
indi1ador
e4# y5
8a resoluci-n de sobrecarga se aplica para seleccionar el me$or
indi1ador de la clase, estructura o inter0a1 dada por el tipo de e.
El descriptor de acceso get del indi1ador se invoca con la
expresi-n de instancia e y la lista de argumentos (# y). .e
produce un error en tiempo de compilaci-n si el indi1ador es de
s-lo escritura.
e4# y5 +
value
8a resoluci-n de sobrecarga se aplica para seleccionar el me$or
indi1ador de la clase, estructura o inter0a1 dada por el tipo de e.
El descriptor de acceso set del indi1ador se invoca con la
expresi-n de instancia e y la lista de argumentos (# y
value). .e produce un error en tiempo de compilaci-n si el
indi1ador es de s-lo lectura.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1#"
Especificacin del lenguaje C#
Construccin Eje)plo +escripcin
!nvocaci-n de
operador
=#
.e aplica la resoluci-n de sobrecargas para seleccionar el me$or
operador unario de la clase, estructura o inter0a1 dada por el
tipo de #. .e invoca al operador seleccionado con la lista de
argumentos (#).
# < y
.e aplica la resoluci-n de sobrecargas, para seleccionar el
me$or operador binario de las clases o estructuras dadas por los
tipos de x e y. El operador seleccionado se invoca con la lista
de argumentos (# y).
!nvocaci-n de
constructores
de instancias
ne, 1(# y)
8a resoluci-n de sobrecarga se aplica para seleccionar el me$or
constructor de la clase o estructura 1. .e invoca al constructor
de instancias con la lista de argumentos (# y).
+.!.1 6istas de argumentos
Toda invocaci-n de delegado y miembro de 0unci-n incluye una lista de argumentos ?ue proporciona los valores
reales o las re0erencias de variable de los par(metros del miembro de 0unci-n. 8a sintaxis para especi0icar la
lista de argumentos de una invocaci-n de miembro de 0unci-n depende de la categor5a del miembro de 0unci-nG
'ara los constructores de instancia, m)todos y delegados, los argumentos se especi0ican como una lista de
argumentos Oar&%ent-listR, como se explica a continuaci-n.
'ara las propiedades, la lista de argumentos est( vac5a cuando se llama al descriptor de acceso get, y est(
0ormada por la expresi-n especi0icada como el operando derec=o del operador de asignaci-n cuando se
invoca el descriptor de acceso set.
'ara los eventos, la lista de argumentos est( 0ormada por la expresi-n especi0icada como el operando
derec=o del operador <+ o =+.
'ara los indi1adores, la lista de argumentos est( 0ormada por las expresiones especi0icadas entre los
corc=etes del acceso a indi1ador. Cuando se invoca el descriptor de acceso set, la lista de argumentos
incluye adem(s la expresi-n especi0icada como el operando derec=o del operador de asignaci-n.
'ara los operadores de0inidos por el usuario, la lista de argumentos est( 0ormada por el operando Hnico del
operador unario o los dos operandos del operador binario.
8os argumentos de propiedades O[1".*R, eventos O[1".8R y operadores de0inidos por el usuario O[1".1"R siempre
se pasan como par(metros de valor O[1".#.1.1R. 8os argumentos de indi1adores O[1".+R siempre se pasan como
par(metros de valor O[1".#.1.1R o matrices de par(metros O[1".#.1.4R. 8os par(metros de re0erencia y de salida
no se aceptan para estas categor5as de miembros de 0unci-n.
8os argumentos de llamadas a constructores de instancia, m)todos o delegados se especi0ican como una lista de
argumentos Oar&%ent-listRG
ar&%ent-list1
ar&%ent
ar&%ent-list ar&%ent
ar&%ent1
e2pression
re- varia-le-reference
out varia-le-reference
1!' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
7na lista de argumentos Oar&%ent-listR consta de uno o m(s argumentos Oar&%entsR, separados por comas.
Cada argumento puede tomar una de las siguientes 0ormasG
7na expresi-n Oe2pressionR, para indicar ?ue el argumento se pasa como un par(metro de valor O[1".#.1.1R.
8a palabra clave re- seguida por una re0erencia a variable Ovaria-le-referenceR O[.4R, para indicar ?ue el
argumento se pasa como un par(metro de re0erencia O[1".#.1.2R. 7na variable debe estar asignada de
manera de0initiva O[.3R antes de ?ue se pueda pasar como par(metro de re0erencia. 8a palabra clave out
seguida por una re0erencia a variable Ovaria-le-referenceR O[.4R, para indicar ?ue el argumento se pasa
como un par(metro de salida O[1".#.1.3R. 7na variable se considera asignada de manera de0initiva O[.3R
despu)s de una llamada a miembro de 0unci-n en la ?ue la variable se pasa como un par(metro de salida.
2urante el procesamiento de una invocaci-n de miembro de 0unci-n O[*.4.4R en tiempo de e$ecuci-n, las
re0erencias de expresiones o de variables de una lista de argumentos se evalHan por orden, de i1?uierda a
derec=a, como sigueG
'ara un par(metro de valor, se evalHa la expresi-n del argumento y se reali1a una conversi-n impl5cita
O[#.1R al tipo de par(metro correspondiente. El valor resultante pasa a ser el valor inicial del par(metro de
valor en la invocaci-n del miembro de 0unci-n.
'ara un par(metro de re0erencia o de salida, se evalHa la re0erencia de variable, mientras ?ue la ubicaci-n de
almacenamiento resultante pasa a ser la ubicaci-n de almacenamiento, representada por el par(metro de la
invocaci-n del miembro de 0unci-n. .i la re0erencia de variable dada como par(metro de re0erencia o de
salida es un elemento de matri1 de tipo de re0erencia Oreference-t#peR, se lleva a cabo una comprobaci-n en
tiempo de e$ecuci-n para garanti1ar ?ue el tipo de elemento de la matri1 es id)ntico al tipo del par(metro. .i
esta comprobaci-n produce un error, se inicia una excepci-n System.'rray1y&eMismatc")#ce&tion.
8os m)todos, indi1adores y constructores de instancia pueden declarar su par(metro situado m(s a la derec=a
como una matri1 de par(metros O[1".#.1.4R. Estos miembros de 0unci-n se invocan en su 0orma normal o en su
0orma expandida, dependiendo de lo ?ue sea aplicable O[*.4.3.1RG
.i se invoca un miembro de 0unci-n con una matri1 de par(metros en su 0orma normal, el argumento pasado
por la matri1 de par(metros debe ser una expresi-n Hnica de un tipo ?ue sea impl5citamente convertible
O[#.1R al tipo de la matri1 de par(metros. En este caso, la matri1 de par(metros actHa exactamente como un
par(metro de valor.
.i se invoca un miembro de 0unci-n con una matri1 de par(metros en su 0orma expandida, la invocaci-n
debe especi0icar cero o m(s argumentos para la matri1 de par(metros, donde cada argumento es una
expresi-n de un tipo impl5citamente convertible O[#.1R al tipo de los elementos de la matri1 de par(metros.
En este caso, la invocaci-n crea una instancia del tipo de la matri1 de par(metros con una longitud
correspondiente al nHmero de argumentos, iniciali1a los elementos de la instancia de matri1 con los valores
de los argumentos especi0icados y utili1a la instancia de matri1 reci)n creada como argumento real.
8as expresiones de una lista de argumentos siempre se evalHan en el orden en ?ue est(n escritas. 'or lo tanto,
el siguiente e$emploG
class 1est
{
static void V(int # int y int ?) {
System.Console.WriteLine("# + {3! y + {2! ? + {8!" # y ?);
!
static void Main() {
int i + 3;
V(i<< i<< i<<);
!
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1!1
Especificacin del lenguaje C#
produce el resultado
# + 3 y + 2 ? + 8
8as reglas de covarian1a matricial O[12.R permiten ?ue un valor de un tipo de matri1 '45 se trate como una
re0erencia a una instancia de un tipo matricial :45, siempre ?ue exista una conversi-n impl5cita de re0erencias
de : a '. 2ebido a estas reglas, si se pasa un elemento de matri1 de un tipo de re0erencia Oreference-t#peR como
un par(metro de re0erencia o de resultado, se lleva a cabo una comprobaci-n en tiempo de e$ecuci-n para
garanti1ar ?ue el tipo de elemento de la matri1 es id?ntico al tipo del par(metro. En el e$emplo
class 1est
{
static void V(re- object #) {...!
static void Main() {
object45 a + ne, object4235;
object45 b + ne, string4235;
V(re- a435); .. %(
V(re- b425); .. 'rray1y&eMismatc")#ce&tion
!
!
la segunda invocaci-n de V causa una excepci-n System.'rray1y&eMismatc")#ce&tion, puesto ?ue el
tipo del elemento de b es string y no object.
Cuando se llama a un miembro de 0unci-n con una matri1 de par(metros en su 0orma expandida, la invocaci-n
se trata exactamente como si se =ubiera insertado una expresi-n de creaci-n de matri1 con un iniciali1ador de
matri1 O[*..1".4R alrededor de los par(metros expandidos. 'or e$emplo, dada la declaraci-n
void V(int # int y &arams object45 args);
las invocaciones siguientes de la 0orma expandida del m)todo
V(23 83);
V(23 83 93 J3);
V(23 83 2 ""ello" 9.3);
se corresponden exactamente con
V(23 83 ne, object45 {!);
V(23 83 ne, object45 {93 J3!);
V(23 83 ne, object45 {2 ""ello" 9.3!);
En particular, debe tenerse en cuenta ?ue si se pasan cero argumentos como matri1 de par(metros, se crea una
matri1 vac5a.
+.!.2 Inferencia de tipos
Cuando se llama a un m)todo gen)rico sin especi0icar argumentos de tipo, una inferencia de tipos procesa los
intentos para deducir los argumentos de tipo para la llamada. 8a presencia de la in0erencia de tipo permite
utili1ar una sintaxis m(s adecuada para llamar a un m)todo gen)rico y permite ?ue el programador no
especi0i?ue in0ormaci-n de tipo redundante. 'or e$emplo, dada la declaraci-n de m)todoG
class C"ooser
{
static Oandom rand + ne, Oandom();
&ublic static 1 C"ooseD1E(1 -irst 1 second) {
return (rand.Ne#t(8) ++ 3)7 -irst/ second;
!
!
es posible invocar el m)todo C"oose sin especi0icar expl5citamente un argumento de tipoG
1!2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
int i + C"ooser.C"oose(K 829); .. Calls C"ooseDintE
string s + C"ooser.C"oose("-oo" "bar"); .. Calls C"ooseDstringE
%ediante la in0erencia de tipos, los argumentos de tipo int y string se determinan desde los argumentos al
m)todo.
8a in0erencia de tipo tiene lugar como parte del proceso en tiempo de compilaci-n de una invocaci-n de m)todo
O[*...1R y tiene lugar antes del paso de resoluci-n de sobrecarga de la invocaci-n. Cuando se especi0ica un
grupo de m)todos concreto en una invocaci-n del m)todo y no se especi0ican argumentos como parte de esta
invocaci-n, se aplica la in0erencia de tipo para cada m)todo gen)rico del grupo de m)todos. .i la in0erencia de
tipo es correcta, los argumentos de tipo se utili1an para determinar los tipos de argumentos para la resoluci-n de
sobrecarga subsiguiente. .i la resoluci-n de sobrecarga selecciona un m)todo gen)rico como el ?ue se va a
invocar, los argumentos de tipo ?ue se deducen se utili1an como argumentos de tipo reales para la invocaci-n. .i
no se puede reali1ar la in0erencia de tipo para un m)todo concreto, dic=o m)todo no participa en la resoluci-n de
sobrecarga. &un?ue se genere un error en la in0erencia de tipo, esto no provocar( un error en tiempo de
compilaci-n. .in embargo, en ocasiones esto lleva a un error en tiempo de compilaci-n cuando la resoluci-n de
sobrecarga no puede encontrar ningHn m)todo aplicable.
.i el nHmero de argumentos suministrados es di0erente del nHmero de par(metros del m)todo, la deducci-n
genera inmediatamente un error. En caso contrario, se asume ?ue el m)todo gen)rico tiene la siguiente 0irmaG
1r MDI2bInE(12 #2 b 1m #m)
Con una llamada a m)todo ?ue tiene la estructura M()2 b)m) la tarea de la in0erencia de tipos es buscar
argumentos de tipo Hnico S2bSn para cada uno de los par(metros de tipo I2bIn con el 0in de ?ue la llamada
MDS2bSnE()2b)m) sea v(lida.
2urante el proceso de in0erencia, cada par(metro de tipo Ii se 0i$a Ofi2edR a un tipo determinado Si o ?ueda sin
0i$ar Onfi2edR con un con$unto asociado de l5mites O-ondsR. Cada uno de los l5mites es algHn tipo 1.
!nicialmente cada variable de tipo Ii est( sin 0i$ar y tiene un con$unto vac5o de l5mites.
8a in0erencia de tipos tiene lugar en 0ases. En cada 0ase se intentar( in0erir argumentos de tipo para m(s
variables de tipo basados en los =alla1gos de la 0ase anterior. En la primera 0ase se reali1an algunas in0erencias
iniciales de l5mites, mientras ?ue en la segunda 0ase se 0i$an variables de tipo a tipos espec50icos y se in0ieren
m(s l5mites. Es posible ?ue la segunda 0ase se tenga ?ue repetir varias veces.
8ota1 la in0erencia de tipos tiene lugar no s-lo cuando se llama a un m)todo gen)rico. 8a in0erencia de tipos
para la conversi-n de grupos de m)todos se describe en la secci-n [ y c-mo buscar el me$or tipo comHn de un
con$unto de expresiones se describe en la secci-n [.
#.4.2.1 *a primera 3ase
'ara cada uno de los argumentos de m)todo )iG
.i )i es una 0unci-n an-nima, se reali1a una inferencia e2pl*cita de tipo de par,%etro O[R desde )i a 1i
En caso contrario, se reali1a una inferencia de tipos de resltado O[R desde )i a 1i
#.4.2.2 *a se"unda 3ase.
8a segunda 0ase se reali1a de la siguiente 0ormaG
Todas las variables de tipo sin fi>ar Ii ?ue no dependen de O[*.4.2.R ninguna Ij se 0i$an O[*.4.2.1"R.
.i no existen variables de este tipo, todas las variables de tipo sin fi>ar Ii se fi>an, y para ellas se
cumplen las siguientes condicionesG
o Hay al menos una variable de tipo Ij ?ue depende de Ii
o Ii tiene un con$unto vac5o de l5mites
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1!3
Especificacin del lenguaje C#
.i no existieran variables de este tipo y =ubiera variables de tipo sin fi>ar, no se producir5a
correctamente la in0erencia de tipos.
En caso contrario, si no =ubiera ninguna otra variable de tipo sin fi>ar, la in0erencia de tipos se
producir5a correctamente.
En caso contrario, para todos los argumentos )i con el tipo de par(metro correspondiente 1i donde los
tipos de resltado O[*.4.2.4R contienen variables de tipo sin fi>ar Ij pero los tipos de entrada O[*.4.2.3R
no, se produce una inferencia de tipos de resltado O[*.4.2.#R desde )i a 1i. & continuaci-n, se repite la
segunda 0ase.
#.4.2.3 :ipos de entrada.
.i ) es un grupo de m)todos o una 0unci-n an-nima con asignaci-n de tipo impl5cita y 1 es un tipo delegado o
tipo de (rbol de expresiones, entonces todos los tipos de par(metro de 1 son tipos de entrada de ) con el tipo 1.
#.4.2.4 :ipos de resultado.
.i ) es un grupo de m)todos o una 0unci-n an-nima y 1 es un tipo delegado o tipo de (rbol de expresiones,
entonces el tipo de resultado de 1 es un tipo de entrada de ) con el tipo 1.
#.4.2. (ependencia
7na variable de tipo sin fi>ar Ii depende directa%ente de una variable de tipo sin fi>ar Ij si para algHn
argumento )( con el tipo 1( Ij se produce un tipo de entrada de )( con el tipo 1( y Ii tiene lugar en un tipo de
resltado de )( con el tipo 1(.
Ij depende de Ii si Ij depende directa%ente de Ii o si Ii depende directa%ente de I( y I( depende de Ij. &s5,
Pdepende deQ es el cierre transitivo, ?ue no re0lexivo de Pdepende directa%ente deQ.
#.4.2.6 $n3erencias de tipo de resultado
7na inferencia de tipos de resltado se reali1a desde una expresi-n ) a un tipo 1 de la siguiente 0ormaG
.i ) es una 0unci-n an-nima con el tipo de resultado in0erido ; O[*.4.2.11R y 1 es un tipo delegado o tipo de
(rbol de expresiones con un tipo de resultado 1b, entonces se reali1a una inferencia de l*%ite inferior
O[*.4.2.+R desde ; a 1b.
En caso contrario, si ) es un grupo de m)todos y 1 es un tipo delegado o tipo de (rbol de expresiones con
tipos de par(metro 12b1( y el tipo de resultado 1b, y la resoluci-n de sobrecarga de ) con los tipos 12b1(
genera un Hnico m)todo con el tipo de resultado ;, entonces se reali1a una inferencia de l*%ite inferior
desde ; a 1b.
En caso contrario, si ) es una expresi-n con el tipo ;, entonces se reali1a una in0erencia de l5mite in0erior
desde ; a 1.
En caso contrario, no se reali1a ninguna in0erencia.
#.4.2.# $n3erencias e2plCcitas de tipo de parmetro
7na in0erencia expl5cita de tipo de par(metro se reali1a a partir de una expresi-n ) a un tipo 1 de la siguiente
0ormaG
.i ) es una 0unci-n an-nima con asignaci-n de tipo expl5cita ?ue tiene tipos de par(metro ;2b;( y 1 es el
tipo delegado o tipo de (rbol de expresiones con tipos de par(metro U2bU(, entonces para cada ;i se reali1a
una in0erencia exacta O[R desde ;i al Ui correspondiente.
1!# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
#.4.2.+ $n3erencias e2actas
7na in0erencia exacta desde un tipo ; a un tipo U se reali1a de la siguiente maneraG
.i U es una de las variables de tipo sin fi>ar Ii, entonces ; se agrega al con$unto de l5mites para Ii.
En caso contrario, si ; es un tipo de matri1 ;e4b5 y U es un tipo de matri1 Ue4b5 del mismo rango, se
reali1a la inferencia e2acta desde ;e a Ue.
En caso contrario, si U es un tipo construido CDU2bU(E y ; es un tipo construido CD;2b;(E, se reali1a la
inferencia e2acta para cada ;i al Ui correspondiente.
En caso contrario, no se reali1a ninguna in0erencia.
#.4.2.5 $n3erencias de lCmite in3erior
7na inferencia de l*%ite inferior desde un tipo ; a un tipo U se reali1a de la siguiente maneraG
.i U es una de las variables de tipo sin fi>ar Ii, entonces ; se agrega al con$unto de l5mites para Ii.
En caso contrario, si ; es un tipo de matri1 ;e4b5 y U es un tipo de matri1 Ue4b5 del mismo rango, o si ; es
un tipo de matri1 unidimensional ;e45 y U es $)numerableDUeE, $CollectionDUeE o $ListDUeE
entonces
o .i ;e es un tipo de re0erencia, se reali1a una inferencia de l*%ite inferior desde ;e a Ue
o En caso contrario, se reali1a una inferencia e2acta desde ;e a Ue
En caso contrario, si U es un tipo construido CDU2bU(E y =ay un con$unto Hnico de tipos CD;2b;(E tal ?ue
existe una conversi-n est(ndar impl5cita desde ; a CD;2b;(E, entonces se reali1a una inferencia e2acta
desde cada ;i al Ui correspondiente.
En caso contrario, no se reali1a ninguna in0erencia.
#.4.2.17 6i=ar tipos
7na variable de tipo sin fi>ar Ii con un con$unto de l5mites se 0i$a Ofi2edR de la siguiente 0ormaG
El con$unto de tipos de candidatos ;j se inicia como con$unto de todos los tipos en el con$unto de l5mites
para Ii.
& continuaci-n, se examina cada l5mite para IiG para cada l5mite ; de Ii se ?uitan todos los tipos ;j para los
?ue no =ay una conversi-n impl5cita est(ndar desde ; en el con$unto de candidatos.
.i entre los tipos de candidatos restantes ;j =ay un tipo Hnico U desde el ?ue =ay una conversi-n impl5cita
est(ndar para todos los dem(s tipos de candidatos, entonces Ii se 0i$a en U.
En caso contrario, la in0erencia de tipos no se reali1a correctamente.
#.4.2.11 :ipo de resultado in3erido
El tipo de res!ltado inferido de una 0unci-n an-nima V se utili1a durante la in0erencia de tipos y la resoluci-n
de sobrecargas. El tipo de resultado in0erido s-lo se puede determinar para una 0unci-n an-nima cuando se
conocen todos los tipos de resultados, ya sea por?ue se dan expl5citamente, a trav)s de una conversi-n de
0unci-n an-nima, o in0eridos durante una in0erencia de tipos en una invocaci-n de m)todo gen)rico envolvente.
El tipo de resultado in0erido se determina como sigueG
.i el cuerpo de V es una expresi-n Oe2pressionR, el tipo de resultado in0erido de V es el tipo de esa expresi-n.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1!!
Especificacin del lenguaje C#
.i el cuerpo de V es un blo?ue O-loc3R y el con$unto de expresiones en las instrucciones return del blo?ue
tiene un tipo comHn me$or 1 O[R, el tipo de resultado in0erido de V es 1.
En caso contrario, no se puede in0erir un tipo de resultado para ).
Como e$emplo de in0erencia de tipos con 0unciones an-nimas, considere el m)todo de extensi-n Select
declarado en la clase System.LinQ.)numerableG
names&ace System.LinQ
{
&ublic static class )numerable
{
&ublic static $)numerableD1OesultE SelectD1Source1OesultE(
t"is $)numerableD1SourceE source
VuncD1Source1OesultE selector)
{
-oreac" (1Source element in source) yield return selector(element);
!
!
!
&sumiendo ?ue el espacio de nombres System.LinQ se import- mediante una cl(usula using, y dada una
clase Customer con una propiedad Name de tipo string, el m)todo Select se puede usar para seleccionar los
nombres de una lista de clientes Ocsto%ersRG
ListDCustomerE customers + SetCustomerList();
$)numerableDstringE names + customers.Select(c +E c.Name);
8a invocaci-n del m)todo de extensi-n O[*...2R de Select se procesa reescribiendo la invocaci-n para una
invocaci-n de m)todo est(ticoG
$)numerableDstringE names + )numerable.Select(customers c +E c.Name);
2ado ?ue los argumentos de tipo no se especi0icaron expl5citamente, la in0erencia de tipos se utili1a para in0erir
los argumentos de tipo. En primer lugar, el argumento customers se relaciona con el par(metro source,
in0iriendo 1 para ?ue sea Customer. & continuaci-n, mediante el proceso de la inter0a1 de tipo de la 0unci-n
an-nima, se da a c el tipo Customer, y la expresi-n c.Name se relaciona con el tipo de resultado del par(metro
selector, in0iriendo S para ?ue sea string. &s5, la invocaci-n es e?uivalente a
SeQuence.SelectDCustomerstringE(customers (Customer c) +E c.Name)
y el resultado es el tipo $)numerableDstringE.
El siguiente e$emplo demuestra c-mo una in0erencia de tipo de la 0unci-n an-nima permite ?ue la in0ormaci-n
de tipo P0luyaQ entre los argumentos de una invocaci-n de m)todo gen)rico. 2ado el m)todoG
static P VDI`PE(I value VuncDI`E -2 VuncD`PE -8) {
return -8(-2(value));
!
Escriba la in0erencia de tipos para la invocaci-nG
double seconds + V("2/2K/93" s +E 1imeS&an.*arse(s) t +E t.1otalSeconds);
se procesa como sigueG en primer lugar, el argumento "2/2K/93" se relaciona con el par(metro value,
in0iriendo I para ?ue sea string. & continuaci-n, el par(metro de la primera 0unci-n an-nima, s, se da al tipo
in0erido string, y la expresi-n 1imeS&an.*arse(s) se relaciona con el tipo de resultado de -2, in0iriendo `
para ?ue sea System.1imeS&an. 'or Hltimo, el par(metro de la segunda 0unci-n an-nima, t, se da al tipo
in0erido System.1imeS&an, y la expresi-n t.1otalSeconds se relaciona con el tipo de resultado de -8,
in0iriendo P para ?ue sea double. &s5, el resultado de la invocaci-n es de tipo double.
1!6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
#.4.2.12 $n3erencia de tipos para la conversin de "rupos de mtodos
2e manera similar a las llamadas de m)todos gen)ricos, la in0erencia de tipos se debe aplicar tambi)n cuando un
grupo de m)todos M ?ue contiene un m)todo gen)rico se convierte a un tipo delegado 6 determinado (c#.#).
2ado un m)todo
1r MDI2bInE(12 #2 b 1m #m)
y el grupo de m)todos M ?ue se est( asignado al tipo delegado 6, la tarea de la in0erencia de tipos consiste en
buscar los argumentos de tipo S2bSn para ?ue la expresi-nG
MDS2bSnE
pasa a ser compatible O[1.1R con 6.
& di0erencia del algoritmo de in0erencia de tipos para llamadas de m)todos gen)ricos, en este caso s-lo =ay
tipos de argumentos, no e2presiones de argumentos. En particular, no =ay 0unciones an-nimas y por lo tanto no
=ay necesidad de varias 0ases de in0erencia.
En lugar de eso, todas las Ii se consideran sin fi>ar y se reali1a una inferencia de nivel inferior desde cada tipo
de argumento ;j de 6 al tipo de par(metro correspondiente 1j de M. .i para alguna de las Ii no se encuentra un
l5mite, la in0erencia de tipos no se reali1ar( correctamente. En caso contrario, todas las Ii se fi>an en las Si
correspondientes, ?ue son el resultado de la in0erencia de tipos.
#.4.2.13 8uscar el me=or tipo comDn de un con=unto de e2presiones
En algunos casos, un tipo comHn necesita in0erirse para un con$unto de expresiones. En particular, los tipos de
elementos de las matrices con asignaci-n de tipo impl5cita y los tipos de resultado de 0unciones an-nimas con
cuerpos de blo?ue O-loc3R se encuentra de esta manera.
2e 0orma intuitiva, dado un con$unto de expresiones )2b)m esta in0erencia deber5a ser e?uivalente a la llamada
de un m)todo
1r MDIE(I #2 b I #m)
con )i como argumentos.
%(s concretamente, la in0erencia se inicia con una variable de tipo sin fi>ar I. 8as inferencias de tipos de
resltados se reali1an desde cada )i a I. 'or Hltimo, I se 0i$a Ofi2edR y, si es correcto, el tipo resultante S es el
tipo comHn resultante para las expresiones. .i el tipo S existe, las excepciones no tienen el me$or tipo comHn.
+.!.3 9esolucin de sobrecargas
8a resoluci-n de sobrecargas es un mecanismo del tiempo de compilaci-n ?ue selecciona el me$or miembro de
0unci-n ?ue puede invocarse dados una lista de argumentos y un con$unto de miembros de 0unci-n candidatos.
8a resoluci-n de sobrecargas selecciona el miembro de 0unci-n al ?ue se invoca en los contextos siguientes
Hnicos en C#G
!nvocaci-n de un m)todo con nombre en una expresi-n de invocaci-n Oinvocation-e2pressionR O[R.
!nvocaci-n de un constructor de instancia con nombre en una expresi-n de creaci-n de ob$eto Oo->ect-
creation-e2pressionR O[*..1".1R.
!nvocaci-n de un descriptor de acceso a indi1ador mediante un acceso a elementos Oele%ent-accessR
O[*..#R.
8lamada de un operador prede0inido o de0inido por el usuario al ?ue se =ace re0erencia en una expresi-n
O[*.2.3 y [*.2.4R.
Cada uno de estos contextos de0ine el con$unto de miembros de 0unci-n candidatos y la lista de argumentos a su
propia manera, segHn se describe detalladamente en las secciones anteriormente citadas. 'or e$emplo, el
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1!(
Especificacin del lenguaje C#
con$unto de candidatos para una invocaci-n a un m)todo no incluye m)todos marcados con override O[*.3R y
los m)todos de una clase base no son candidatos si ningHn m)todo de una clase derivada es aplicable O[*...1R.
7na ve1 identi0icados los miembros de 0unci-n candidatos y la lista de argumentos, la selecci-n del me$or
miembro de 0unci-n es la misma en todos los casosG
2ado el con$unto de miembros de 0unci-n candidatos aplicables, se locali1a el me$or miembro de 0unci-n
del con$unto. .i el con$unto s-lo contiene un miembro de 0unci-n, )se es el me$or miembro. / bien, el me$or
miembro de 0unci-n es a?u)l ?ue es me$or ?ue todos los dem(s miembros de 0unci-n con respecto a la lista
de argumentos dada, a condici-n de ?ue cada miembro de 0unci-n se compare con todos los dem(s
miembros aplicando las reglas de la [*.4.3.2. .i no =ay exactamente un miembro de 0unci-n me$or ?ue
todos los dem(s, la llamada de un miembro de 0unci-n es ambigua y se produce un error durante la
compilaci-n.
En las secciones siguientes se de0ine el signi0icado exacto de los t)rminos ie/ro de f!nci,n aplica/le y
e1or ie/ro de f!nci,n.
#.4.3.1 Miembro de 3uncin aplicable
.e dice ?ue un miembro de 0unci-n es un ie/ro de f!nci,n aplica/le con respecto a una lista de argumentos
' si todas las condiciones siguientes son verdaderasG
El nHmero de argumentos de ' es id)ntico al nHmero de par(metros de la declaraci-n del miembro de
0unci-n.
'ara cada argumento de ', el modo de pasar los par(metros del argumento Oes decir, value, re- u outR es
id)ntico al modo de pasar los par(metros del par(metro correspondiente, yG
o para un par(metro de valor o una matri1 de par(metros, existe una conversi-n impl5cita O[R del
argumento al tipo del par(metro correspondiente, o
o para un par(metro re- u out, el tipo del argumento es id)ntico al tipo del par(metro correspondiente
Odespu)s de todo, un par(metro re- u out es un alias para el argumento ?ue se pasaR.
'ara un miembro de 0unci-n ?ue incluye una matri1 de par(metros, si el miembro es aplicable por las reglas
anteriores, se dice ?ue es aplicable en su fora noral. .i un miembro de 0unci-n ?ue incluye una matri1 de
par(metros no es aplicable en su 0orma normal, el miembro puede ser aplicable en su fora e.pandidaG
8a 0orma expandida se construye mediante el reempla1o de la matri1 de par(metros en la declaraci-n del
miembro de 0unci-n con cero o m(s par(metros de valor del tipo de los elementos de la matri1 de
par(metros, de 0orma ?ue el nHmero de argumentos de la lista de argumentos ' coincida con el nHmero total
de par(metros. .i ' tiene menos argumentos ?ue el nHmero de par(metros de tipo 0i$ado de la declaraci-n
del miembro de 0unci-n, la 0orma expandida del miembro de 0unci-n no puede construirse y, por lo tanto, no
es aplicable.
/ bien, la 0orma expandida es aplicable si, para cada argumento de ', el modo de pasar los par(metros del
argumento es id)ntico al modo de pasar los par(metros del par(metro correspondiente, y
o para un par(metro de valores 0i$ados o par(metro de valores creados por la expansi-n, existe una
conversi-n impl5cita O[#.1R del tipo del argumento al tipo del par(metro correspondiente, o
o para un par(metro re- u out, el tipo del argumento es id)ntico al tipo del par(metro correspondiente.
#.4.3.2 Me=or miembro de 3uncin
2ada una lista de argumentos ' con un con$unto de expresiones de argumento d )2, )8, ..., )N e y dos miembros
de 0unci-n aplicables M* y M^ con los tipos de par(metro d *2, *8, ..., *N e y d ^2, ^8, ..., ^N e, M* se de0ine como un
e1or ie/ro de f!nci,n ?ue M^ si
1!$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
para cada argumento, la conversi-n impl5cita de )I a ^I no es me$or ?ue la conversi-n impl5cita de )I a *I, y
por lo menos para un argumento, la conversi-n de )I a *I es me$or ?ue la conversi-n de )I a ^I.
Cuando se reali1a esta evaluaci-n, si M* o M^ es aplicable en su 0orma expandida, entonces *I o ^I =ace
re0erencia a un par(metro en la 0orma expandida de la lista de par(metros.
.i las secuencias de tipo de par(metros, {*2, *8, f, *N! y {^2, ^8, f, ^N! son id)nticas, se aplican las siguientes
reglas de desempate, por orden, con el 0in de determinar el me$or miembro de 0unci-n.
.i M* es un m)todo no gen)rico y M^ es un m)todo gen)rico, M* es me$or ?ue M^.
2e lo contrario, si M* es aplicable en su estructura normal y M^ tiene una matri1 &arams y s-lo es aplicable
en su 0orma expandida, M* es me$or ?ue M^.
2e lo contrario, si M* tiene menos par(metros declarados ?ue M^, M* es me$or ?ue M^. Esto puede ocurrir si
ambos m)todos tienen matrices &arams y s-lo son aplicables en sus 0ormas expandidas.
2e lo contrario, si M* tiene m(s tipos de par(metro espec50icos ?ue M^, M* es me$or ?ue M^. {O2, O8, f, ON! y
{S2, S8, f, SN! representar(n los tipos de par(metros no expandidos y para los ?ue no se crearon instancias
de M* y M^. 8os tipos de par(metro de M* son m(s espec50icos ?ue los de M^ si, para cada par(metro, OI no es
menos espec50ico ?ue SI y, para al menos un par(metro, OI es m(s espec50ico ?ue SIG
o 7n par(metro de tipo es menos espec50ico ?ue un par(metro ?ue no es de tipo.
o 2e manera recursiva, un tipo construido es m(s espec50ico ?ue otro tipo construido Ocon el mismo
nHmero de argumentos de tipoR si al menos un argumento de tipo es m(s espec50ico y no =ay argumentos
de tipo menos espec50icos ?ue el argumento de tipo correspondiente.
o 7n tipo de matri1 es m(s espec50ico ?ue otro tipo de matri1 Ocon el mismo nHmero de dimensionesR si el
tipo de elemento del primero es m(s espec50ico ?ue el tipo de elemento del segundo.
En caso contrario, si un miembro es un operador de no elevaci-n y el otro es un operador de elevaci-n, el de
no elevaci-n es me$or.
En caso contrario, ningHn miembro de 0unci-n es me$or.
#.4.3.3 Me=or conversin de e2presiones
2ada una conversi-n impl5cita C2 ?ue convierte de una expresi-n ) a un tipo 12, y una conversi-n impl5cita C8
?ue convierte de una expresi-n ) a un tipo 18, C2 es una conversi,n e1or ?ue C8 si 12 y 18 son tipos di0erentes y
al menos se cumple una de las condiciones siguientesG
)2 tiene un tipo S y la conversi-n desde S a 12 es me$or ?ue la conversi-n desde S a 18.
) es una 0unci-n an-nima, 12 y 18 son tipos delegados o tipos de (rbol de expresiones con listas de
par(metros id)nticos, y existe un tipo de resultado in0erido I para ) en el contexto de esa lista de par(metros
O[*.4.2.11R, y se cumple una de las condiciones siguientesG
12 tiene un tipo de resultado `2 y 18 tiene el tipo de resultado `8, y la conversi-n desde I a `2 es me$or
?ue la conversi-n desde S a `8
12 tiene un tipo de resultado ` y 18 devuelve valores void
#.4.3.4 Me=or conversin de tipos
2ada una conversi-n impl5cita C2 ?ue convierte de un tipo S a un tipo 12, y una conversi-n C8 ?ue convierte de
un tipo S a un tipo 18, C2 es una conversi,n e1or ?ue C8 si 12 y 18 son tipos di0erentes y se cumple al menos
una de las condiciones siguientesG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1!"
Especificacin del lenguaje C#
S es 12
Existe una conversi-n impl5cita desde 12 a 18 y no =ay una conversi-n impl5cita desde 18 a 12
12 es un tipo integral con signo y 18 es un tipo integral sin signo. ConcretamenteG
o 12 es sbyte y 18 es byte, us"ort, uint o ulong
o 12 es s"ort y 18 es us"ort, uint o ulong
o 12 es int y 18 es uint o ulong
o 12 es long y 18 es ulong
Tenga en cuenta ?ue as5 se puede de0inir una conversi-n para ?ue sea me$or incluso cuando no =aya ninguna
conversi-n impl5cita de0inida. 2e este modo, por e$emplo la conversi-n de la expresi-n X a s"ort es me$or
?ue la conversi-n de X a us"ort, por?ue una conversi-n de cual?uier tipo a s"ort es me$or ?ue una
conversi-n a us"ort.
#.4.3. !obrecar"a en clases "enricas
8as 0irmas declaradas deben ser Hnicas, pero es posible ?ue al sustituir argumentos de tipo se generen 0irmas
id)nticas. En estos casos, y gracias a las reglas de desempate de la resoluci-n de sobrecarga antes mencionada,
se escoge el miembro m(s especi0ico.
En los siguientes e$emplos se muestran sobrecargas v(lidas y no v(lidas segHn dic=a reglaG
inter-ace $2D1E {...!
inter-ace $8D1E {...!
class S2D;E
{
int V2(; u); .. %verload resulotion -or SDintE.V2
int V2(int i); .. ,ill &ic( non=generic
void V8($2D;E a); .. Ualid overload
void V8($8D;E a);
!
class S8D;UE
{
void V9(; u U v); .. Ualid but overload resolution -or
void V9(U v ; u); .. S8DintintE.V9 ,ill -ail
void VJ(; u $2DUE v); .. Ualid but overload resolution -or
void VJ($2DUE v ; u); .. S8D$2DintEintE.VJ ,ill -ail
void VK(; u2 $2DUE v8); .. Ualid overload
void VK(U v2 ; u8);
void VX(re- ; u); .. valid overload
void VX(out U v);
!
+.!.! Inocacin de miembros de funcin
En esta secci-n se explica el proceso ?ue tiene lugar en tiempo de e$ecuci-n para invocar un miembro de
0unci-n concreto. .e supone ?ue un proceso de tiempo de compilaci-n ya =a determinado el miembro concreto
?ue se invoca, posiblemente por la aplicaci-n de la resoluci-n de sobrecargas a un con$unto de miembros de
0unci-n candidatos.
'ara la descripci-n del proceso de invocaci-n, los miembros de 0unci-n se dividen en dos categor5asG
16' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
%iembros de 0unci-n est(ticos. .on constructores de instancia, m)todos est(ticos, descriptores de acceso a
propiedad est(ticos y operadores de0inidos por el usuario. 8os miembros de 0unci-n est(ticos siempre son
no virtuales.
%iembros de 0unci-n de instancia. .on m)todos de instancia, descriptores de acceso a propiedad de
instancia y descriptores de acceso a indi1ador. 8os miembros de 0unci-n de instancia son virtuales o no
virtuales, y siempre se les llama en una instancia concreta. 8a instancia se calcula mediante una expresi-n
de instancia, y ?ueda accesible dentro del miembro de 0unci-n como t"is O[*..*R.
El procesamiento en tiempo de e$ecuci-n de una invocaci-n de miembro de 0unci-n re?uiere los pasos
siguientes, donde M es el miembro de 0unci-n y, si M es un miembro de instancia, ) es la expresi-n de instanciaG
.i M es un miembro de 0unci-n est(ticoG
o 8a lista de argumentos se evalHa segHn lo descrito en [*.4.1.
o .e invoca M.
.i M es un miembro de 0unci-n de instancia declarado en un tipo de valor Ovale-t#peRG
o .e evalHa ). .i esta evaluaci-n da lugar a una excepci-n, no se e$ecutan nuevos pasos.
o .i ) no se clasi0ica como variable, se crea una variable local temporal con el estilo de ) y el valor de )
se asigna a esa variable. Entonces ) se vuelve a clasi0icar como re0erencia para esa variable local
temporal. 8a variable temporal est( accesible como t"is dentro de M, pero no de otra 0orma. 'or lo
tanto, solamente si ) es una variable verdadera es posible ?ue el proceso llamante observe los cambios
?ue M e0ectHa en t"is.
o 8a lista de argumentos se evalHa segHn lo descrito en [*.4.1.
o .e invoca M. 8a variable a ?ue =ace re0erencia ) pasa a ser la variable a ?ue =ace re0erencia t"is.
.i M es un miembro de 0unci-n de instancia declarado en un tipo de re0erencia Oreference-t#peRG
o .e evalHa ). .i esta evaluaci-n da lugar a una excepci-n, no se e$ecutan nuevos pasos.
o 8a lista de argumentos se evalHa segHn lo descrito en [*.4.1.
o .i el tipo de ) es un tipo de valor Ovale-t#peR, se reali1a una conversi-n boxing O[4.3.1R para convertir
) al tipo object, y ) se considera de tipo object en los pasos siguientes. En este caso, M s-lo podr5a
ser un miembro de System.%bject.
o .e comprueba la valide1 del valor de ). .i el valor de ) es null, se inicia una excepci-n
System.NullOe-erence)#ce&tion y no se e$ecutan nuevos pasos.
o 8a implementaci-n del miembro de 0unci-n ?ue se va a invocar se determina de la siguiente 0ormaG
.i el tipo de tiempo de compilaci-n de ) es una inter0a1, el miembro de 0unci-n ?ue =ay ?ue invocar
es la implementaci-n de M ?ue proporciona el tipo de tiempo de e$ecuci-n de la instancia a la ?ue
=ace re0erencia ). Este miembro de 0unci-n se determina aplicando las reglas de asignaci-n de
inter0aces O[13.4.4R para determinar la implementaci-n de M proporcionada por el tipo en tiempo de
e$ecuci-n de la instancia a la ?ue =ace re0erencia ).
2e lo contrario, si M es un miembro de 0unci-n virtual, el miembro de 0unci-n ?ue =ay ?ue invocar
es la implementaci-n de M ?ue proporciona el tipo de tiempo de e$ecuci-n de la instancia a la ?ue
=ace re0erencia ) Este miembro de 0unci-n se determina aplicando las reglas para determinar la
implementaci-n m(s derivada O[1".#.3R de M relativa al tipo en tiempo de e$ecuci-n de la instancia a
la ?ue =ace re0erencia ).
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 161
Especificacin del lenguaje C#
2e lo contrario, M ser( un miembro de 0unci-n no virtual y el miembro de 0unci-n ?ue =abr( ?ue
invocar ser( el propio M.
o .e invoca la implementaci-n del miembro de 0unci-n determinada en el paso anterior. El ob$eto al ?ue
=ace re0erencia ) se convierte en el ob$eto al ?ue =ace re0erencia t"is.
#.4.4.1 $nvocaciones en instancias de conversin bo2in"
7n miembro de 0unci-n implementado en un tipo de valor Ovale-t#peR puede invocarse mediante una instancia
de conversi-n boxing del tipo de valor en las situaciones siguientesG
.i el miembro de 0unci-n es un override de un m)todo =eredado del tipo object y se invoca mediante
una expresi-n de instancia de tipo object.
.i el miembro de 0unci-n es una implementaci-n de un miembro de 0unci-n de inter0a1 y se invoca
mediante una expresi-n de instancia de un tipo de inter0a1 Ointerface-t#peR.
.i se invoca el miembro de 0unci-n a trav)s de un delegado.
En estas situaciones, se considera ?ue la instancia convertida mediante boxing contiene una variable de tipo de
valor Ovale-t#peR, y esta variable se convierte en la variable a la ?ue se =ace re0erencia con t"is dentro de la
invocaci-n del miembro de 0unci-n. Esto, concretamente, signi0ica ?ue cuando se invoca un miembro de
0unci-n en una instancia convertida mediante boxing, el miembro de 0unci-n puede modi0icar el valor contenido
en dic=a instancia.
+.# E"presiones primarias
8as expresiones primarias incluyen las 0ormas m(s simples de las expresiones.
pri%ar#-e2pression1
pri%ar#-no-arra#-creation-e2pression
arra#-creation-e2pression
pri%ar#-no-arra#-creation-e2pression1
literal
si%ple-na%e
parenthesi0ed-e2pression
%e%-er-access
invocation-e2pression
ele%ent-access
this-access
-ase-access
post-incre%ent-e2pression
post-decre%ent-e2pression
o->ect-creation-e2pression
dele&ate-creation-e2pression
anon#%os-o->ect-creation-e2pression
t#peof-e2pression
chec3ed-e2pression
nchec3ed-e2pression
defalt-vale-e2pression
anon#%os-%ethod-e2pression
8as expresiones primarias se dividen en expresiones de creaci-n de matrices Oarra#-creation-e2pressionsR y
expresiones primarias sin creaci-n de matrices Opri%ar#-no-arra#-creation-e2pressionsR. .i las expresiones de
162 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
creaci-n de matrices se tratan de esta manera, en lugar de enumerarlas $unto con todas las 0ormas de expresiones
simples, se permite ?ue la gram(tica des=abilite potencialmente c-digos con0usos comoG
object o + ne, int495425;
?ue, de otra manera, podr5a interpretarse como
object o + (ne, int495)425;
+.#.1 6iterales
7na expresi-n primaria Opri%ar#-e2pressionR compuesta por un literal OliteralR O[2.4.4R se clasi0ica como un
valor.
+.#.2 1ombres sencillos
7n nombre simple Osi%ple-na%eR est( 0ormado por un identi0icadorV opcionalmente le sigue una lista de
argumentos de tipoG
si%ple-na%e1
identifier t#pe-ar&%ent-list
opt
7n nombre simple Osi%ple-na%eR tiene la estructura $ o la estructura $D'2 ... 'aE, donde $ es un solo
identi0icador y D'2 ... 'aE una lista de argumentos de tipo Ot#pe-ar&%ent-listR opcionales. .i no se
especi0ica ninguna lista de argumentos de tipo Ot#pe-ar&%ent-listR, se considera ?ue a es cero. El nombre
simple Osi%ple-na%eR se evalHa y clasi0ica como sigueG
.i a es cero y el nombre simple Osi%ple-na%eR aparece dentro de un blo?ue O-loc3R y si el espacio de
declaraci-n de variables locales O[3.3R del blo?ue O-loc3R Oo de un blo?ue contenedorR contiene una variable
local, un par(metro o una constante con el nombre $, el nombre simple Osi%ple-na%eR =ace re0erencia a
dic=o par(metro, constante o variable local y se clasi0ica como una variable o un valor.
.i a es cero y el nombre simple Osi%ple-na%eR aparece dentro del cuerpo de una declaraci-n de m)todo
gen)rico y si dic=a declaraci-n incluye un par(metro de tipo con el nombre $, el nombre simple Osi%ple-
na%eR =ace re0erencia a dic=o par(metro de tipo.
2e lo contrario, para cada tipo de instancia 1 O[1".3.1R, empe1ando por el tipo de instancia de la declaraci-n
de tipo envolvente inmediata y continuando con el tipo de instancia de cada clase envolvente o declaraci-n
de estructura Osi las =ubieraRG
o .i a es cero y la declaraci-n de 1 incluye un par(metro de tipo con el nombre $, el nombre simple
Osi%ple-na%eR =ace re0erencia a dic=o par(metro de tipo.
o 2e lo contrario, si la bHs?ueda de un miembro O[*.3R de $ en 1 con argumentos de tipo a da un
resultadoG
.i 1 es el tipo de instancia de la clase envolvente o del tipo struct inmediato y la bHs?ueda identi0ica
uno o m(s m)todos, el resultado es un grupo de m)todos con una expresi-n de instancia asociada de
t"is. .i se especi0ic- una lista de argumentos de tipo, se utili1a para llamar a un m)todo gen)rico
O[*...1R.
2e lo contrario, si 1 es el tipo de instancia de la clase envolvente o del tipo struct inmediato, si la
bHs?ueda identi0ica un miembro de instancia, y si la re0erencia ocurre dentro del blo?ue O-loc3R de
un constructor de instancia, un m)todo de instancia o un descriptor de acceso a instancia, el
resultado es el mismo ?ue un acceso a miembros O[R de la 0orma t"is.$. Esto s-lo puede ocurrir
cuando a es cero.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 163
Especificacin del lenguaje C#
2e lo contrario, el resultado es el mismo ?ue un acceso a miembros O[*..4R con la estructura 1.$ o
1.$D'2 ... 'aE. En este caso, se produce un error durante la compilaci-n si el nombre simple
Osi%ple-na%eR =ace re0erencia a un miembro de instancia.
2e lo contrario, para cada espacio de nombres N, empe1ando por el espacio de nombres en el ?ue se produce
el nombre simple Osi%ple-na%eR, continuando por cada uno de los espacios de nombres envolventes Osi los
=ubieraR y terminando por el espacio de nombres global, se ir(n evaluando los siguientes pasos =asta ?ue se
localice una entidadG
o .i a es cero e $ es el nombre de un espacio de nombres en NG
.i la ubicaci-n donde tiene lugar el nombre simple Osi%ple-na%eR tiene una declaraci-n de espacio
de nombres para N y la declaraci-n de espacio de nombres contiene una directiva de alias extern
Oe2tern-alias-directiveR o una directiva de alias using Osin&-alias-directiveR ?ue asocia el nombre $
con un nombre de espacio de nombres o de tipo, el nombre simple Osi%ple-na%eR es ambiguo y se
genera un error en tiempo de compilaci-n.
2e lo contrario, el nombre simple Osi%ple-na%eR =ace re0erencia al espacio de nombres denominado
$ en N.
o 2e lo contrario, si N contiene un tipo accesible con un nombre $ y par(metros de tipo aG
.i a es cero y la ubicaci-n donde tiene lugar el nombre simple Osi%ple-na%eR tiene una declaraci-n
de espacio de nombres para N y la declaraci-n de espacio de nombres contiene una directiva de alias
extern Oe2tern-alias-directiveR o una directiva de alias using Osin&-alias-directiveR ?ue asocia el
nombre $ con un nombre de espacio de nombres o de tipo, el nombre simple Osi%ple-na%eR es
ambiguo y se genera un error en tiempo de compilaci-n.
2e lo contrario, el nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR =ace
re0erencia al tipo construido con los argumentos de tipo dados.
o 2e lo contrario, si la ubicaci-n donde tiene lugar el nombre simple Osi%ple-na%eR tiene lugar en una
declaraci-n de espacio de nombres para NG
.i a es cero y la declaraci-n de espacio de nombres contiene una directiva de alias extern Oe2tern-
alias-directiveR o una directiva de alias using Osin&-alias-directiveR ?ue asocia el nombre $ a un
espacio de nombres o tipo importado, entonces el nombre simple Osi%ple-na%eR =ace re0erencia a
dic=o espacio de nombres o tipo.
2e lo contrario, si los espacios de nombres importados por las directivas using de espacio de
nombres Osin&-na%espace-directivesR de la declaraci-n del espacio de nombres contienen
exactamente un Hnico tipo con el nombre $ y par(metros de tipo a, entonces el nombre simple
Osi%ple-na%eR =ace re0erencia al tipo construido con los argumentos de tipo dados.
2e lo contrario, si los espacios de nombres importados por las directivas using de espacio de
nombres Osin&-na%espace-directivesR de la declaraci-n del espacio de nombres contienen m(s de
un tipo con el nombre $ y par(metros de tipo a, entonces el nombre simple Osi%ple-na%eR ser(
ambiguo y se producir( un error.
Tenga en cuenta ?ue este paso es paralelo al paso correspondiente en el procesamiento de un nombre de
espacio de nombres o de tipo Ona%espace-or-t#pe-na%eR O[3.8R.
2e lo contrario, el nombre simple Osi%ple-na%eR no est( de0inido y se produce un error en tiempo de
compilaci-n.
16# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
#..2.1 !i"ni3icado invariable en blo0ues
'or cada repetici-n de un identi0icador dado como un nombre simple Osi%ple-na%eR en una expresi-n o
declarador, dentro del espacio de declaraci-n de la variable local O[3.3R ?ue envuelve inmediatamente a dic=a
repetici-n, todas las dem(s repeticiones del mismo identi0icador como nombre simple Osi%ple-na%eR en una
expresi-n o declarador debe =acer re0erencia a la misma entidad. Esta regla asegura ?ue el signi0icado de un
nombre siempre es el mismo dentro de un blo?ue, blo?ue s9itc=, instrucci-n 0orB, 0oreac=B o usingB, o 0unci-n
an-nima determinada.
En el e$emplo
class 1est
{
double #;
void V(bool b) {
# + 2.3;
i- (b) {
int #;
# + 2;
!
!
!
se produce un error durante la compilaci-n por?ue # =ace re0erencia a varias entidades dentro del blo?ue
externo Ocuya extensi-n incluye el blo?ue anidado de la instrucci-n i-R. 'or el contrario, el e$emploG
class 1est
{
double #;
void V(bool b) {
i- (b) {
# + 2.3;
!
else {
int #;
# + 2;
!
!
!
est( permitido por?ue el nombre # nunca se utili1a en el blo?ue externo.
2ebe tenerse en cuenta ?ue la regla del signi0icado invariable s-lo se aplica a los nombres simples. Es
per0ectamente v(lido ?ue el mismo identi0icador tenga un signi0icado como nombre simple y otro distinto como
operando derec=o de un acceso a miembros O[*..4R. 'or e$emploG
struct *oint
{
int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
!
El e$emplo anterior ilustra un modelo comHn de uso de los nombres de campos como nombres de par(metros en
un constructor de instancia. En el e$emplo, los nombres simples # e y =acen re0erencia a los par(metros, pero
ello no impide ?ue expresiones de acceso a miembros como t"is.# y t"is.y obtengan acceso a los campos.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 16!
Especificacin del lenguaje C#
+.#.3 E"presiones entre par*ntesis
7na expresi-n entre par)ntesis Oparenthesi0ed-e2pressionR consiste en una expresi-n Oe2pressionR encerrada
entre par)ntesis.
parenthesi0ed-e2pression1
( e2pression )
7na expresi-n entre par)ntesis Oparenthesi0ed-e2pressionR se evalHa mediante la evaluaci-n de la expresi-n
Oe2pressionR contenida entre los par)ntesis. .i la expresi-n Oe2pressionR entre par)ntesis denota un espacio de
nombres, un tipo o un grupo de m)todos, se produce un error durante la compilaci-n. 2e lo contrario, el
resultado de la expresi-n entre par)ntesis Oparenthesi0ed-e2pressionR es el resultado de la evaluaci-n de la
expresi-n Oe2pressionR contenida.
+.#.! 'cceso a miembros
7n acceso a miembro O%e%-er-accessR consiste en una expresi-n primaria Opri%ar#-e2pressionR, un tipo
prede0inido Opredefined-t#peR o un miembro de alias completo O6alified-alias-%e%-erR seguido por un s5mbolo
Oto6enR P.Q y, despu)s, por un identi0icador OidentifierRV opcionalmente, a este Hltimo puede seguirle una lista de
argumentos de tipo Ot#pe-ar&%ent-listR.
%e%-er-access1
pri%ar#-e2pression . identifier t#pe-ar&%ent-list
opt
predefined-t#pe . identifier t#pe-ar&%ent-list
opt
6alified-alias-%e%-er . identificador
predefined-t#pe1 no de
bool byte c"ar decimal double -loat int long
object sbyte s"ort string uint ulong us"ort
8a producci-n de miembros alias completos O6alified-alias-%e%-erR se de0ine en la secci-n [+.*.
7n acceso a miembro O%e%-er-accessR tiene la estructura ).$ o la estructura ).$D'2 ... 'aE, donde ) es una
expresi-n primaria, $ es un solo identi0icador y D'2 ... 'aE una lista de argumentos de tipo Ot#pe-ar&%ent-
listR opcional. .i no se especi0ica ninguna lista de argumentos de tipo Ot#pe-ar&%ent-listR, se considera ?ue a es
cero. El acceso a miembro O%e%-er-accessR se evalHa y clasi0ica como sigueG
.i a es cero y ) es un espacio de nombres y ) contiene un espacio de nombres anidado con el nombre $, el
resultado es dic=o espacio de nombres.
2e lo contrario, si ) es un espacio de nombres y ) contiene un tipo accesible con el nombre $ y par(metros
de tipo a, el resultado es el tipo construido con los argumentos de tipo dados.
.i ) es un tipo prede0inido Opredefined-t#peR o una expresi-n primaria Opri%ar#-e2pressionR clasi0icada
como un tipo, si ) no es un par(metro de tipo y si una bHs?ueda de miembros O[*.3R de $ en ) con
par(metros de tipo a produce una coincidencia, entonces ).$ se evalHa y clasi0ica como sigueG
o .i $ identi0ica un tipo, el resultado es el tipo construido con los argumentos de tipo dados.
o .i $ identi0ica uno o varios m)todos, entonces el resultado es un grupo de m)todos sin una expresi-n de
instancia asociada. .i se especi0ic- una lista de argumentos de tipo, se utili1a para llamar a un m)todo
gen)rico O[*...1R.
o .i $ identi0ica una propiedad static, entonces el resultado es un acceso a propiedad sin una expresi-n
de instancia asociada.
o .i $ identi0ica un campo staticG
166 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
.i el campo es readonly y la re0erencia ocurre 0uera del constructor est(tico de la clase o
estructura donde est( declarado el campo, entonces el resultado es un valor, concretamente, el valor
del campo est(tico $ de ).
En caso contrario, el resultado es una variable, en concreto, el campo est(tico $ en ).
o .i $ identi0ica un evento staticG
.i la re0erencia ocurre dentro de la clase o estructura donde est( declarado el evento, y )ste se =a
declarado sin declaraciones de descriptor de acceso a evento Oevent-accessor-declarationsR O[1".8R,
entonces ).$ se procesa exactamente como si $ 0uera un campo est(tico.
/ bien, el resultado es un acceso a evento sin una expresi-n de instancia asociada.
o .i $ identi0ica una constante, entonces el resultado es un valor, en concreto el valor de la constante.
o .i $ identi0ica un miembro de enumeraci-n, entonces el resultado es un valor, a saber, el valor de dic=o
miembro de enumeraci-n.
o 2e lo contrario, ).$ ser( una re0erencia de miembro no v(lida y se producir( un error en tiempo de
compilaci-n.
.i ) es un acceso a propiedad, un acceso a indi1ador, una variable o un valor, cuyo tipo es 1, y una
bHs?ueda de miembros O[R de $ en 1 con argumentos de tipo a produce una coincidencia, entonces ).$ se
evalHa y clasi0ica como sigueG
o En primer lugar, si ) es un acceso a propiedad o a indi1ador, entonces se obtiene el valor del acceso a
propiedad o a indi1ador O[*.1.1R y ) se reclasi0ica como un valor.
o .i $ identi0ica uno o varios m)todos, entonces el resultado es un grupo de m)todos con una expresi-n de
instancia asociada de ). .i se especi0ic- una lista de argumentos de tipo, se utili1a para llamar a un
m)todo gen)rico O[*...1R.
o .i $ identi0ica una propiedad de instancia, entonces el resultado es un acceso a propiedad con una
expresi-n de instancia asociada de ).
o .i 1 es un tipo de clase Oclass-t#peR e $ identi0ica un campo de instancia de dic=o tipo de claseG
.i el valor de ) es null, se inicia una excepci-n System.NullOe-erence)#ce&tion.
2e lo contrario, si el campo es readonly y la re0erencia ocurre 0uera de un constructor de instancia
de la clase donde est( declarado el campo, entonces el resultado es un valor, concretamente, el valor
del campo $ en el ob$eto al ?ue =ace re0erencia ).
2e lo contrario, el resultado es una variable, en concreto, el campo $ en el ob$eto al ?ue =ace
re0erencia ).
o .i 1 es un tipo struct Ostrct-t#peR e $ identi0ica un campo de instancia de dic=o tipoG
.i ) es un valor o si el campo es readonly y la re0erencia ocurre 0uera de un constructor de
instancia de la estructura donde est( declarado el campo, entonces el resultado es un valor,
concretamente, el valor del campo $ en la instancia de estructura dada por ).
/ bien, el resultado es una variable, en concreto, el campo $ en la instancia de estructura dada
por ).
o .i $ identi0ica un evento de instanciaG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 16(
Especificacin del lenguaje C#
.i la re0erencia ocurre dentro de la clase o estructura donde est( declarado el evento, y )ste se =a
declarado sin declaraciones de descriptor de acceso a evento Oevent-accessor-declarationsR O[1".8R,
entonces ).$ se procesa exactamente como si $ 0uera un campo de instancia.
2e lo contrario, el resultado es un acceso a evento con una expresi-n de instancia asociada de ).
En caso contrario, se reali1a un intento de procesar ).$ como una invocaci-n del m)todo de extensi-n
O[*...2R. .i esto da error, ).$ ser( una re0erencia de miembro no v(lida y se producir( un error en tiempo
de compilaci-n.
#..4.1 Eombres simples y nombres de tipos idnticos
En un acceso a miembros con la estructura ).$, si ) es un solo identi0icador y el signi0icado de ) como nombre
simple Osi%ple-na%eR O[*..2R es una constante, un campo, una propiedad, una variable local o un par(metro del
mismo tipo ?ue el signi0icado de ) como nombre de tipo Ot#pe-na%eR O[3.8R, entonces se permiten los dos
posibles signi0icados de ). 8os dos posibles signi0icados de ).$ nunca son ambiguos, puesto ?ue $
necesariamente tiene ?ue ser un miembro del tipo ) en los dos casos. Es decir, la regla sencillamente permite
el acceso a los miembros est(ticos y tipos anidados de ) donde, de otra 0orma, se =abr5a producido un error en
tiempo de compilaci-n. 'or e$emploG
struct Color
{
&ublic static readonly Color W"ite + ne, Color(...);
&ublic static readonly Color :lac( + ne, Color(...);
&ublic Color Com&lement() {...!
!
class '
{
&ublic Color Color; .. Vield Color o- ty&e Color
void V() {
Color + Color.:lac(; .. Oe-erences Color.:lac( static member
Color + Color.Com&lement(); .. $nvo(es Com&lement() on Color -ield
!
static void S() {
Color c + Color.W"ite; .. Oe-erences Color.W"ite static member
!
!
2entro de la clase ', estas repeticiones del identi0icador Color ?ue =acen re0erencia al tipo Color est(n
subrayadas, y las ?ue =acen re0erencia al campo Color no.
#..4.2 Fmbi"Gedades "ramaticales
8as producciones para nombre simple Osi%ple-na%eR O[*..2R y acceso a miembro O%e%-er-accessR O[*..4R
pueden dar lugar a ambigIedades en la gram(tica de las expresiones. 'or e$emplo, la instrucci-nG
V(SD':E(M));
se puede interpretar como una llamada a V con dos argumentos, S D ' y : E (M). Tambi)n se puede interpretar
como una llamada a V con un argumento, ?ue es una llamada a un m)todo gen)rico S con dos argumentos de
tipo y un argumento normal.
.i se puede anali1ar Oen contextoR una secuencia de s5mbolos como un nombre simple Osi%ple-na%eR O[*..2R,
un acceso a miembro O%e%-er-accessR O[*..4R o un acceso a miembros de puntero Opointer-%e%-er-accessR
O[18..2R ?ue termine con una lista de argumentos de tipo Ot#pe-ar&%ent-listR O[4.4.1R, se examinar( el s5mbolo
Oto6enR ?ue aparece inmediatamente despu)s del s5mbolo Oto6enR de cierre E. .i se trata de
( ) 5 ! / ; . 7 ++ @+
16$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a lista de argumentos de tipo Ot#pe-ar&%ent-listR se retiene como parte del nombre simple Osi%ple-na%eR, del
acceso a miembro O%e%-er-accessR o del acceso a miembro de puntero Opointer-%e%-er-accessR y se descarta
cual?uier otro an(lisis posible de la secuencia de s5mbolos Oto6enR. 2e lo contrario, lista de argumentos de tipo
Ot#pe-ar&%ent-listR no se considera parte del nombre simple Osi%ple-na%eR, del acceso a miembro O%e%-er-
accessR o del acceso a miembro de puntero Opointer-%e%-er-accessR incluso si no =ay otro an(lisis posible de la
secuencia de s5mbolos Oto6enR. Tenga en cuenta ?ue estas reglas no se aplican al anali1ar una lista de
argumentos de tipo Ot#pe-ar&%ent-listR en un espacio de nombres o de tipo na%espace-or-t#pe-na%eR O[3.8R.
8a instrucci-n
V(SD':E(M));
se interpretar(, de acuerdo con esta regla, como una llamada a V con un argumento, ?ue es una llamada a un
m)todo gen)rico S con dos argumentos de tipo y un argumento normal. Cada una de las instrucciones
V(S D ' : E M);
V(S D ' : EE M);
se interpretar(n como una llamada a V con dos argumentos. 8a instrucci-n
# + V D ' E <y;
se interpretar( como un operador menor ?ue, mayor ?ue y unario de signo m(s, como si la instrucci-n se
=ubiese escrito # + (V D ') E (<y), en lugar de como un nombre simple Osi%ple-na%eR con una lista de
argumentos de tipo Ot#pe-ar&%ent-listR seguida de un operador binario de signo m(s. En la instrucci-n
# + y is CD1E < ?;
los s5mbolos Oto6enR CD1E se interpretan como un nombre de espacio de nombres o de tipo Ona%espace-or-t#pe-
na%eR con una lista de argumentos de tipo Ot#pe-ar&%ent-listR.
+.#.# E"presiones de inocacin
7na expresi-n de invocaci-n o llamada Oinvocation-e2pressionR se utili1a para llamar a un m)todo.
invocation-e2pression1
pri%ar#-e2pression ( ar&%ent-list
opt
)
8a expresi-n primaria Opri%ar#-e2pressionR de una expresi-n de invocaci-n Oinvocation-e2pressionR debe ser un
grupo de m)todos o un valor de un tipo delegado Odele&ate-t#peR. .i la expresi-n primaria Opri%ar#-e2pressionR
es un grupo de m)todos, la expresi-n de invocaci-n Oinvocation-e2pressionR es una invocaci-n de m)todo O[R. .i
la expresi-n primaria Opri%ar#-e2pressionR es un valor de un tipo delegado Odele&ate-t#peR, la expresi-n de
invocaci-n Oinvocation-e2pressionR es una invocaci-n de delegado O[R. .i la expresi-n primaria Opri%ar#-
e2pressionR no es un grupo de m)todos ni un valor de un tipo delegado Odele&ate-t#peR, se produce un error en
tiempo de compilaci-n.
8a lista de argumentos Oar&%ent-listR opcional O[*.4.1R proporciona valores o re0erencias de variables para los
par(metros del m)todo.
El resultado de evaluar una expresi-n de invocaci-n Oinvocation-e2pressionR se clasi0ica como sigueG
.i la expresi-n de invocaci-n Oinvocation-e2pressionR invoca un m)todo o un delegado ?ue devuelve void,
el resultado es nada. 7na expresi-n ?ue se clasi0ica como nada s-lo est( permitida en el contexto de una
expresi-n de instrucci-n Ostate%ent-e2pressionR O[8.#R o como el cuerpo de una expresi-n lambda Ola%-da-
e2pressionR O[*.14R.
En caso contrario, el resultado es un valor del tipo ?ue devuelve el m)todo o el delegado.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 16"
Especificacin del lenguaje C#
#...1 $nvocaciones de mtodo
'ara una invocaci-n de m)todo, la expresi-n primaria Opri%ar#-e2pressionR de la expresi-n de invocaci-n
Oinvocation-e2pressionR debe ser un grupo de m)todos. El grupo de m)todos identi0ica el m)todo ?ue se invoca
o el con$unto de m)todos sobrecargados entre los cuales se elige un m)todo concreto para invocar. En el Hltimo
caso, la determinaci-n del m)todo concreto ?ue se invoca se basa en el contexto suministrado por los tipos de
los argumentos de lista de argumentos Oar&%ent-listR.
El procesamiento en tiempo de compilaci-n de una invocaci-n de m)todo con la estructura M('), donde M es un
grupo de m)todos O?ue posiblemente incluya una lista de argumentos de tipo gt#pe-ar&%ent-listhR y ' es una
lista de argumentos Oar&%ent-listR opcional, se compone de los siguientes pasosG
.e construye el con$unto de m)todos candidatos para la invocaci-n del m)todo. 'ara cada m)todo V
asociado con el grupo de m)todos MG
o .i V es un m)todo no gen)rico, V es un candidato cuandoG
M no tiene una lista de argumentos de tipo y
V es aplicable en lo ?ue concierne a ' O[*.4.3.1R.
o .i V es un m)todo gen)rico y M no tiene una lista de argumentos de tipo, V es un candidato cuandoG
8a in0erencia de tipo O[*.4.2R se reali1a correctamente, deduciendo una lista de argumentos de tipo
para la llamada y
7na ve1 in0eridos, los argumentos de tipo se sustituyen por los par(metros de tipo del m)todo
correspondientes, todos los tipos construidos en la lista de par(metros de V cumplen sus
restricciones O[4.4.4R y la lista de par(metros de V es aplicable en lo ?ue concierne a ' O[*.4.3.1R.
o .i V es un m)todo gen)rico y M incluye una lista de argumentos de tipo, V es un candidato cuandoG
V tiene el mismo nHmero de par(metros de tipo del m)todo ?ue el suministrado en la lista de
argumentos de tipo y
8os argumentos de tipo se sustituyen por los par(metros de tipo del m)todo correspondientes, todos
los tipos construidos en la lista de par(metros de V cumplen sus restricciones O[4.4.4R y la lista de
par(metros de V es aplicable en lo ?ue concierne a ' O[*.4.3.1R.
El con$unto de m)todos candidatos se limita a m)todos procedentes de los tipos m(s derivadosG para cada
m)todo C.V del con$unto, donde C es el tipo en el ?ue se declara el m)todo V, se ?uitan del con$unto todos
los m)todos declarados en un tipo base de C. .i C es un tipo de clase di0erente de object, se ?uitan del
con$unto todos los m)todos declarados en un tipo de inter0a1. OEsta Hltima regla s-lo tiene e0ecto cuando el
grupo de m)todos es el resultado de una bHs?ueda de miembros en un par(metro de tipo con una clase base
e0ectiva di0erente de ob$ect y un con$unto de inter0aces e0ectivas ?ue no est)n vac5as.R
.i el con$unto resultante de m)todos candidatos est( vac5o, no se reali1an los pasos siguientes, y en lugar de
eso se reali1a un intento de procesar la invocaci-n como una invocaci-n del m)todo de extensi-n O[*...2R.
.i esto da error, signi0ica ?ue no existen m)todos aplicables, y se produce un error durante la compilaci-n.
El me$or m)todo del con$unto de m)todos candidatos se identi0ica mediante las reglas de resoluci-n de
sobrecargas de [*.4.3. .i no puede identi0icarse un m)todo individual me$or, la invocaci-n del m)todo es
ambigua, y se produce un error durante la compilaci-n. &l reali1ar la resoluci-n de sobrecarga, se tienen en
cuenta los par(metros de un m)todo gen)rico despu)s de sustituir los argumentos de tipo Osuministrados o
in0eridosR para los par(metros de tipo del m)todo correspondientes.
.e reali1a la validaci-n 0inal del m)todo me$or elegidoG
1(' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
o El m)todo se valida en el contexto del grupo de m)todosG si el me$or m)todo es un m)todo est(tico, el
grupo de m)todos debe =aberse obtenido de un nombre simple Osi%ple-na%eR o de un acceso a miembro
O%e%-er-accessR mediante un tipo. .i el m)todo me$or es un m)todo de instancia, el grupo de m)todos
debe =aberse obtenido de un nombre simple Osi%ple-na%eR, de un acceso a miembro O%e%-er-accessR a
trav)s de una variable o un valor, o de un acceso a base O-ase-accessR. .i no se cumple ninguna de estas
dos condiciones, se producir( un error de compilaci-n.
o .i el m)todo me$or es un m)todo gen)rico, los argumentos de tipo Osuministrados o in0eridosR se cote$an
con las restricciones O[4.4.4R declaradas en el m)todo gen)rico. .i un argumento de tipo no satis0ace las
restricciones correspondientes del par(metro de tipo, se generar( un error en tiempo de compilaci-n.
7na ve1 seleccionado un m)todo y validado en tiempo de compilaci-n por los pasos anteriores, se procesa la
invocaci-n real en tiempo de e$ecuci-n con0orme a las reglas de invocaci-n de un miembro de 0unci-n
explicadas en [*.4.4.
El e0ecto intuitivo de las reglas de resoluci-n explicadas es como sigueG para locali1ar el m)todo concreto
invocado por una invocaci-n de m)todo, se empie1a con el tipo indicado por la invocaci-n del m)todo y se
continHa en la cadena de la =erencia =asta encontrar por lo menos una declaraci-n de m)todo aplicable,
accesible y no de invalidaci-n. 2espu)s, se lleva a cabo la in0erencia de tipos y la resoluci-n de sobrecargas en
el con$unto de m)todos aplicables, accesibles y de no invalidaci-n declarados en dic=o tipo y se invoca el
m)todo seleccionado por este procedimiento. .i no se encuentra ningHn m)todo, pruebe en su lugar a procesar la
invocaci-n como una invocaci-n del m)todo de extensi-n.
#...2 $nvocaciones del mtodo de e2tensin
En una invocaci-n de m)todo O[*...1R una de las estructurasG
e2pr . identificador ( )
e2pr . identificador ( ar&s )
e2pr . identificador D t#pear&s E ( )
e2pr . identificador D t#pear&s E ( ar&s )
si el procesamiento normal de la invocaci-n no encuentra m)todos aplicables, se reali1a un intento de procesar
la estructura como una invocaci-n del m)todo de extensi-n. El ob$etivo es buscar el me$or nombre de tipo Ot#pe-
na%eR C, para ?ue se produ1ca la invocaci-n del m)todo est(tico correspondienteG
C . identificador ( e2pr )
C . identificador ( e2pr ar&s )
C . identificador D t#pear&s E ( e2pr )
C . identificador D t#pear&s E ( e2pr ar&s )
7n m)todo de extensi-n Ci.Mj es candidato siG
Ci es una clase no gen)rica y no anidada
El nombre de Mj es identifier
Mj es accesible y aplicable cuando se aplica a los argumentos como un m)todo est(tico tal y como se
muestra anteriormente
Existe una conversi-n de identidad, de re0erencia o boxing impl5cita desde e2pr al tipo del primer par(metro
de Mj.
8a bHs?ueda de C se reali1a de la siguiente 0ormaG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1(1
Especificacin del lenguaje C#
Empe1ando por la declaraci-n del espacio de nombres envolvente m(s cercana, siguiendo por cada
declaraci-n de espacio de nombres envolvente, y terminando por la unidad de compilaci-n contenedora, se
reali1an sucesivos intentos de encontrar un con$unto de candidatos para los m)todos de extensi-nG
o .i el espacio de nombres o la unidad de compilaci-n dada contiene directamente declaraciones de tipo
no gen)rico Ci con m)todos de extensi-n candidatos Mj, el con$unto de dic=os m)todos de extensi-n es
el con$unto candidato.
o .i los espacios de nombres importado usando directivas de espacio de nombres en el espacio de
nombres o la unidad de compilaci-n dada contienen directamente declaraciones de tipo no gen)rico Ci
con m)todos de extensi-n candidatos Mj, el con$unto de dic=os m)todos de extensi-n es el con$unto
candidato.
.i no se encuentra ningHn con$unto de candidatos en la unidad de compilaci-n o la declaraci-n de espacios
de nombres envolventes, se produce un error durante la compilaci-n.
En caso contrario, se aplica la resoluci-n de sobrecargas en el con$unto de candidatos tal como se describe
en la secci-n O[*.4.3R. .i no se encuentra un m)todo individual me$or, se produce un error en tiempo de
compilaci-n.
C es el tipo dentro del ?ue se encuentra declarado el me$or m)todo como un m)todo de extensi-n.
Cuando se utili1a C como destino, la llamada a m)todo se procesa como una invocaci-n de m)todo est(tico
O[*.4.4R.
8as reglas anteriores signi0ican ?ue los m)todos de instancia tienen prioridad sobre los m)todos de extensi-n,
?ue los m)todos de extensi-n disponibles en declaraciones de espacios de nombres internos tienen prioridad
sobre los m)todos de extensi-n disponibles en las declaraciones de espacios de nombres externos, y ?ue los
m)todos de extensi-n declarados directamente en un espacio de nombres tienen prioridad sobre los importados
dentro del mismo espacio de nombres con una directiva using de espacio de nombres. 'or e$emploG
&ublic static class )
{
&ublic static void V(t"is object obj int i) { !
&ublic static void V(t"is object obj string s) { !
!
class ' { !
class :
{
&ublic void V(int i) { !
!
class C
{
&ublic void V(object obj) { !
!
class I
{
static void 1est(' a : b C c) {
a.V(2); .. ).V(object int)
a.V(""ello"); .. ).V(object string)
b.V(2); .. :.V(int)
b.V(""ello"); .. ).V(object string)
c.V(2); .. C.V(object)
c.V(""ello"); .. C.V(object)
!
!
1(2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En el e$emplo, el m)todo de : tiene prioridad sobre el primer m)todo de extensi-n, y el m)todo de C tiene
prioridad sobre ambos m)todos de extensi-n.
&ublic static class C
{
&ublic static void V(t"is int i) { Console.WriteLine("C.V({3!)" i); !
&ublic static void S(t"is int i) { Console.WriteLine("C.S({3!)" i); !
&ublic static void H(t"is int i) { Console.WriteLine("C.H({3!)" i); !
!
names&ace N2
{
&ublic static class 6
{
&ublic static void V(t"is int i) { Console.WriteLine("6.V({3!)" i); !
&ublic static void S(t"is int i) { Console.WriteLine("6.S({3!)" i); !
!
!
names&ace N8
{
using N2;
&ublic static class )
{
&ublic static void V(t"is int i) { Console.WriteLine(").V({3!)" i); !
!
class 1est
{
static void Main(string45 args)
{
2.V();
8.S();
9.H();
!
!
!
El resultado de este e$emplo esG
).V(2)
6.S(8)
C.H(9)
6.S tiene prioridad sobre C.S, y ).V tiene prioridad sobre ambos, 6.V y C.V.
#...3 $nvocaciones de dele"ados
'ara una invocaci-n de delegado, la expresi-n primaria Opri%ar#-e2pressionR de la expresi-n de invocaci-n
Oinvocation-e2pressionR debe ser un valor de un tipo delegado Odele&ate-t#peR. &dem(s, considerando ?ue el tipo
delegado Odele&ate-t#peR debe ser un miembro de 0unci-n con la misma lista de par(metros ?ue el tipo delegado
Odele&ate-t#peR, )ste debe ser aplicable O[*.4.3.1R con respecto a la lista de argumentos Oar&%ent-listR de
expresi-n de invocaci-n Oinvocation-e2pressionR.
El procesamiento en tiempo de e$ecuci-n de una invocaci-n de delegado con la estructura 6('), donde 6 es una
expresi-n primaria Opri%ar#-e2pressionR de un tipo delegado y ' es una lista de argumentos Oar&%ent-listR
opcional, se compone de los siguientes pasosG
.e evalHa 6. .i esta evaluaci-n da lugar a una excepci-n, no se e$ecutan nuevos pasos.
.e comprueba la valide1 del valor de 6. .i el valor de 6 es null, se inicia una excepci-n
System.NullOe-erence)#ce&tion y no se e$ecutan nuevos pasos.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1(3
Especificacin del lenguaje C#
En otro caso, 6 es una re0erencia a una instancia de delegado. 8as llamadas a miembros de 0unci-n O[*.4.4R
se reali1an en cada una de las entidades invocables de la lista de llamadas del delegado. En el caso de las
entidades invocables y ?ue constan de una instancia y de un m)todo de instancia, la instancia para la
invocaci-n es la contenida en la entidad a la ?ue se puede llamar.
+.#.$ 'cceso a elementos>
7n acceso a elementos Oele%ent-accessR consta de una expresi-n primaria sin creaci-n de matrices Opri%ar#-no-
arra#-creation-e2pressionR, seguida de un to6en P4Q, una lista de expresiones Oe2pression-listR y un to6en P5Q.
7na lista de expresiones Oe2pression-listR consta de una o m(s expresiones Oe2pressionsR, separadas por comas.
ele%ent-access1
pri%ar#-no-arra#-creation-e2pression 4 e2pression-list 5
e2pression-list1
e2pression
e2pression-list e2pression
.i la expresi-n primaria sin creaci-n de matrices Opri%ar#-no-arra#-creation-e2pressionR de un acceso a
elementos Oele%ent-accessR es un valor de tipo matricial Oarra#-t#peR, el acceso a elementos Oele%ent-accessR es
un acceso a matri1 O[*..#.1R. 2e lo contrario, la expresi-n primaria sin creaci-n de matrices Opri%ar#-no-arra#-
creation-e2pressionR debe ser una variable o un valor de un tipo de clase, estructura o inter0a1 ?ue tenga uno o
m(s miembros indi1adores, en cuyo caso el acceso a elementos Oele%ent-accessR es un acceso a indi1ador
O[*..#.2R.
#..6.1 Fcceso a matrices
'ara un acceso a matrices, la expresi-n primaria sin creaci-n de matrices Opri%ar#-no-arra#-creation-
e2pressionR del acceso a elementos Oele%ent-accessR debe ser un valor de tipo matricial Oarra#-t#peR. El nHmero
de expresiones de la lista de expresiones Oe2pression-listR debe ser el mismo ?ue el rango del tipo matricial
Oarra#-t#peR, y cada expresi-n debe ser de tipo int, uint, long, ulong o de un tipo ?ue pueda convertirse de
0orma impl5cita a uno o m(s de estos tipos.
El resultado de la evaluaci-n de un acceso a matri1 es una variable del tipo de elementos de la matri1, es decir,
el elemento de matri1 seleccionado por los valores de las expresiones en la lista de expresiones Oe2pression-listR.
El procesamiento en tiempo de e$ecuci-n de un acceso a matri1 con la estructura *4'5 Odonde * es una
expresi-n primaria sin creaci-n de matrices Opri%ar#-no-arra#-creation-e2pressionR de un tipo matricial Oarra#-
t#peR y ' es una lista de expresiones Oe2pression-listR se compone de los siguientes pasosG
.e evalHa *. .i esta evaluaci-n da lugar a una excepci-n, no se e$ecutan nuevos pasos.
8as expresiones de 5ndice de la lista de expresiones Oe2pression-listR se evalHan por orden, de i1?uierda a
derec=a. 2espu)s de la evaluaci-n de cada expresi-n de 5ndice, se reali1a una conversi-n impl5cita O[#.1R a
uno de los tipos siguientesG int, uint, long, ulong. .e elige el primer tipo de esta lista para el cual existe
una conversi-n impl5cita. 'or e$emplo, si la expresi-n de 5ndice es de tipo s"ort, se lleva a cabo una
conversi-n impl5cita a int, puesto ?ue son posibles conversiones impl5citas de s"ort a int y de s"ort a
long. .i la evaluaci-n de una expresi-n de 5ndice o de la conversi-n impl5cita posterior causa una
excepci-n, no se evalHan otras expresiones de 5ndice y no se e$ecutan nuevos pasos.
.e comprueba la valide1 del valor de *. .i el valor de * es null, se inicia una excepci-n
System.NullOe-erence)#ce&tion y no se e$ecutan nuevos pasos.
.e compara otra ve1 el valor de cada expresi-n de lista de expresiones Oe2pression-listR con los l5mites
reales de cada dimensi-n de la instancia matricial a ?ue =ace re0erencia *. .i uno o m(s valores no est(n
1(# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
comprendidos en el intervalo, se inicia una excepci-n System.$nde#%ut%-Oange)#ce&tion y no se
e$ecutan nuevos pasos.
.e calcula la ubicaci-n del elemento de matri1 dada por la expresi-n o expresiones de 5ndice, ?ue pasa a ser
el resultado del acceso a matri1.
#..6.2 Fcceso al indi%ador
'ara un acceso a indi1ador, la expresi-n primaria sin creaci-n de matrices Opri%ar#-no-arra#-creation-
e2pressionR del acceso a elementos Oele%ent-accessR debe ser una variable o un valor de un tipo de clase,
estructura o inter0a1, y este tipo debe implementar uno o m(s indi1adores ?ue sean aplicables con respecto a la
lista de expresiones Oe2pression-listR del acceso a elementos Oele%ent-accessR.
El procesamiento en tiempo de compilaci-n de un acceso a indi1ador de la 0orma *4'5, donde * es una
expresi-n primaria sin creaci-n de matrices Opri%ar#-no-arra#-creation-e2pressionR de un tipo 1 de clase,
estructura o inter0a1, y ' es una lista de expresiones Oe2pression-listR, se compone de los siguientes pasosG
.e construye el con$unto de indi1adores suministrados por 1. El con$unto est( 0ormado por todos los
indi1adores declarados en 1 o un tipo base de 1 ?ue no son declaraciones override y est(n accesibles en el
contexto actual O[3.R.
El con$unto se reduce a a?uellos indi1adores ?ue sean aplicables y no est)n ocultos por otros indi1adores.
8as reglas siguientes se aplican a todos los indi1adores S.$ del con$unto, donde S es el tipo en el ?ue se
declara el indi1ador $G
o .i $ no es aplicable con respecto a ' O[*.4.3.1R, entonces $ se ?uita del con$unto.
o .i $ es aplicable con respecto a ' O[*.4.3.1R, entonces todos los indi1adores declarados en un tipo base
de S se ?uitan del con$unto.
o .i $ es aplicable con respecto a ' O[*.4.3.1R y S es un tipo de clase distinto de object, todos los
indi1adores declarados en una inter0a1 se ?uitan del con$unto.
.i el con$unto resultante de indi1adores candidatos est( vac5o, entonces no existen indi1adores aplicables, y
se produce un error durante la compilaci-n.
El me$or indi1ador del con$unto de indi1adores candidatos se identi0ica mediante las reglas de resoluci-n de
sobrecargas de [*.4.3. .i no puede identi0icarse un indi1ador individual me$or, el acceso a indi1ador es
ambiguo y se produce un error durante la compilaci-n.
8as expresiones de 5ndice de la lista de expresiones Oe2pression-listR se evalHan por orden, de i1?uierda a
derec=a. El resultado de procesar el acceso a indi1ador es una expresi-n clasi0icada como un acceso a
indi1ador. 8a expresi-n de acceso a indi1ador =ace re0erencia al indi1ador determinado en el paso anterior, y
tiene una expresi-n de instancia asociada de * y una lista de argumentos asociada de '.
2ependiendo del contexto en ?ue se utilice, un acceso a indi1ador provoca la invocaci-n del descriptor de
acceso get O&et-accessorR o del descriptor de acceso set Oset-accessorR del indi1ador. .i el acceso a indi1ador es
el destino de una asignaci-n, se invoca el descriptor de acceso set Oset-accessorR para asignar un nuevo valor
O[*.1#.1R. En todos los dem(s casos, se invoca el descriptor de acceso a get O&et-accessorR para obtener el valor
actual O[*.1.1R.
+.#.+ 'cceso a t?is
7n acceso a t=is Othis-accessR consta de la palabra reservada t"is.
this-access1
t"is
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1(!
Especificacin del lenguaje C#
El acceso a t=is Othis-accessR s-lo se permite en el blo?ue O-loc3R de un constructor de instancia, un m)todo de
instancia o un descriptor de acceso a una instancia. Tiene uno de los siguientes signi0icadosG
Cuando se utili1a t"is en una expresi-n primaria Opri%ar#-e2pressionR dentro de un constructor de
instancia de una clase, )sta se clasi0ica como un valor. El tipo del valor es el tipo de instancia O[1".3.1R de la
clase dentro de la cual ocurre la utili1aci-n y el valor es una re0erencia al ob$eto ?ue se construye.
Cuando se utili1a t"is en una expresi-n primaria Opri%ar#-e2pressionR dentro de un m)todo de instancia o
de un descriptor de acceso a instancia de una clase, )sta se clasi0ica como un valor. El tipo del valor es el
tipo de instancia O[1".3.1R de la clase dentro de la cual ocurre la utili1aci-n, y el valor es una re0erencia al
ob$eto para el cual se invoca el m)todo o el descriptor de acceso.
Cuando se utili1a t"is en una expresi-n primaria Opri%ar#-e2pressionR dentro de un constructor de
instancia de una estructura, )sta se clasi0ica como una variable. El tipo de la variable es el tipo de instancia
O[1".3.1R de la estructura dentro de la cual ocurre la utili1aci-n y la variable representa la estructura ?ue se
construye. 8a variable t"is de un constructor de instancia de una estructura se comporta exactamente igual
?ue un par(metro out del tipo structV esto signi0ica concretamente ?ue la variable debe estar asignada
de0initivamente en todas las rutas de e$ecuci-n del constructor de instancia.
Cuando se utili1a t"is en una expresi-n primaria Opri%ar#-e2pressionR dentro de un m)todo de instancia o
un descriptor de acceso a instancia de una estructura, )sta se clasi0ica como una variable. El tipo de la
variable es el tipo de instancia O[1".3.1R de la estructura donde se da el uso.
o .i el m)todo o el descriptor de acceso no es un iterador O[1".14R, la variable t"is representa la
estructura para la ?ue se invoca el m)todo o el descriptor de acceso, y se comporta exactamente igual
?ue el par(metro re- del tipo struct.
o .i el m)todo o el descriptor de acceso no es un iterador, la variable t"is representa una copia de la
estructura para la ?ue se invoca el m)todo o el descriptor de acceso, y se comporta exactamente igual
?ue el par(metro de valor del tipo struct.
El uso de t"is en una expresi-n primaria Opri%ar#-e2pressionR dentro de un contexto distinto de los
mencionados anteriormente, produce un error en tiempo de compilaci-n. En particular, no es posible =acer
re0erencia a t"is en un m)todo est(tico, en un descriptor de acceso a una propiedad est(tica o en un
iniciali1ador de variable Ovaria-le-initiali0erR de una declaraci-n de campo.
+.#.- 'cceso a bases
7n acceso a base O-ase-accessR est( 0ormado por la palabra reservada base seguida de un s5mbolo Oto6enR P.Q y
un identi0icador, o de una lista de expresiones Oe2pression-listR encerrada entre corc=etesG
-ase-access1
base . identificador
base 4 e2pression-list 5
7n acceso a base O-ase-accessR permite obtener acceso a miembros de clase base ?ue est(n ocultos por
miembros de nombres similares en la clase o estructura actuales. El acceso a base O-ase-accessR s-lo se permite
en el blo?ue O-loc3R de un constructor de instancia, un m)todo de instancia o un descriptor de acceso a una
instancia. .i base.$ ocurre en una clase o una estructura, $ debe denotar un miembro de la clase base de dic=a
clase o estructura. 2e igual manera, si base4)5 ocurre en una clase, debe existir un indi1ador aplicable en la
clase base.
En tiempo de compilaci-n, las expresiones de acceso a base O-ase-accessR con la estructura base.$ y base4)5
se evalHan exactamente igual ?ue si se escribieran ((:)t"is).$ y ((:)t"is)4)5, donde : es la clase base de
la clase o estructura en ?ue tiene lugar la construcci-n. 'or lo tanto, base.$ y base4)5 corresponden a
t"is.$ y t"is4)5, con la excepci-n de ?ue t"is se considera como una instancia de la clase base.
1(6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Cuando un acceso a base O-ase-accessR =ace re0erencia a un miembro de 0unci-n virtual Oun m)todo, una
propiedad o un indi1adorR, cambia la 0unci-n ?ue se debe invocar en tiempo de e$ecuci-n O[*.4.4R. El miembro
de 0unci-n ?ue se invoca se determina buscando la implementaci-n m(s derivada O[1".#.3R del miembro de
0unci-n con respecto a : Oen lugar de la relativa al tipo de tiempo de e$ecuci-n de t"is, como ser5a normal en
un acceso distinto del acceso a baseR. 'or lo tanto, dentro de un override de un miembro de 0unci-n virtual,
un acceso a base O-ase-accessR puede utili1arse para llamar a la implementaci-n =eredada del miembro de
0unci-n. .i el miembro de 0unci-n al ?ue =ace re0erencia un acceso a base O-ase-accessR es abstracto, se
producir( un error en tiempo de compilaci-n.
+.#.. ,peradores postfijos de incremento y decremento
post-incre%ent-e2pression1
pri%ar#-e2pression <<
post-decre%ent-e2pression1
pri%ar#-e2pression ==
El operando de una operaci-n de su0i$o de incremento o decremento debe ser una expresi-n clasi0icada como
una variable, un acceso a propiedad o un acceso a indi1ador. El resultado de la operaci-n es un valor del mismo
tipo ?ue el operando.
.i el operando de una operaci-n de post0i$o de incremento o decremento es una propiedad o un acceso a
indi1ador, la propiedad o el indi1ador debe tener tanto un descriptor de acceso get como set. .i no es )ste el
caso, se produce un error en tiempo de compilaci-n.
8a resoluci-n de sobrecargas de operadores unarios O[*.2.3R se aplica para seleccionar una implementaci-n de
operador concreta. Existen operadores prede0inidos << y == para los tipos siguientesG sbyte, byte, s"ort,
us"ort, int, uint, long, ulong, c"ar, -loat, double, decimal y cual?uier tipo enum. 8os operadores
prede0inidos << devuelven el valor generado al sumar 1 al operando y los operadores prede0inidos == devuelven
el valor generado al restarle 1. En un contexto c"ec(ed, si el resultado de esta suma o resta se encuentra 0uera
del intervalo del tipo del resultado y el tipo del resultado es un tipo integral o enum, se inicia una excepci-n
System.%ver-lo,)#ce&tion.
El procesamiento en tiempo de e$ecuci-n de una operaci-n de post0i$o de incremento o decremento de la 0orma
#<< o #== consta de los pasos siguientesG
.i # se clasi0ica como una variableG
o .e evalHa # para producir la variable.
o .e guarda el valor de #.
o .e invoca el operador seleccionado con el valor guardado de # como argumento.
o El valor devuelto por el operador se almacena en la ubicaci-n dada por la evaluaci-n de #.
o El valor guardado de # es el resultado de la operaci-n.
.i # se clasi0ica como una propiedad o un acceso a indi1adorG
o .e evalHa la expresi-n de instancia Osi # no es staticR y la lista de argumentos Osi # es un acceso a
indi1adorR asociada con #, y el resultado se utili1a en las posteriores invocaciones de descriptor de
acceso get y set.
o .e invoca el descriptor de acceso get de # y se guarda el valor devuelto.
o .e invoca el operador seleccionado con el valor guardado de # como argumento.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1((
Especificacin del lenguaje C#
o .e invoca el descriptor de acceso set de # con el valor devuelto por el operador como su argumento
value.
o El valor guardado de # es el resultado de la operaci-n.
8os operadores << y == admiten la notaci-n de pre0i$os O[*.#.R. El resultado de #<< o #== es el valor de #
antes de la operaci-n, mientras ?ue el resultado de <<# o ==# es el valor de # desp?s de la operaci-n. En uno u
otro caso, # tiene el mismo valor despu)s de la operaci-n.
7na implementaci-n de o&erator << u o&erator == puede invocarse mediante la notaci-n de post0i$o o
pre0i$o. 4o es posible contar con implementaciones de operador independientes para las dos notaciones.
+.#.10 El operador ne@
El operador ne, se utili1a para crear nuevas instancias de tipos.
Existen tres 0ormas de expresiones ne,G
8as expresiones de creaci-n de ob$etos se utili1an para crear nuevas instancias de tipos de clase y tipos de
valor.
Expresiones de creaci-n de matrices, ?ue se utili1an para crear nuevas instancias de tipos de matri1.
Expresiones de creaci-n de delegados, ?ue se utili1an para crear nuevas instancias de tipos delegados.
El operador ne, implica la creaci-n de una instancia de un tipo, pero no necesariamente la asignaci-n din(mica
de memoria. En concreto, las instancias de tipos de valor no re?uieren m(s memoria ?ue las variables en las ?ue
residen, por lo ?ue no se llevan a cabo asignaciones din(micas cuando se usa ne, para crear instancias de tipos
de valor.
#..17.1 &2presiones de creacin de ob=etos
7na expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR se utili1a para crear una nueva instancia de
un tipo de clase Oclass-t#peR o un tipo de valor Ovale-t#peR.
o->ect-creation-e2pression1
ne, t#pe ( ar&%ent-list
opt
) o->ect-or-collection-initiali0er
opt

ne, t#pe o->ect-or-collection-initiali0er
o->ect-or-collection-initiali0er1
o->ect-initiali0er
collection-initiali0er
El tipo Ot#peR de una expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR debe ser un tipo de clase
Oclass-t#peR, un tipo de valor Ovale-t#peR o un tipo de par(metro Ot#pe-para%eterR. El tipo Ot#peR no puede ser
un tipo de clase Oclass-t#peR abstract.
8a lista de argumentos Oar&%ent-listR opcional O[*.4.1R s-lo est( permitida si el tipo Ot#peR es un tipo de clase
Oclass-t#peR o un tipo struct Ostrct-t#peR.
7na expresi-n de creaci-n de ob$etos puede omitir la lista de argumentos de constructores y los par)ntesis de
cierre siempre ?ue incluya un iniciali1ador de ob$eto o de colecci-n. /mitir la lista de argumentos de
constructores y los par)ntesis de cierre es e?uivalente a especi0icar una lista de argumentos vac5a.
El procesamiento de una expresi-n de creaci-n de ob$etos ?ue incluye un iniciali1ador de ob$eto o de colecci-n
consiste en procesar primero el constructor de instancias y, a continuaci-n, el miembro de las iniciali1aciones de
elemento especi0icadas por el iniciali1ador de ob$eto O[*..1".2R o el iniciali1ador de colecci-n O[*..1".3R.
1($ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
El procesamiento en tiempo de compilaci-n de una expresi-n de creaci-n de ob$etos Oo->ect-creation-
e2pressionR de la 0orma ne, 1('), donde 1 es un tipo de clase Oclass-t#peR o un tipo de valor Ovale-t#peR y '
es una lista de argumentos Oar&%ent-listR opcional, se compone de los siguientes pasosG
.i 1 es un tipo de valor Ovale-t#peR y ' no est( presenteG
o 8a expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR es una invocaci-n de constructor
predeterminado. El resultado de la expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR es un
valor de tipo 1, en concreto, el valor predeterminado de 1 segHn se de0ine en [4.1.1.
En caso contrario, si 1 es un par(metro de tipo Ot#pe-para%eterR y ' no est( presenteG
o .i no se =a especi0icado ninguna restricci-n de tipo ni de constructor O[1".1.R para 1, se produce un
error durante la compilaci-n.
o El resultado de la expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR es un valor del tipo en
tiempo de e$ecuci-n al ?ue est( enla1ado el par(metro de tipo, en concreto el resultado de invocar el
constructor predeterminado de dic=o tipo. El tipo en tiempo de e$ecuci-n puede ser un tipo de re0erencia
o un tipo de valor.
En caso contrario, si 1 es un tipo de clase Oclass-t#peR o un tipo struct Ostrct-t#peRG
o .i 1 es un tipo de clase Oclass-t#peR abstract, se produce un error en tiempo de compilaci-n.
o 8os constructores de instancia ?ue se invoca se determina con las reglas de resoluci-n de sobrecargas de
[*.4.3. El con$unto de constructores de instancia candidatos est( 0ormado por todos los constructores de
instancia accesibles declarados en 1, ?ue son aplicables con respecto a ' O[*.4.3.1R. .i el con$unto de
constructores de instancia candidatos est( vac5o o no es posible identi0icar un solo constructor de
instancia id-neo, se produce un error en tiempo de compilaci-n.
o El resultado de la expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR es un valor de tipo 1, en
concreto, el valor generado al invocar el constructor de instancia determinado en el paso anterior.
2e lo contrario, la expresi-n de creaci-n de ob$etos Oo->ect-creation-e2pressionR no es v(lida y se produce
un error durante la compilaci-n.
El procesamiento en tiempo de compilaci-n de una expresi-n de creaci-n de ob$etos Oo->ect-creation-
e2pressionR con la estructura ne, 1('), donde 1 es un tipo de clase Oclass-t#peR o un tipo struct Ostrct-t#peR y '
es una lista de argumentos Oar&%ent-listR opcional, se compone de los siguientes pasosG
.i 1 es un tipo de clase Oclass-t#peRG
o .e asigna una nueva instancia de la clase 1. .i no =ay memoria disponible su0iciente para asignar la
nueva instancia, se inicia una excepci-n System.%ut%-Memory)#ce&tion y no se e$ecutan m(s
pasos.
o Todos los campos de la nueva instancia se iniciali1an con sus valores predeterminados O[.2R.
o 8os constructores de instancia se invoca con0orme a las reglas de invocaci-n de un miembro de 0unci-n
O[*.4.4R. .e pasa autom(ticamente al constructor de instancia una re0erencia a la instancia reci)n
asignada y se posibilita el acceso a dic=a instancia como t"is desde el constructor.
.i 1 es un tipo struct Ostrct-t#peRG
o .e crea una instancia de tipo 1 mediante la asignaci-n de una variable local temporal. 2ado ?ue se
re?uiere un constructor de instancia de un tipo struct Ostrct-t#peR para asignar de0initivamente un valor
a cada campo de la instancia ?ue se crea, no es necesaria una iniciali1aci-n de la variable temporal.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1("
Especificacin del lenguaje C#
o 8os constructores de instancia se invoca con0orme a las reglas de invocaci-n de un miembro de 0unci-n
O[*.4.4R. .e pasa autom(ticamente al constructor de instancia una re0erencia a la instancia reci)n
asignada y se posibilita el acceso a dic=a instancia como t"is desde el constructor.
#..17.2 $niciali%adores de ob=eto
7n iniciali-ador de o/1eto especi0ica valores para cero o m(s campos o propiedades de un ob$eto.
o->ect-initiali0er1
{ %e%-er-initiali0er-list
opt
!
{ %e%-er-initiali0er-list !
%e%-er-initiali0er-list1
%e%-er-initiali0er
%e%-er-initiali0er-list %e%-er-initiali0er
%e%-er-initiali0er1
identifier @ initiali0er-vale
initiali0er-vale1
e2pression
o->ect-or-collection-initiali0er
7n iniciali1ador de ob$eto se compone de una secuencia de iniciali1adores de miembro, ?ue 0iguran entre los
to6ens P{Q y P!Q y separados por comas. Cada iniciali1ador de miembro debe nombrar una propiedad o campo
accesible del ob$eto ?ue se iniciali1a, seguido por un signo igual y una expresi-n o un iniciali1ador de ob$eto o
colecci-n. Es un error ?ue un iniciali1ador de ob$eto incluya m(s de un iniciali1ador de miembro para la misma
propiedad o campo. 4o es posible ?ue un iniciali1ador de ob$eto =aga re0erencia a un ob$eto reci)n creado ?ue
se est( iniciali1ando.
7n iniciali1ador de miembro ?ue especi0ica una expresi-n despu)s de un signo igual se procesa igual ?ue una
asignaci-n O[*.1#.1R al campo o propiedad.
7n iniciali1ador de miembro ?ue especi0ica un iniciali1ador de ob$eto despu)s de un signo igual es un
iniciali-ador de o/1eto anidado, es decir una iniciali1aci-n de un ob$eto incrustado. En lugar de asignar un
nuevo valor al campo o propiedad, las asignaciones de un iniciali1ador de ob$eto anidado se tratan como
asignaciones a miembros del campo o propiedad. 8os iniciali1adores de ob$etos anidados no se pueden aplicar a
propiedades con un tipo de valor, o a campos de s-lo lectura con un tipo de valor.
7n iniciali1ador de miembro ?ue especi0ica un iniciali1ador de colecci-n despu)s de un signo igual es una
iniciali1aci-n de una colecci-n incrustada. En lugar de asignar una nueva colecci-n al campo o propiedad, los
elementos dados en un iniciali1ador se agregan a la colecci-n re0erenciada por el campo o propiedad. El campo
o la propiedad deben ser un tipo de colecci-n ?ue cumpla los re?uisitos especi0icados en la secci-n [*..1".3.
8a siguiente clase representa un punto con dos coordenadasG
&ublic class *oint
{
int # y;
&ublic int I { get { return #; ! set { # + value; ! !
&ublic int ` { get { return y; ! set { y + value; ! !
!
7na instancia de *oint se puede crear e iniciali1ar de la siguiente 0ormaG
*oint a + ne, *oint { I + 3 ` + 2 !;
?ue tiene el mismo e0ecto ?ue
1$' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
*oint \\a + ne, *oint();
\\a.I + 3;
\\a.` + 2;
*oint a + \\a;
donde \\a es una variable temporal inaccesible e invisible en caso contrario. 8a siguiente clase representa un
rect(ngulo creado a partir de dos puntosG
&ublic class Oectangle
{
*oint &2 &8;
&ublic *oint *2 { get { return &2; ! set { &2 + value; ! !
&ublic *oint *8 { get { return &8; ! set { &8 + value; ! !
!
7na instancia de Oectangle se puede crear e iniciali1ar de la siguiente 0ormaG
Oectangle r + ne, Oectangle {
*2 + ne, *oint { I + 3 ` + 2 !
*8 + ne, *oint { I + 8 ` + 9 !
!;
?ue tiene el mismo e0ecto ?ue
Oectangle \\r + ne, Oectangle();
*oint \\&2 + ne, *oint();
\\&2.I + 3;
\\&2.` + 2;
\\r.*2 + \\&2;
*oint \\&8 + ne, *oint();
\\&8.I + 8;
\\&8.` + 9;
\\r.*8 + \\&8;
Oectangle r + \\r;
donde \\r, \\&2 y \\&8 son variables temporales ?ue, en caso contrario, son inaccesibles e invisibles.
.i el constructor de Oectangle asigna las dos instancias *oint incrustadas
&ublic class Oectangle
{
*oint &2 + ne, *oint();
*oint &8 + ne, *oint();
&ublic *oint *2 { get { return &2; ! !
&ublic *oint *8 { get { return &8; ! !
!
el siguiente constructor se puede utili1ar para iniciali1ar las instancias *oint incrustadas en lugar de asignar
nuevas instanciasG
Oectangle r + ne, Oectangle {
*2 + { I + 3 ` + 2 !
*8 + { I + 8 ` + 9 !
!;
?ue tiene el mismo e0ecto ?ue
Oectangle \\r + ne, Oectangle();
\\r.*2.I + 3;
\\r.*2.` + 2;
\\r.*8.I + 8;
\\r.*8.` + 9;
Oectangle r + \\r;
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1$1
Especificacin del lenguaje C#
#..17.3 $niciali%adores de coleccin
7n iniciali1ador de colecci-n especi0ica los elementos de una colecci-n.
collection-initiali0er1
{ ele%ent-initiali0er-list !
{ ele%ent-initiali0er-list !
ele%ent-initiali0er-list1
ele%ent-initiali0er
ele%ent-initiali0er-list ele%ent-initiali0er
ele%ent-initiali0er1
non-assi&n%ent-e2pression
{ e2pression-list !
7n iniciali1ador de colecci-n se compone de una secuencia de iniciali1adores de elemento, ?ue 0iguran entre los
to6ens P{Q y P!Q y separados por comas. Cada iniciali1ador de elemento especi0ica un elemento ?ue se va a
agregar al ob$eto de colecci-n ?ue se iniciali1a, y se compone de una lista de expresiones entre los to6ens { y !
y separadas por comas. 7n iniciali1ador de elemento de una sola expresi-n se puede escribir sin corc=etes, pero
en ese caso no puede ser una expresi-n de asignaci-n, con el 0in de evitar ambigIedad con los iniciali1adores
de miembro. 8a producci-n de expresiones de no asignaci-n Onon-assi&n%ent-e2pressionR se de0ine en la
secci-n [*.1*.
& continuaci-n, se muestra un e$emplo de una expresi-n de creaci-n de ob$eto ?ue incluye un iniciali1ador de
colecci-nG
ListDintE digits + ne, ListDintE { 3 2 8 9 J K X M Y L !;
El ob$eto de colecci-n al ?ue se aplica un iniciali1ador de colecci-n debe ser un tipo ?ue implemente
System.Collections.$)numerable o se producir( un error durante la compilaci-n. 'ara cada elemento
especi0icado en orden, el iniciali1ador de colecci-n invoca un m)todo 'dd en el ob$eto de destino con la lista de
expresiones del iniciali1ador de elemento como lista de argumentos, aplicando una resoluci-n de sobrecarga
normal para cada invocaci-n. 'or tanto, el ob$eto de colecci-n debe contener un m)todo 'dd aplicable para cada
iniciali1ador de elemento.
8a siguiente clase representa un contacto con un nombre y una lista de nHmeros de tel)0onoG
&ublic class Contact
{
string name;
ListDstringE &"oneNumbers + ne, ListDstringE();
&ublic string Name { get { return name; ! set { name + value; ! !
&ublic ListDstringE *"oneNumbers { get { return &"oneNumbers; ! !
!
ListDContactE se puede crear e iniciali1ar de la siguiente 0ormaG
var contacts + ne, ListDContactE {
ne, Contact {
Name + "C"ris Smit""
*"oneNumbers + { "83X=KKK=3232" "J8K=YY8=Y3Y3" !
!
ne, Contact {
Name + ":ob Harris"
*"oneNumbers + { "XK3=KKK=32LL" !
!
!;
?ue tiene el mismo e0ecto ?ue
1$2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
var \\clist + ne, ListDContactE();
Contact \\c2 + ne, Contact();
\\c2.Name + "C"ris Smit"";
\\c2.*"oneNumbers.'dd("83X=KKK=3232");
\\c2.*"oneNumbers.'dd("J8K=YY8=Y3Y3");
\\clist.'dd(\\c2);
Contact \\c8 + ne, Contact();
\\c8.Name + ":ob Harris";
\\c8.*"oneNumbers.'dd("XK3=KKK=32LL");
\\clist.'dd(\\c8);
var contacts + \\clist;
donde \\clist \\c2 y \\c8 son variables temporales ?ue, en caso contrario, son inaccesibles e invisibles.
#..17.4 &2presiones de creacin de matrices
'ara crear una nueva instancia de un tipo matricial Oarra#-t#peR, se utili1a una expresi-n de creaci-n de matrices
Oarra#-creation-e2pressionR.
arra#-creation-e2pression1
ne, non-arra#-t#pe 4 e2pression-list 5 ran3-specifiers
opt
arra#-initiali0er
opt
ne, arra#-t#pe arra#-initiali0er
ne, ran3-specifier arra#-initiali0er
7na expresi-n de creaci-n de matrices de la primera 0orma asigna una instancia de matri1 del tipo ?ue se
obtiene al eliminar cada una de las expresiones individuales de la lista de expresiones. 'or e$emplo, la expresi-n
de creaci-n de matrices ne, int423 835 produce una instancia de matri1 de tipo int45, y la expresi-n ne,
int423545 produce una matri1 de tipo int4545. Cada expresi-n de la lista de expresiones debe ser de tipo
int, uint, long o ulong, o bien de un tipo ?ue pueda convertirse impl5citamente a uno o m(s de estos tipos.
El valor de cada expresi-n determina la longitud de la dimensi-n correspondiente en la instancia de matri1
reci)n asignada. 2ado ?ue la longitud de la dimensi-n de matri1 no puede ser negativa, si existe una expresi-n
constante Oconstant-e2pressionR con un valor negativo en la lista de expresiones, se producir( un error en tiempo
de compilaci-n.
Excepto en un contexto no seguro O[18.1R, la 0orma de las matrices no se especi0ica.
.i una expresi-n de creaci-n de matri1 de la primera 0orma incluye un iniciali1ador de matri1, cada expresi-n de
la lista de expresiones debe ser una constante, y las longitudes de rango y dimensi-n especi0icadas por la lista de
expresiones deben coincidir con las del iniciali1ador.
En una expresi-n de creaci-n de matrices de la segunda o tercera 0orma, el rango del tipo de matri1 especi0icado
o el especi0icador de rango debe coincidir con el del iniciali1ador. 8as longitudes de las dimensiones
individuales se in0ieren del nHmero de elementos en cada uno de los niveles de anidamiento correspondientes
del iniciali1ador de matri1. 'or lo tanto, la expresi-n
ne, int45 {{3 2! {8 9! {J K!!
se corresponde exactamente con
ne, int49 85 {{3 2! {8 9! {J K!!
7na expresi-n de creaci-n de matrices de la tercera 0orma se conoce como e.presi,n de creaci,n de atrices
con asignaci,n de tipo iplcita. Es similar a la segunda 0orma, excepto en ?ue el tipo de elemento de la matri1
no se da expl5citamente, sino ?ue se determina como el me$or tipo comHn O[*.4.2.13R del con$unto de
expresiones del iniciali1ador de matri1. 'ara una matri1 multidimensional, es decir, una donde el especi0icador
de rango Oran3-specifierR contiene al menos una coma, este con$unto comprende todas las expresiones
Oe2pressionsR encontradas en los iniciali1adores de matrices Oarra#-initiali0ersR anidados.
8os iniciali1adores de matrices se describen m(s detalladamente en [12.#.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1$3
Especificacin del lenguaje C#
El resultado de evaluar una expresi-n de creaci-n de matrices se clasi0ica como un valor, concretamente como
una re0erencia a la instancia de matri1 reci)n asignada. El procesamiento en tiempo de e$ecuci-n de una
expresi-n de creaci-n de matrices consta de los siguientes pasosG
8as expresiones de longitud de dimensi-n de la lista de expresiones Oe2pression-listR se evalHan por orden,
de i1?uierda a derec=a. 2espu)s de la evaluaci-n de cada expresi-n, se reali1a una conversi-n impl5cita
O[#.1R a uno de los tipos siguientesG int, uint, long, ulong. .e elige el primer tipo de esta lista para el
cual existe una conversi-n impl5cita. .i la evaluaci-n de una expresi-n o de la conversi-n impl5cita posterior
causa una excepci-n, no se evalHan otras expresiones y no se e$ecutan nuevos pasos.
8os valores calculados para las longitudes de dimensi-n se validan como sigue. .i uno o m(s valores son
menores ?ue cero, se inicia una excepci-n System.%ver-lo,)#ce&tion y no se e$ecutan nuevos pasos.
.e asigna una instancia de matri1 con las longitudes de dimensi-n dadas. .i no =ay memoria disponible
su0iciente para asignar la nueva instancia, se inicia una excepci-n System.%ut%-Memory)#ce&tion y no
se e$ecutan m(s pasos.
Todos los elementos de la nueva instancia de matri1 se iniciali1an con sus valores predeterminados O[.2R.
.i la expresi-n de creaci-n de matri1 contiene un iniciali1ador de matri1, entonces se evalHan las
expresiones del iniciali1ador y se asignan a sus elemento de matri1 correspondientes. 8as evaluaciones y
asignaciones se llevan a cabo en el orden en ?ue est(n escritas las expresiones en el iniciali1ador de matri1,
es decir, los elementos se iniciali1an en orden de 5ndice creciente, empe1ando por la dimensi-n situada m(s
a la derec=a. .i la evaluaci-n de una expresi-n dada o la posterior asignaci-n al elemento de matri1
correspondiente causa una excepci-n, no se iniciali1an m(s elementos Oy los elementos restantes conservan
sus valores predeterminadosR.
7na expresi-n de creaci-n de matri1 permite crear una instancia de una matri1 con elementos de un tipo de
matri1, pero los elementos de una matri1 como )sta deben iniciali1arse de 0orma manual. 'or e$emplo, la
instrucci-n
int4545 a + ne, int4233545;
crea una matri1 de una dimensi-n con 1"" elementos de tipo int45. El valor inicial de cada elemento es null.
7na misma expresi-n de creaci-n de matrices no puede crear tambi)n instancias de las submatrices, y la
instrucci-n
int4545 a + ne, int423354K5; .. )rror
da como resultado un error en tiempo de compilaci-n. 8a creaci-n de instancias de las submatrices debe
reali1arse de 0orma manual, como en
int4545 a + ne, int4233545;
-or (int i + 3; i D 233; i<<) a4i5 + ne, int4K5;
Cuando una matri1 de matrices tiene 0orma PrectangularQ, es decir, cuando todas las submatrices tienen la
misma longitud, es m(s e0ica1 utili1ar una matri1 de varias dimensiones. En el e$emplo anterior, la creaci-n de
instancias de la matri1 de matrices crea 1"1 ob$etos, una matri1 externa y 1"" submatrices. 'or el contrario,
int45 + ne, int4233 K5;
s-lo crea un ob$eto, una matri1 de dos dimensiones, y reali1a la asignaci-n mediante una sola instrucci-n.
& continuaci-n se muestran e$emplos de expresiones de creaci-n de matrices con asignaci-n de tipo impl5cita.
var a + ne,45 { 2 23 233 2333 !; .. int45
var b + ne,45 { 2 2.K 8 8.K !; .. double45
var c + ne,45 { { ""ello" null ! { ",orld" "@" ! !; .. string45
var d + ne,45 { 2 "one" 8 "t,o" !; .. )rror
1$# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a Hltima expresi-n origina un error durante la compilaci-n por?ue ni int ni string son impl5citamente
convertibles entre s5, de modo ?ue no =ay un me$or tipo comHn. En este caso se debe utili1ar una expresi-n de
creaci-n de matrices con asignaci-n de tipo impl5cita, por e$emplo, especi0icando el tipo para ?ue sea
object45. &lternativamente, uno de los elementos se puede convertir a un tipo base comHn, ?ue entonces
pasar5a a ser el tipo de elemento in0erido.
8as expresiones de creaci-n de matrices con asignaci-n de tipo impl5cita se pueden combinar con iniciali1adores
de ob$etos an-nimos O[*..1".#R para crear estructuras de datos con asignaci-n de tipo an-nima. 'or e$emploG
var contacts + ne,45 {
ne, {
Name + "C"ris Smit""
*"oneNumbers + ne,45 { "83X=KKK=3232" "J8K=YY8=Y3Y3" !
!
ne, {
Name + ":ob Harris"
*"oneNumbers + ne,45 { "XK3=KKK=32LL" !
!
!;
#..17. &2presiones de creacin de dele"ados
7na expresi-n de creaci-n de delegados Odele&ate-creation-e2pressionR se usa para crear una nueva instancia de
un tipo delegado Odele&ate-t#peR.
dele&ate-creation-e2pression1
ne, dele&ate-t#pe ( e2pression )
El argumento de una expresi-n de creaci-n de delegados debe ser un grupo de m)todos, una 0unci-n an-nima o
un valor de un tipo delegado Odele&ate-t#peR. .i el argumento es un con$unto de m)todos, identi0ica el m)todo y,
en el caso de un m)todo de instancia, el ob$eto para el ?ue se crea un delegado. .i el argumento es una 0unci-n
an-nima de0ine los par(metros y el cuerpo del m)todo para el destino del delegado. .i el argumento es un valor
de un tipo delegado Odele&ate-t#peR, identi0ica una instancia de delegado del ?ue se va crear una copia.
El procesamiento en tiempo de compilaci-n de una expresi-n de creaci-n de delegados Odele&ate-creation-
e2pressionR con la estructura ne, 6()), donde 6 es un tipo delegado Odele&ate-t#peR y ) es una expresi-n
Oe2pressionR, se compone de los siguientes pasosG
.i ) es un grupo de m)todos, la expresi-n de creaci-n de delegados se procesa de la misma manera ?ue una
conversi-n de grupo de m)todos O[R de ) a 6.
.i ) es una 0unci-n an-nima, la expresi-n de creaci-n de delegados se procesa de la misma manera ?ue una
conversi-n de 0unci-n an-nima O[#.R de ) a 6.
.i ) es un valor de un tipo delegado, ) debe ser compatible O[R con 6, y el resultado es una re0erencia a un
delegado reci)n creado del tipo 6 ?ue =ace re0erencia a la misma lista de invocaci-n ?ue ). .i ) no es
compatible con 6, se produce un error en tiempo de compilaci-n.
El procesamiento en tiempo de e$ecuci-n de una expresi-n de creaci-n de delegados Odele&ate-creation-
e2pressionR con la estructura ne, 6()), donde 6 es un tipo delegado Odele&ate-t#peR y ) es una expresi-n
Oe2pressionR, se compone de los siguientes pasosG
.i ) es un grupo de m)todos, la expresi-n de creaci-n de delegados se evalHa como una conversi-n de
grupo de m)todos O[#.#R de ) a 6.
.i ) es una 0unci-n an-nima, la expresi-n de creaci-n de delegados se evalHa como una conversi-n de
0unci-n an-nima O[#.R de ) a 6.
.i ) es un valor de un tipo delegado Odele&ate-t#peRG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1$!
Especificacin del lenguaje C#
o .e evalHa ). .i esta evaluaci-n da lugar a una excepci-n, no se e$ecutan nuevos pasos.
o .i el valor de ) es null, se inicia una excepci-n System.NullOe-erence)#ce&tion y no se
e$ecutan nuevos pasos.
o .e asigna una nueva instancia del tipo delegado 6. .i no =ay memoria disponible su0iciente para asignar
la nueva instancia, se inicia una excepci-n System.%ut%-Memory)#ce&tion y no se e$ecutan m(s
pasos.
o .e iniciali1a la nueva instancia de delegado con la misma lista de invocaciones ?ue la instancia de
delegado proporcionada por ).
8a lista de invocaciones de un delegado se determina cuando se iniciali1a el delegado y permanece constante
durante toda la vigencia del delegado. 2ic=o de otra 0ormaG no se podr(n cambiar las entidades de destino
invocables de un delegado una ve1 =aya sido creado el delegado. .i se combinan dos delegados o se ?uita uno
de otro O[1.1R, se produce un nuevo delegadoV no se cambia el contenido de ningHn delegado existente.
4o es posible crear un delegado ?ue =aga re0erencia a una propiedad, un indi1ador, un operador de0inido por el
usuario, un constructor de instancia, un destructor o un constructor est(tico.
Como se =a explicado antes, cuando se crea un delegado a partir de un grupo de m)todos, la lista de par(metros
0ormales y el tipo de valor devuelto del delegado determinan cu(l de los m)todos sobrecargados se debe
seleccionar. En el e$emplo
delegate double 6oubleVunc(double #);
class '
{
6oubleVunc - + ne, 6oubleVunc(SQuare);
static -loat SQuare(-loat #) {
return # > #;
!
static double SQuare(double #) {
return # > #;
!
!
el campo '.- se iniciali1a con un delegado ?ue =ace re0erencia al segundo m)todo SQuare debido a ?ue ese
m)todo coincide exactamente con la lista de par(metros 0ormales y el tipo de valor devuelto de 6oubleVunc. .i
no =ubiera existido el segundo m)todo SQuare, se =abr5a producido un error de compilaci-n.
#..17.6 &2presiones de creacin de ob=etos annimos
7na expresi-n de creaci-n de ob$etos an-nimos Oanon#%os-o->ect-creation-e2pressionR se utili1a para crear un
ob$eto de un tipo an-nimo.
anon#%os-o->ect-creation-e2pression1
ne, anon#%os-o->ect-initiali0er
anon#%os-o->ect-initiali0er1
{ %e%-er-declarator-list
opt
!
{ %e%-er-declarator-list !
%e%-er-declarator-list1
%e%-er-declarator
%e%-er-declarator-list %e%-er-declarator
1$6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
%e%-er-declarator1
si%ple-na%e
%e%-er-access
-ase-access
identifier @ e2pression
7n iniciali1ador de ob$eto an-nimo declara un tipo an-nimo y devuelve una instancia de ese tipo. 7n tipo
an-nimo es un tipo de clase sin nombre ?ue =ereda directamente de object. 8os miembros de un tipo an-nimo
son una secuencia de propiedades de s-lo lectura in0eridas del iniciali1ador de ob$etos an-nimos utili1ado para
crear una instancia del tipo. Espec50icamente, un iniciali1ador de ob$eto an-nimo con la estructura
ne, p
1
+ e
1
p
2
+ e
2
A p
n
+ e
n

declara un tipo an-nimo con la estructura
class \\'nonymous2
{
&rivate readonly B
1
f
1
;
&rivate readonly B
2
f
2
;
A
&rivate readonly B
n
f
n
;
&ublic \\'nonymous2(B
1
a
1
B
2
a
2
A B
n
a
n
) {
f
1
+ a
1
;
f
2
+ a
2
;
A
f
n
+ a
n
;
!
&ublic B
1
p
1
{ get { return f
1
; ! !
&ublic B
2
p
2
{ get { return f
2
; ! !
A
&ublic B
n
p
n
{ get { return f
n
; ! !
&ublic override bool )Quals(object o) { b !
&ublic override int SetHas"Code() { b !
!
donde cada B
2
es el tipo de expresi-n e
2
.correspondiente. 8a expresi-n utili1ada en un declarador de miembro
O%e%-er-declaratorR debe tener un tipo. 'or tanto, es un error en tiempo de compilaci-n ?ue una expresi-n de
un declarador de miembro O%e%-er-declaratorR sea nula o una 0unci-n an-nima. Tambi)n se trata de un error en
tiempo de compilaci-n ?ue la expresi-n tenga un tipo no seguro.
El compilador genera autom(ticamente el nombre de un tipo an-nimo y no se puede =acer re0erencia a )ste en
un texto del programa.
2entro del mismo programa, dos iniciali1adores de ob$etos an-nimos ?ue especi0i?uen una secuencia de
propiedades con los mismos nombres y tipos en tiempo de compilaci-n en el mismo orden producir(n instancias
del mismo tipo an-nimo.
En el e$emplo
var &2 + ne, { Name + "La,nmo,er" *rice + JLK.33 !;
var &8 + ne, { Name + "S"ovel" *rice + 8X.LK !;
&2 + &8;
la asignaci-n en la Hltima l5nea se permite por?ue &2 y &8 son del mismo tipo an-nimo.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1$(
Especificacin del lenguaje C#
8os m)todos )Quals y SetHas"code en tipos an-nimos invalidan los m)todos =eredados de object, y se
de0inen en t)rminos de )Quals y SetHas"code de las propiedades, para ?ue las dos instancias del mismo tipo
an-nimo sean iguales si y s-lo si todas sus propiedades son iguales.
7n declarador de miembro se puede abreviar como un nombre simple O[*..2R, un acceso a miembro O[*..4R o
un acceso a base O[*..8R. Es lo ?ue se denomina iniciali-ador de proyecci,n y es la 0orma abreviada de una
declaraci-n de asignaci-n para una propiedad con el mismo nombre. Concretamente, los declaradores de
miembros con la estructura
identificador e2pr . identificador
son precisamente e?uivalentes a los siguientes, respectivamenteG
identifer + identificador identificador + e2pr . identificador
'or tanto, en un iniciali1ador de proyecci-n el identi0icador OidentifierR selecciona tanto el valor como el campo
o propiedad para el ?ue el valor se asigna. !ntuitivamente, un iniciali1ador de proyecci-n proyecta no s-lo un
valor, sino tambi)n el nombre de ese valor.
+.#.11 ,perador typeof
El operador ty&eo- se utili1a para obtener el ob$eto System.1y&e para un tipo.
t#peof-e2pression1
ty&eo- ( t#pe )
ty&eo- ( n-ond-t#pe-na%e )
ty&eo- ( void )
n-ond-t#pe-na%e1
identifier &eneric-di%ension-specifier
opt
identifier // identifier &eneric-di%ension-specifier
opt
n-ond-t#pe-na%e . identifier &eneric-di%ension-specifier
opt
&eneric-di%ension-specifier1
D co%%as
opt
E
co%%as1

co%%as
8a primera 0orma de expresi-n typeo0 Ot#peof-e2pressionR consta de una palabra clave ty&eo- seguida de un
tipo Ot#peR entre par)ntesis. El resultado de una expresi-n de esta 0orma es el ob$eto System.1y&e del tipo
indicado. .-lo existe un ob$eto System.1y&e para cual?uier tipo dado. 8o ?ue implica ?ue, para el tipo 1,
ty&eo-(1) ++ ty&eo-(1) siempre ser( true.
8a segunda 0orma de la expresi-n typeo0 Ot#peof-e2pressionR consta de una palabra clave ty&eo- seguida de un
nombre de tipo sin enla1ar On-ond-t#pe-na%eR entre par)ntesis. 7n nombre de tipo sin enla1ar On-ond-t#pe-
na%eR es muy similar a un nombre de tipo Ot#pe-na%eR O[3.8R excepto en ?ue un nombre de tipo sin enla1ar
On-ond-t#pe-na%eR contiene especi0icadores de dimensi-n gen)ricos O&eneric-di%ension-specifiersR donde un
nombre de tipo Ot#pe-na%eR contiene listas de argumentos de tipo Ot#pe-ar&%ent-listsR. Cuando el operando de
una expresi-n typeo0 Ot#peof-e2pressionR es una secuencia de s5mbolos Oto6enR ?ue cumple con la gram(tica del
nombre de tipo sin enla1ar On-ond-t#pe-na%eR y del nombre de tipo Ot#pe-na%eR, principalmente cuando no
contiene un especi0icador de dimensi-n gen)rico O&eneric-di%ension-specifierR ni una lista de argumentos de
tipo Ot#pe-ar&%ent-listR, se considera ?ue la secuencia de s5mbolos es un nombre de tipo Ot#pe-na%eR. El
signi0icado de un nombre de tipo sin enla1ar On-ond-t#pe-na%eR se determina como sigueG
Convertir la secuencia de s5mbolos Oto6enR en un nombre de tipo Ot#pe-na%eR al reempla1ar cada
especi0icador de dimensi-n gen)rico O&eneric-di%ension-specifierR por una lista de argumentos de tipo
1$$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Ot#pe-ar&%ent-listR con el mismo nHmero de comas y la palabra clave object ?ue cada argumento de tipo
Ot#pe-ar&%entR.
Evaluar el nombre de tipo Ot#pe-na%eR resultante, al mismo tiempo ?ue se omiten todas las restricciones de
los par(metros de tipo.
El nombre de tipo sin enla1ar On-ond-t#pe-na%eR se resuelve como un tipo gen)rico sin enla1ar asociado
al tipo construido resultante O[4.4.3R.
El resultado de la expresi-n typeo0 Ot#peof-e2pressionR es el ob$eto System.1y&e para el tipo gen)rico sin
enla1ar resultante.
8a tercera 0orma de la expresi-n typeo0 Ot#peof-e2pressionR consta de una palabra clave ty&eo- seguida de una
palabra clave void entre par)ntesis. El resultado de una expresi-n con esta estructura es el ob$eto
System.1y&e ?ue representa la ausencia de un tipo. El ob$eto del tipo devuelto por ty&eo-(void) es
exclusivo del ob$eto del tipo devuelto por cual?uier tipo. Este ob$eto de tipo especial es Htil en las bibliotecas de
clases ?ue permiten la re0lexi-n en m)todos del lengua$e, donde dic=os m)todos desean tener un medio para
representar el tipo de valor devuelto de cual?uier m)todo, incluidos los m)todos void, con una instancia de
System.1y&e.
El operador ty&eo- se puede utili1ar en un par(metro de tipo. El resultado es el ob$eto System.1y&e para el
tipo en tiempo de e$ecuci-n enla1ado al par(metro de tipo. El operador ty&eo- tambi)n se puede utili1ar en un
tipo construido o en un tipo gen)rico no sin enla1ar O[4.4.3R. El ob$eto System.1y&e para el tipo gen)rico sin
enla1ar no es el mismo ?ue el ob$eto System.1y&e del tipo de instancia. El tipo de instancia siempre es un tipo
construido cerrado en tiempo de e$ecuci-n, por?ue el ob$eto depende de los argumentos de tipo en tiempo de
e$ecuci-n ?ue se est(n utili1ando, mientras ?ue el tipo gen)rico sin enla1ar no tiene argumentos de tipo.
En el e$emplo
using System;
class ID1E
{
&ublic static void *rint1y&es() {
1y&e45 t + {
ty&eo-(int)
ty&eo-(System.$nt98)
ty&eo-(string)
ty&eo-(double45)
ty&eo-(void)
ty&eo-(1)
ty&eo-(ID1E)
ty&eo-(IDID1EE)
ty&eo-(IDE)
!;
-or (int i + 3; i D t.Lengt"; i<<) {
Console.WriteLine(t4i5);
!
!
!
class 1est
{
static void Main() {
IDintE.*rint1y&es();
!
!
produce el resultadoG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1$"
Especificacin del lenguaje C#
System.$nt98
System.$nt98
System.String
System.6ouble45
System.Uoid
System.$nt98
Id24System.$nt985
Id24Id24System.$nt9855
Id2415
2ebe tenerse en cuenta ?ue int y System.$nt98 son el mismo tipo.
Tambi)n ?ue el resultado de ty&eo-(IDE) no depende del argumento de tipo, pero el resultado de
ty&eo-(ID1E) s5.
+.#.12 6os operadores c?ec3ed y unc?ec3ed
8os operadores c"ec(ed y unc"ec(ed se utili1an con el 0in de controlar el conte.to de copro/aci,n de
des/ordaiento para conversiones y operaciones aritm)ticas de tipo integral.
chec3ed-e2pression1
c"ec(ed ( e2pression )
nchec3ed-e2pression1
unc"ec(ed ( e2pression )
El operador c"ec(ed evalHa la expresi-n contenida en un contexto comprobado Oc=ec6edR, y el operador
unc"ec(ed evalHa la expresi-n contenida en un contexto no comprobado Ounc=ec6edR. 7na expresi-n c=ec6ed
Ochec3ed-e2pressionR o una expresi-n unc=ec6ed Onchec3ed-e2pressionR se corresponde exactamente con una
expresi-n entre par)ntesis Oparenthesi0ed-e2pressionR O[*..3R, excepto por?ue la expresi-n contenida se evalHa
en el contexto de comprobaci-n de desbordamiento dado.
El contexto de comprobaci-n de desbordamiento tambi)n puede controlarse mediante instrucciones c"ec(ed y
unc"ec(ed O[8.11R.
8as siguientes operaciones resultan a0ectadas por el contexto de comprobaci-n de desbordamiento establecido
por los operadores e instrucciones c"ec(ed y unc"ec(edG
8os operadores unarios prede0inidos << y == O[*..+ y [*.#.R, cuando el operando es de un tipo integral.
El operador unario prede0inido = O[*.#.2R, cuando el operando es de un tipo integral.
8os operadores binarios prede0inidos <, =, > y . O[*.*R, cuando los dos operandos son de tipo integral.
8as conversiones expl5citas num)ricas O[#.2.1R de un tipo integral a otro, o de -loat o double a un tipo
integral.
Cuando una de las operaciones anteriores produce un resultado demasiado grande para representarlo en el tipo
de destino, el contexto en ?ue se e$ecuta la operaci-n controla el comportamiento resultanteG
En un contexto c"ec(ed, si la operaci-n es una expresi-n constante O[*.18R, se produce un error en tiempo
de compilaci-n. / bien, si la operaci-n se reali1a en tiempo de e$ecuci-n, se inicia una excepci-n
System.%ver-lo,)#ce&tion.
En un contexto unc"ec(ed, el resultado se trunca, descart(ndose cual?uier bit de orden superior ?ue no
?uepa en el tipo de destino.
'ara expresiones no constantes Oexpresiones ?ue se evalHan en tiempo de e$ecuci-nR no incluidas por operadores
o instrucciones c"ec(ed o unc"ec(ed, el contexto de comprobaci-n de desbordamiento predeterminado es
unc"ec(ed salvo ?ue 0actores externos Ocomo la con0iguraci-n de opciones del compilador y del entorno de
e$ecuci-nR llamen a la evaluaci-n c"ec(ed.
1"' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
'ara expresiones constantes Oexpresiones ?ue pueden evaluarse completamente en tiempo de compilaci-nR, el
contexto de comprobaci-n de desbordamiento predeterminado siempre es c"ec(ed. .alvo ?ue una expresi-n
constante se colo?ue expl5citamente en un contexto unc"ec(ed, los desbordamientos ?ue ocurren durante la
evaluaci-n en tiempo de compilaci-n de la expresi-n siempre causan errores de tiempo de compilaci-n.
El cuerpo de una 0unci-n an-nima no se ve a0ectado por los contextos c"ec(ed o unc"ec(ed en los ?ue ocurre
la 0unci-n an-nima.
En el e$emplo
class 1est
{
static readonly int # + 2333333;
static readonly int y + 2333333;
static int V() {
return c"ec(ed(# > y); .. 1"ro,s %ver-lo,)#ce&tion
!
static int S() {
return unc"ec(ed(# > y); .. Oeturns =M8M9MLLXY
!
static int H() {
return # > y; .. 6e&ends on de-ault
!
!
no se noti0ican errores de tiempo de compilaci-n puesto ?ue ninguna de las expresiones puede evaluarse en
tiempo de compilaci-n. En tiempo de e$ecuci-n, el m)todo V inicia una excepci-n
System.%ver-lo,)#ce&tion y el m)todo S devuelve W*2*3*++#8 Olos 32 bits menores del resultado 0uera
de intervaloR. El comportamiento del m)todo H depende del contexto de comprobaci-n de desbordamiento
predeterminado de la compilaci-n, pero es el mismo ?ue V o el mismo ?ue S.
En el e$emplo
class 1est
{
const int # + 2333333;
const int y + 2333333;
static int V() {
return c"ec(ed(# > y); .. Com&ile error over-lo,
!
static int S() {
return unc"ec(ed(# > y); .. Oeturns =M8M9MLLXY
!
static int H() {
return # > y; .. Com&ile error over-lo,
!
!
los desbordamientos ?ue se producen durante la evaluaci-n de las expresiones constantes en V y H causan la
noti0icaci-n de errores en tiempo de compilaci-n, puesto ?ue las expresiones se evalHan en un contexto
c"ec(ed. Tambi)n se produce un desbordamiento cuando se evalHa la expresi-n constante en S, si bien, al tener
lugar la evaluaci-n en un contexto unc"ec(ed, dic=o desbordamiento no se noti0ica.
8os operadores c"ec(ed y unc"ec(ed solamente a0ectan al contexto de comprobaci-n de desbordamiento
para a?uellas operaciones ?ue est(n contenidas textualmente en los to6ens P(Q y P)Q. 8os operadores no tienen
ningHn e0ecto sobre los miembros de 0unci-n ?ue se invocan como consecuencia de la evaluaci-n de la
expresi-n contenida. En el e$emplo
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1"1
Especificacin del lenguaje C#
class 1est
{
static int Multi&ly(int # int y) {
return # > y;
!
static int V() {
return c"ec(ed(Multi&ly(2333333 2333333));
!
!
el uso de c"ec(ed en V no a0ecta a la evaluaci-n de # > y en Multi&ly y, por lo tanto, # > y se evalHa en el
contexto de comprobaci-n de desbordamiento predeterminado.
El operador unc"ec(ed es pr(ctico cuando se escriben constantes de los tipos integrales con signo en notaci-n
=exadecimal. 'or e$emploG
class 1est
{
&ublic const int 'll:its + unc"ec(ed((int)3#VVVVVVVV);
&ublic const int Hig":it + unc"ec(ed((int)3#Y3333333);
!
8as dos constantes =exadecimales anteriores son de tipo uint. 2ado ?ue las constantes est(n 0uera del intervalo
de int, sin el operador unc"ec(ed, las conversiones al tipo int producir5an errores en tiempo de compilaci-n.
8as instrucciones y operadores c"ec(ed y unc"ec(ed permiten a los programadores controlar algunos
aspectos de determinados c(lculos num)ricos. 4o obstante, el comportamiento de algunos operadores num)ricos
depende de los tipos de datos de sus operandos. 'or e$emplo, la multiplicaci-n de dos decimales siempre genera
una excepci-n por desbordamiento, inclso en una construcci-n unc"ec(ed expl5cita. 2e igual manera, la
multiplicaci-n de dos tipos de punto 0lotante nunca genera una excepci-n por desbordamiento, inclso en una
construcci-n c"ec(ed expl5cita. &simismo, otros operadores nnca resultan a0ectados por el modo de
comprobaci-n, ya sea predeterminado o expl5cito.
+.#.13 E"presiones de alor predeterminadas
7na expresi-n de valor predeterminada se utili1a para obtener el valor predeterminado O[.2R de un tipo.
3eneralmente, una expresi-n de valor predeterminada se utili1a para par(metros de tipo puesto ?ue es posible
?ue no se detecte si el par(metro de tipo es un tipo de valor o un tipo de re0erencia. O4o existe una conversi-n
del literal null al par(metro de tipo a menos ?ue )ste sea un tipo de re0erencia.R
defalt-vale-e2pression1
de-ault ( t#pe )
.i el tipo Ot#peR de una expresi-n de valor predeterminada Odefalt-vale-e2pressionR se evalHa como un tipo de
re0erencia en tiempo de e$ecuci-n, null se convierte en dic=o tipo como resultado. .i el tipo Ot#peR de una
expresi-n de valor predeterminada Odefalt-vale-e2pressionR se evalHa como un tipo de valor en tiempo de
e$ecuci-n, se obtiene el valor predeterminado del tipo de valor Ovale-t#peR como resultado O[4.1.2R.
7na expresi-n de valor predeterminada Odefalt-vale-e2pressionR es una expresi-n constante O[*.18R si el tipo
es un tipo de re0erencia o un par(metro de tipo ?ue es un tipo de re0erencia O[1".1.R. &dem(s, una expresi-n de
valor predeterminada Odefalt-vale-e2pressionR es una expresi-n constante si el tipo es uno de los tipos de valor
siguientesG sbyte, byte, s"ort, us"ort, int, uint, long, ulong, c"ar, -loat, double, decimal, bool
o cual?uier tipo de enumeraci-n.
+.#.1! E"presiones de m*todos annimos
7na expresi-n de m)todo an-nimo Oanon#%os-%ethod-e2pressionR es uno de los dos m)todos ?ue existen para
de0inir una 0unci-n an-nima. Este tema se describe con m(s detalle en la secci-n [*.14.
1"2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
+.$ ,peradores unarios
8os operadores <, =, @, A, <<, ==, y los operadores de conversi-n de tipos se denominan operadores unarios.
nar#-e2pression1
pri%ar#-e2pression
< nar#-e2pression
= nar#-e2pression
@ nar#-e2pression
A nar#-e2pression
pre-incre%ent-e2pression
pre-decre%ent-e2pression
cast-e2pression
+.$.1 ,perador unario de signo m)s
'ara una operaci-n con la 0orma <#, se aplica la resoluci-n de sobrecargas de operadores unarios O[*.2.3R con el
0in de seleccionar una implementaci-n de operador concreta. El operando se convierte al tipo de par(metro del
operador seleccionado, y el tipo del resultado es el tipo de valor devuelto del operador. 8os operadores de signo
m(s unarios prede0inidos sonG
int o&erator <(int #);
uint o&erator <(uint #);
long o&erator <(long #);
ulong o&erator <(ulong #);
-loat o&erator <(-loat #);
double o&erator <(double #);
decimal o&erator <(decimal #);
'ara cada uno de estos operadores, el resultado es sencillamente el valor del operando.
+.$.2 ,perador unario de signo menos
'ara una operaci-n con la 0orma C#, se aplica la resoluci-n de sobrecargas de operadores unarios O[*.2.3R con el
0in de seleccionar una implementaci-n de operador concreta. El operando se convierte al tipo de par(metro del
operador seleccionado, y el tipo del resultado es el tipo de valor devuelto del operador. 8os operadores de
negaci-n prede0inidos sonG
4egaci-n enteraG
int o&erator C(int #);
long o&erator C(long #);
El resultado se calcula restando # de cero. .i el valor de # es el valor menor representable del tipo de
operando OY2
31
para int o Y2
#3
para long), la negaci-n matem(tica de # no se puede representar en este
tipo de operando. .i esto ocurre dentro de un contexto c"ec(ed, se inicia una excepci-n
System.%ver-lo,)#ce&tionV si ocurre dentro de un contexto unc"ec(ed, el resultado es el valor del
operando y no se in0orma del desbordamiento.
.i el operando del operador de negaci-n es de tipo uint, se convierte al tipo long y el tipo del resultado es
long. 7na excepci-n es la regla ?ue permite escribir el valor int Y214*483#48 OY2
31
R como un literal
entero decimal O[2.4.4.2R.
.i el operando del operador de negaci-n es de tipo ulong, se produce un error durante la compilaci-n. 7na
excepci-n es la regla ?ue permite escribir el valor long Y+2233*2"3#84**8"8 OY2
#3
R como un literal
entero decimal O[2.4.4.2R.
4egaci-n de punto 0lotanteG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1"3
Especificacin del lenguaje C#
-loat o&erator C(-loat #);
double o&erator C(double #);
El resultado es el valor de # con su signo invertido. .i # es 4a4, el resultado es tambi)n 4a4.
4egaci-n decimalG
decimal o&erator C(decimal #);
El resultado se calcula restando # de cero. 8a negaci-n decimal e?uivale a usar el operador unario de signo
menos del tipo System.6ecimal.
+.$.3 ,perador de negacin lgica
'ara una operaci-n con la 0orma @#, se aplica la resoluci-n de sobrecargas de operadores unarios O[*.2.3R para
seleccionar una implementaci-n de operador concreta. El operando se convierte al tipo de par(metro del
operador seleccionado, y el tipo del resultado es el tipo de valor devuelto del operador. .olamente existe un
operador de negaci-n l-gica prede0inidoG
bool o&erator @(bool #);
Este operador calcula la negaci-n l-gica del operandoG si )ste es true, el resultado es -alse. .i el operando es
-alse, el resultado es true.
+.$.! ,perador de complemento de bit a bit
'ara una operaci-n con la 0orma A#, se aplica la resoluci-n de sobrecargas de operadores unarios O[*.2.3R
para seleccionar una implementaci-n de operador concreta. El operando se convierte al tipo de par(metro del
operador seleccionado, y el tipo del resultado es el tipo de valor devuelto del operador. 8os operadores de
complemento de bit a bit prede0inidos sonG
int o&erator A(int #);
uint o&erator A(uint #);
long o&erator A(long #);
ulong o&erator A(ulong #);
'ara cada uno de estos operadores, el resultado de la operaci-n es el complemento de bit a bit de #.
Todos los tipos de enumeraci-n ) proporcionan impl5citamente el siguiente operador de complemento de bit
a bitG
) o&erator A() #);
El resultado de evaluar A#, donde # es una expresi-n de un tipo de enumeraci-n ) con un tipo subyacente ;,
es exactamente el mismo ?ue el de evaluar OER(A(;)#).
+.$.# ,peradores prefijos de incremento y decremento
pre-incre%ent-e2pression1
<< nar#-e2pression
pre-decre%ent-e2pression1
== nar#-e2pression
El operando de una operaci-n de pre0i$o de incremento o decremento debe ser una expresi-n clasi0icada como
un variable, un acceso a propiedad o un acceso a indi1ador. El resultado de la operaci-n es un valor del mismo
tipo ?ue el operando.
.i el operando de una operaci-n de pre0i$o de incremento o decremento es una propiedad o un acceso a
indi1ador, la propiedad o el indi1ador debe tener tanto un descriptor de acceso get como set. .i no es )ste el
caso, se produce un error en tiempo de compilaci-n.
1"# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a resoluci-n de sobrecargas de operadores unarios O[*.2.3R se aplica para seleccionar una implementaci-n de
operador concreta. Existen operadores prede0inidos << y == para los tipos siguientesG sbyte, byte, s"ort,
us"ort, int, uint, long, ulong, c"ar, -loat, double, decimal y cual?uier tipo enum. 8os operadores
prede0inidos << devuelven el valor generado al sumar 1 al operando, y los operadores prede0inidos ==
devuelven el valor generado al restarle 1. En un contexto c"ec(ed, si el resultado de esta suma o resta se
encuentra 0uera del intervalo del tipo del resultado y el tipo del resultado es un tipo integral o enum, se inicia
una excepci-n System.%ver-lo,)#ce&tion.
El procesamiento en tiempo de e$ecuci-n de una operaci-n de pre0i$o de incremento o decremento de la 0orma <
<# o ==# consta de los pasos siguientesG
.i # se clasi0ica como una variableG
o .e evalHa # para producir la variable.
o .e invoca el operador seleccionado con el valor de # como argumento.
o El valor devuelto por el operador se almacena en la ubicaci-n dada por la evaluaci-n de #.
o El valor devuelto por el operador es el resultado de la operaci-n.
.i # se clasi0ica como una propiedad o un acceso a indi1adorG
o .e evalHa la expresi-n de instancia Osi # no es staticR y la lista de argumentos Osi # es un acceso a
indi1adorR asociada con #, y el resultado se utili1a en las posteriores invocaciones de descriptor de
acceso get y set.
o .e invoca el descriptor de acceso get de #.
o .e invoca el operador seleccionado con el valor devuelto por el descriptor de acceso get como
argumento.
o .e invoca el descriptor de acceso set de # con el valor devuelto por el operador como su argumento
value.
o El valor devuelto por el operador es el resultado de la operaci-n.
8os operadores << y == admiten la notaci-n de post0i$os O[*..+R. El resultado de #<< o #== es el valor de #
antes de la operaci-n, mientras ?ue el resultado de <<# o ==# es el valor de # desp?s de la operaci-n. En uno u
otro caso, # tiene el mismo valor despu)s de la operaci-n.
7na implementaci-n de o&erator << u o&erator == puede invocarse mediante la notaci-n de post0i$o o
pre0i$o. 4o es posible contar con implementaciones de operador independientes para las dos notaciones.
+.$.$ E"presiones de conersin
7na expresi-n de conversi-n de tipos Ocast-e2pressionR se usa para convertir expl5citamente una expresi-n a un
tipo dado.
cast-e2pression1
( t#pe ) nar#-e2pression
7na expresi-n de conversi-n cast Ocast-e2pressionR de la 0orma (1)), donde 1 es un tipo Ot#peR y ) es una
expresi-n unaria Onar#-e2pressionR, reali1a una conversi-n expl5cita O[#.2R del valor de ) al tipo 1. .i no existe
una conversi-n expl5cita de ) a 1, se produce un error durante la compilaci-n. En caso contrario, el resultado es
el valor producido por la conversi-n expl5cita. El resultado siempre se clasi0ica como un valor, aun?ue ) denote
una variable.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1"!
Especificacin del lenguaje C#
8a gram(tica de una expresi-n de conversi-n de tipos Ocast-e2pressionR produce algunas ambigIedades
sint(cticas. 'or e$emplo, la expresi-n (#)Cy podr5a interpretarse como una expresi-n de conversi-n de tipos
Ocast-e2pressionR Ouna conversi-n del tipo Cy al tipo #R o como una expresi-n aditiva Oadditive-e2pressionR
combinada con una expresi-n entre par)ntesis Oparenthesi0ed-e2pressionR O?ue calcula el valor de # C yR.
'ara resolver las ambigIedades de las expresiones de conversi-n de tipos Ocast-e2pressionR, existe la siguiente
reglaG una secuencia de uno o m(s s5mbolos Oto3ensR O[2.3.3R encerrados entre par)ntesis se considera el inicio
de una expresi-n de conversi-n de tipos Ocast-e2pressionR s-lo si al menos uno de los siguientes supuestos
es ciertoG
8a secuencia de to6ens es correcta gramaticalmente para un tipo Ot#peR, pero no para una expresi-n
Oe2pressionR.
8a secuencia de to6ens es correcta gramaticalmente para un tipo Ot#peR, y el s5mbolo ?ue sigue
inmediatamente al par)ntesis de cierre es el to6en PAQ, P@Q o P(Q, un identi0icador OidentifierR O[2.4.1R,
un literal OliteralR O[2.4.4R o cual?uier palabra clave O3e#wordR O[2.4.3R excepto as e is.
El t)rmino Pgramaticalmente correctaQ signi0ica ?ue la secuencia de s5mbolos Oto6ensR debe a$ustarse a la
producci-n gramatical particular de esta clase de expresiones. En concreto, no se considera al signi0icado real de
sus identi0icadores constituyentes. 'or e$emplo, si # e y son identi0icadores, entonces #.y es correcta
gramaticalmente para un tipo, aun?ue #.y no denote realmente un tipo.
2e la regla de eliminaci-n de ambigIedades se deduce ?ue, si # e y son identi0icadores, (#)y, (#)(y) y
(#)(=y) son expresiones de conversi-n de tipos Ocast-e2pressionsR, pero no as5 (#)=y, aun?ue # identi0i?ue
un tipo. 4o obstante, si # es una palabra clave ?ue identi0ica un tipo prede0inido Ocomo intR, las cuatro 0ormas
son expresiones de conversi-n de tipos Ocast-e2pressionsR Opor?ue esta palabra clave nunca podr5a ser una
expresi-n por s5 mismaR.
+.+ ,peradores aritm*ticos
8os operadores >, ., B, < y C se denominan operadores aritm)ticos.
%ltiplicative-e2pression1
nar#-e2pression
%ltiplicative-e2pression > nar#-e2pression
%ltiplicative-e2pression . nar#-e2pression
%ltiplicative-e2pression B nar#-e2pression
additive-e2pression1
%ltiplicative-e2pression
additive-e2pression < %ltiplicative-e2pression
additive-e2pression C %ltiplicative-e2pression
+.+.1 ,perador de multiplicacin
'ara una operaci-n con la 0orma # > y, se aplica la resoluci-n de sobrecargas de operadores binarios O[*.2.4R
para seleccionar una implementaci-n de operador concreta. 8os operandos se convierten a los tipos de
par(metro del operador seleccionado, y el tipo del resultado es el tipo de valor devuelto por el operador.
& continuaci-n se enumeran los operadores de multiplicaci-n prede0inidos. Todos los operadores calculan el
producto de # e y.
%ultiplicaci-n de enterosG
int o&erator >(int # int y);
uint o&erator >(uint # uint y);
long o&erator >(long # long y);
ulong o&erator >(ulong # ulong y);
1"6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En un contexto c"ec(ed, si el producto est( 0uera del intervalo del tipo del resultado, se inicia una
excepci-n System.%ver-lo,)#ce&tion. En un contexto unc"ec(ed, no se noti0ican los
desbordamientos y se descarta cual?uier bit signi0icativo de nivel superior del resultado ?ue est) 0uera del
intervalo del tipo de resultado.
%ultiplicaci-n de nHmeros de punto 0lotanteG
-loat o&erator >(-loat # -loat y);
double o&erator >(double # double y);
El producto se calcula segHn las reglas de aritm)tica !EEE *4. 8a tabla siguiente muestra los resultados de
todas las posibles combinaciones de valores 0initos distintos de cero, ceros, in0initos y 4a4. En la tabla, # e
y son valores 0initos positivos. ? es el resultado de # > y. .i el resultado es demasiado grande para el tipo de
destino, ? es in0inito. .i el resultado es demasiado pe?ueUo para el tipo de destino, ? es cero.
<y Cy <3 C3 <e Ce NaN
<# <? C? <3 C3 <e Ce NaN
C# C? <? C3 <3 Ce <e NaN
<3 <3 C3 <3 C3 NaN NaN NaN
C3 C3 <3 C3 <3 NaN NaN NaN
<e <e Ce NaN NaN <e Ce NaN
Ce Ce <e NaN NaN Ce <e NaN
NaN NaN NaN NaN NaN NaN NaN NaN
%ultiplicaci-n de nHmeros decimalesG
decimal o&erator >(decimal # decimal y);
.i el valor resultante es demasiado grande para representarlo en 0ormato decimal, se inicia una excepci-n
System.%ver-lo,)#ce&tion. .i el valor resultante es demasiado pe?ueUo para representarlo en 0ormato
decimal, el resultado es cero. 8a escala del resultado, antes de cual?uier redondeo, es la suma de las
escalas de los dos operandos.
8a multiplicaci-n de decimales e?uivale al uso del operador de multiplicaci-n de tipo System.6ecimal.
+.+.2 ,perador de diisin
'ara una operaci-n con la 0orma # . y, se aplica la resoluci-n de sobrecargas de operadores binarios O[*.2.4R
para seleccionar una implementaci-n de operador concreta. 8os operandos se convierten a los tipos de
par(metro del operador seleccionado, y el tipo del resultado es el tipo de valor devuelto por el operador.
& continuaci-n se enumeran los operadores de divisi-n prede0inidos. Todos los operadores calculan el cociente
de # e y.
2ivisi-n de nHmeros enterosG
int o&erator .(int # int y);
uint o&erator .(uint # uint y);
long o&erator .(long # long y);
ulong o&erator .(ulong # ulong y);
.i el valor del operando derec=o es cero, se inicia una excepci-n System.6ivide:yPero)#ce&tion.
8a divisi-n redondea el resultado =acia cero, y el valor absoluto del resultado es el entero mayor posible ?ue
sea menor ?ue el valor absoluto del cociente de los dos operandos. El resultado es cero o positivo cuando los
dos operandos tienen el mismo signo, y cero o negativo si los dos operandos tienen signos opuestos.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1"(
Especificacin del lenguaje C#
.i el operando i1?uierdo es el int o long representable menor y el derec=o es C2, se produce un
desbordamiento. En un contexto c"ec(ed, esto =ace ?ue se produ1ca una excepci-n
System.'rit"metic)#ce&tion Oo una subclase de la mismaR. En un contexto unc"ec(ed, la
implementaci-n de0ine si se inicia una excepci-n System.'rit"metic)#ce&tion Oo una subclase de la
mismaR o no se in0orma del desbordamiento, siendo el valor resultante el del operando i1?uierdo.
2ivisi-n de nHmeros de punto 0lotanteG
-loat o&erator .(-loat # -loat y);
double o&erator .(double # double y);
El cociente se calcula segHn las reglas de aritm)tica !EEE *4. 8a tabla siguiente muestra los resultados de
todas las posibles combinaciones de valores 0initos distintos de cero, ceros, in0initos y 4a4. En la tabla, # e
y son valores 0initos positivos. ? es el resultado de # . y. .i el resultado es demasiado grande para el tipo de
destino, ? es in0inito. .i el resultado es demasiado pe?ueUo para el tipo de destino, ? es cero.
<y Cy <3 C3 <e Ce NaN
<# <? C? <e Ce <3 C3 NaN
C# C? <? Ce <e C3 <3 NaN
<3 <3 C3 NaN NaN <3 C3 NaN
C3 C3 <3 NaN NaN C3 <3 NaN
<e <e Ce <e Ce NaN NaN NaN
Ce Ce <e Ce <e NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
2ivisi-n de nHmeros decimalesG
decimal o&erator .(decimal # decimal y);
.i el valor del operando derec=o es cero, se inicia una excepci-n System.6ivide:yPero)#ce&tion. .i
el valor resultante es demasiado grande para representarlo en 0ormato decimal, se inicia una excepci-n
System.%ver-lo,)#ce&tion. .i el valor resultante es demasiado pe?ueUo para representarlo en 0ormato
decimal, el resultado es cero. 8a escala del resultado ser( la menor escala ?ue conserve un resultado igual
al valor decimal representable m(s cercano al aut)ntico valor matem(tico.
8a divisi-n de decimales e?uivale al uso del operador de divisi-n de tipo System.6ecimal.
+.+.3 ,perador de resto
'ara una operaci-n con la 0orma # B y, se aplica la resoluci-n de sobrecargas de operadores binarios O[*.2.4R
para seleccionar una implementaci-n de operador concreta. 8os operandos se convierten a los tipos de
par(metro del operador seleccionado, y el tipo del resultado es el tipo de valor devuelto por el operador.
& continuaci-n se enumeran los operadores de resto prede0inidos. Todos los operadores calculan el resto de la
divisi-n entre # e y.
;esto de nHmeros enterosG
int o&erator B(int # int y);
uint o&erator B(uint # uint y);
long o&erator B(long # long y);
ulong o&erator B(ulong # ulong y);
El resultado de # B y es el valor producido por # C (# . y) > y. .i y es cero, se produce una excepci-n
System.6ivide:yPero)#ce&tion.
1"$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
.i el operando i1?uierdo es el valor int o long menor y el operando derec=o es =2, se inicia una excepci-n
System.%ver-lo,)#ce&tion. En ningHn caso # B y inicia una excepci-n donde # . y no iniciar5a una
excepci-n.
;esto de nHmeros de punto 0lotanteG
-loat o&erator B(-loat # -loat y);
double o&erator B(double # double y);
8a tabla siguiente muestra los resultados de todas las posibles combinaciones de valores 0initos distintos de
cero, ceros, in0initos y 4a4. En la tabla, # e y son valores 0initos positivos. ? es el resultado de # B y, y se
calcula como # C n > y, donde n es el mayor entero posible ?ue sea menor o igual a # . y. Este m)todo para
calcular el resto es an(logo al utili1ado para los operandos enteros, pero di0iere de la de0inici-n de !EEE *4
Oen la ?ue n es el entero m(s pr-ximo a # . yR.
<y Cy <3 C3 <e Ce NaN
<# <? <? NaN NaN # # NaN
C# C? C? NaN NaN C# C# NaN
<3 <3 <3 NaN NaN <3 <3 NaN
C3 C3 C3 NaN NaN C3 C3 NaN
<e NaN NaN NaN NaN NaN NaN NaN
Ce NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
;esto de nHmeros decimalesG
decimal o&erator B(decimal # decimal y);
.i el valor del operando derec=o es cero, se inicia una excepci-n System.6ivide:yPero)#ce&tion. 8a
escala del resultado, antes de cual?uier redondeo, es la mayor de las escalas de los dos operandosV el signo
del resultado, si es distinto de cero, es el mismo ?ue el de #.
El resto decimal e?uivale al uso del operador de resto de tipo System.6ecimal.
+.+.! ,perador de suma
'ara una operaci-n con la 0orma # < y, se aplica la resoluci-n de sobrecargas de operadores binarios O[*.2.4R
para seleccionar una implementaci-n de operador concreta. 8os operandos se convierten a los tipos de
par(metro del operador seleccionado, y el tipo del resultado es el tipo de valor devuelto por el operador.
& continuaci-n se enumeran los operadores de suma prede0inidos. 'ara tipos num)ricos y de enumeraci-n, los
operadores de suma prede0inidos calculan la suma de los dos operandos. Cuando al menos uno de los operandos es
de tipo string, los operadores de suma prede0inidos concatenan las representaciones de la cadena de los operandos.
.uma de nHmeros enterosG
int o&erator <(int # int y);
uint o&erator <(uint # uint y);
long o&erator <(long # long y);
ulong o&erator <(ulong # ulong y);
En un contexto c"ec(ed, si la suma est( 0uera del intervalo del tipo del resultado, se inicia una excepci-n
System.%ver-lo,)#ce&tion. En un contexto unc"ec(ed, no se noti0ican los desbordamientos y se
descarta cual?uier bit signi0icativo de nivel superior del resultado ?ue est) 0uera del intervalo del tipo
de resultado.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 1""
Especificacin del lenguaje C#
.uma de nHmeros de punto 0lotanteG
-loat o&erator <(-loat # -loat y);
double o&erator <(double # double y);
8a suma se calcula segHn las reglas de aritm)tica !EEE *4. 8a tabla siguiente muestra los resultados de
todas las posibles combinaciones de valores 0initos distintos de cero, ceros, in0initos y 4a4. En la tabla, # e
y son valores 0initos distintos de cero y ? es el resultado de # < y. .i # e y tienen la misma magnitud pero
signos opuestos, ? es cero positivo. .i # < y es demasiado grande para representarlo en el tipo de destino,
? es un in0inito con el signo de # < y.
y <3 C3 <e Ce NaN
# ? # # <e Ce NaN
<3 y <3 <3 <e Ce NaN
C3 y <3 C3 <e Ce NaN
<e <e <e <e <e NaN NaN
Ce Ce Ce Ce NaN Ce NaN
NaN NaN NaN NaN NaN NaN NaN
.uma de nHmeros decimalesG
decimal o&erator <(decimal # decimal y);
.i el valor resultante es demasiado grande para representarlo en 0ormato decimal, se inicia una excepci-n
System.%ver-lo,)#ce&tion. 8a escala del resultado, antes de cual?uier redondeo, es la mayor de las
escalas de los dos operandos.
8a suma de decimales e?uivale al uso del operador de suma de tipo System.6ecimal.
.uma de enumeraciones. Todos los tipos de enumeraci-n proporcionan de 0orma impl5cita los siguientes
operadores prede0inidos, donde ) es el tipo enum y ; es el tipo subyacente de )G
) o&erator <() # ; y);
) o&erator <(; # ) y);
8os operadores se evalHan exactamente como ())((;)# < (;)y).
Concatenaci-n de cadenasG
string o&erator <(string # string y);
string o&erator <(string # object y);
string o&erator <(object # string y);
El operador binario < concatena cadenas cuando uno o los dos operandos son de tipo string. .i un
operando de la concatenaci-n de cadenas es null, se sustituye una cadena vac5a. / bien, cual?uier
argumento ?ue no sea de cadena se convierte a su representaci-n en 0ormato de cadena mediante la
invocaci-n del m)todo virtual 1oString =eredado del tipo object. .i 1oString devuelve null, se
sustituye una cadena vac5a.
using System;
2'' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class 1est
{
static void Main() {
string s + null;
Console.WriteLine("s + E" < s < "D"); .. dis&lays s + ED
int i + 2;
Console.WriteLine("i + " < i); .. dis&lays i + 2
-loat - + 2.8933)<2KV;
Console.WriteLine("- + " < -); .. dis&lays - + 2.89)<2K
decimal d + 8.L33m;
Console.WriteLine("d + " < d); .. dis&lays d + 8.L33
!
!
El resultado del operador de concatenaci-n de cadenas es una cadena 0ormada por los caracteres del
operando i1?uierdo seguidos de los caracteres del operando derec=o. El operador de concatenaci-n de
cadenas nunca devuelve un valor null. 'uede iniciarse una excepci-n System.%ut%-Memory)#ce&tion
si no =ay su0iciente memoria libre para asignar la cadena resultante.
Combinaci-n de delegados. Todos los tipos delegados proporcionan impl5citamente el siguiente operador
prede0inido, donde 6 es el tipo delegadoG
6 o&erator <(6 # 6 y);
El operador binario < reali1a la combinaci-n de delegados cuando los dos operandos son de un tipo
delegado 6. O.i los operandos tienen tipos de delegado distintos, se produce un error en tiempo de
compilaci-n.R .i el primer operando es null, el resultado de la operaci-n es el valor del segundo operando
Oaun?ue este operando tambi)n sea nullR. En caso contrario, si el segundo operando es null, el resultado
de la operaci-n es el valor del primer operando. / bien, el resultado de la operaci-n es una nueva instancia
de delegado ?ue, cuando se invoca, llama al primer operando y despu)s al segundo. 'ara obtener e$emplos
de combinaci-n de delegados, vea [*.*. y [1.4. 'uesto ?ue System.6elegate no es un tipo delegado,
no tiene o&erator <.
+.+.# ,perador de resta
'ara una operaci-n con la 0orma # C y, se aplica la resoluci-n de sobrecargas de operadores binarios O[*.2.4R
para seleccionar una implementaci-n de operador concreta. 8os operandos se convierten a los tipos de
par(metro del operador seleccionado, y el tipo del resultado es el tipo de valor devuelto por el operador.
& continuaci-n se enumeran los operadores de resta prede0inidos. Todos los operadores restan y de #.
;esta de enterosG
int o&erator C (int # int y);
uint o&erator C (uint # uint y);
long o&erator C (long # long y);
ulong o&erator C (ulong # ulong y);
En un contexto c"ec(ed, si la di0erencia est( 0uera del intervalo del tipo del resultado, se inicia una
excepci-n System.%ver-lo,)#ce&tion. En un contexto unc"ec(ed, no se noti0ican los
desbordamientos y se descarta cual?uier bit signi0icativo de nivel superior del resultado ?ue est) 0uera del
intervalo del tipo de resultado.
;esta de nHmeros de punto 0lotanteG
-loat o&erator C (-loat # -loat y);
double o&erator C (double # double y);
8a di0erencia se calcula segHn las reglas de aritm)tica !EEE *4. 8a tabla siguiente muestra los resultados
de todas las posibles combinaciones de valores 0initos distintos de cero, ceros, in0initos y 4a4. En la tabla,
# e y son valores 0initos distintos de cero y ? es el resultado de # C y. .i # e y son iguales, ? es cero
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2'1
Especificacin del lenguaje C#
positivo. .i # C y es demasiado grande para representarlo en el tipo de destino, ? es un in0inito con el signo
de # C y.
y <3 C3 <e Ce NaN
# ? # # Ce <e NaN
<3 Cy <3 <3 Ce <e NaN
C3 Cy C3 <3 Ce <e NaN
<e <e <e <e NaN <e NaN
Ce Ce Ce Ce Ce NaN NaN
NaN NaN NaN NaN NaN NaN NaN
;esta de nHmeros decimalesG
decimal o&erator C (decimal # decimal y);
.i el valor resultante es demasiado grande para representarlo en 0ormato decimal, se inicia una excepci-n
System.%ver-lo,)#ce&tion. 8a escala del resultado, antes de cual?uier redondeo, es la mayor de las
escalas de los dos operandos.
8a resta de decimales e?uivale al uso del operador de resta de tipo System.6ecimal.
;esta de enumeraciones. Todos los tipos de enumeraci-n proporcionan de 0orma impl5cita el siguiente
operador prede0inido, donde ) es el tipo enum y ; es el tipo subyacente de )G
; o&erator C () # ) y);
Este operador se evalHa exactamente como (;)((;)# C (;)y). Es decir, el operador calcula la di0erencia
entre los valores ordinales de # e y, y el tipo del resultado es el tipo subyacente de la enumeraci-n.
) o&erator C () # ; y);
Este operador se evalHa exactamente como ())((;)# C y). Es decir, el operador resta un valor del tipo
subyacente de la enumeraci-n, ?ue produce un valor de la enumeraci-n.
Eliminaci-n de delegados. Todos los tipos delegados proporcionan impl5citamente el siguiente operador
prede0inido, donde 6 es el tipo delegadoG
6 o&erator C (6 # 6 y);
El operador binario < reali1a la eliminaci-n de delegados cuando los dos operandos son de un tipo delegado
6. .i los operandos tienen tipos de delegado distintos, se produce un error en tiempo de compilaci-n. .i el
primer operando es null, el resultado de la operaci-n tambi)n es null. En caso contrario, si el segundo
operando es null, el resultado de la operaci-n es el valor del primer operando. 2e lo contrario, ambos
operandos representan listas de invocaciones O[1.1R ?ue tienen una o m(s entradas, y el resultado es una
nueva lista de invocaciones ?ue se compone de la lista del primer operando con las entradas del segundo
operando ?uitadas de ella, siempre ?ue la lista del segundo operando sea una sublista apropiada contigua al
primero. O'ara determinar la igualdad de la sublista, las entradas correspondientes se comparan en
cuanto al operador de igualdad del delegado O[*.+.8R.R En caso contrario, el resultado es el valor del
operando i1?uierdo. En el proceso no se modi0ica la lista de ninguno de los operandos. .i la lista del
segundo operando coincide con varias sublistas de entradas contiguas de la lista del primero, se ?uita la
sublista coincidente situada m(s a la derec=a de las entradas contiguas. .i la eliminaci-n produce una lista
vac5a, el resultado es null. 'or e$emploG
delegate void 6(int #);
2'2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class C
{
&ublic static void M2(int i) { .> b >. !
&ublic static void M8(int i) { .> b >. !
!
class 1est
{
static void Main() {
6 cd2 + ne, 6(C.M2);
6 cd8 + ne, 6(C.M8);
6 cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd2; .. +E M2 < M8 < M8
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd2 < cd8; .. +E M8 < M2
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd8 < cd8; .. +E M2 < M2
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd8 < cd2; .. +E M2 < M8
cd9 + cd2 < cd8 < cd8 < cd2; .. M2 < M8 < M8 < M2
cd9 =+ cd2 < cd2; .. +E M2 < M8 < M8 < M2
!
!
+.- ,peradores de despla8amiento
8os operadores DD y EE permiten reali1ar operaciones de despla1amiento de bits.
shift-e2pression1
additive-e2pression
shift-e2pression DD additive-e2pression
shift-e2pression ri&ht-shift additive-e2pression
'ara una operaci-n con la 0orma # DD count o # EE count, se aplica la resoluci-n de sobrecargas de
operadores binarios O[*.2.4R con el 0in de seleccionar una implementaci-n de operador concreta. 8os operandos
se convierten a los tipos de par(metro del operador seleccionado, y el tipo del resultado es el tipo de valor
devuelto por el operador.
Cuando se declara un operador de despla1amiento sobrecargado, el tipo del primer operando siempre debe ser la
clase o estructura ?ue contiene su declaraci-n, mientras ?ue el tipo del segundo operando siempre debe ser int.
& continuaci-n se enumeran los operadores de despla1amiento prede0inidos.
2espla1amiento a la i1?uierdaG
int o&erator DD(int # int count);
uint o&erator DD(uint # int count);
long o&erator DD(long # int count);
ulong o&erator DD(ulong # int count);
El operador DD despla1a # a la i1?uierda el nHmero de bits calculados como se explica a continuaci-n.
8os bits de orden superior no comprendidos en el intervalo del tipo de resultado de # no se tienen en cuenta,
los bits restantes se despla1an a la i1?uierda y las posiciones vac5as de los bits de orden in0erior se
establecen en cero.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2'3
Especificacin del lenguaje C#
2espla1amiento a la derec=aG
int o&erator EE(int # int count);
uint o&erator EE(uint # int count);
long o&erator EE(long # int count);
ulong o&erator EE(ulong # int count);
El operador EE despla1a # a la derec=a el nHmero de bits calculados como se explica a continuaci-n.
.i # es de tipo int o long, los bits de orden in0erior de # no se tienen en cuenta, los bits restantes se
despla1an a la derec=a y las posiciones vac5as de los bits de orden superior se establecen en cero si # no es
negativo, y en uno si # es negativo.
.i # es de tipo uint o ulong, los bits de orden in0erior de # no se tienen en cuenta, los bits restantes se
despla1an a la derec=a y las posiciones vac5as de los bits de orden superior se establecen en cero.
'ara los operadores prede0inidos, el nHmero de bits del despla1amiento se calcula como se explica a
continuaci-nG
.i el tipo de # es int o uint, el valor del despla1amiento viene dado por los cinco bits de orden in0erior de
count. Es decir, el recuento del despla1amiento se calcula a partir de count F 3#2V.
.i el tipo de # es long o ulong, el valor del despla1amiento viene dado por los seis bits de orden in0erior
de count. Es decir, el recuento del despla1amiento se calcula a partir de count F 3#9V.
.i el valor del despla1amiento resultante es cero, los operadores de despla1amiento sencillamente devuelven el
valor de #.
8as operaciones de despla1amiento nunca causan desbordamientos y producen el mismo resultado en los
contextos c"ec(ed y unc"ec(ed.
.i el operando i1?uierdo del operador EE es de un tipo integral con signo, el operador reali1a un despla1amiento
arit%?tico a la derec=a, en el cual el valor del bit m(s signi0icativo Oel bit de signoR del operando se propaga a
las posiciones vac5as de los bits de orden superior. .i el operando i1?uierdo del operador EE es de un tipo
integral sin signo, el operador reali1a un despla1amiento l/&ico a la derec=a, en el cual las posiciones vac5as de
los bits de orden superior siempre se establecen en cero. 'ara reali1ar la operaci-n opuesta de la in0erida a partir
del tipo del operando, pueden utili1arse conversiones expl5citas. 'or e$emplo, si # es una variable de tipo int, la
operaci-n unc"ec(ed((int)((uint)# EE y)) reali1a un despla1amiento l-gico a la derec=a de #.
+.. ,peradores de comprobacin de tipos y relacionales
8os operadores ++, @+, D, E, D+, E+, is y as se denominan operadores relacionales y de comprobaci-n de tipos.
relational-e2pression1
shift-e2pression
relational-e2pression D shift-e2pression
relational-e2pression E shift-e2pression
relational-e2pression D+ shift-e2pression
relational-e2pression E+ shift-e2pression
relational-e2pression is t#pe
relational-e2pression as t#pe
e6alit#-e2pression1
relational-e2pression
e6alit#-e2pression ++ relational-e2pression
e6alit#-e2pression @+ relational-e2pression
El operador is se describe en [*.+.1", y el operador as en [*.+.11.
2'# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8os operadores ++, @+, D, E, D+ y E+ son operadores de coparaci,n. 'ara una operaci-n con la 0orma # op y,
donde op es un operador de comparaci-n, se aplica la resoluci-n de sobrecargas de operadores binarios O[R para
seleccionar una implementaci-n de operador concreta. 8os operandos se convierten a los tipos de par(metro del
operador seleccionado, y el tipo del resultado es el tipo de valor devuelto por el operador.
8os operadores de comparaci-n prede0inidos se describen en las siguientes secciones. Todos los operadores de
comparaci-n prede0inidos devuelven un resultado de tipo bool, como se muestra en la tabla siguiente.
7peracin /esultado
# ++ y
true si # es igual a y, -alse en los dem(s casos
# @+ y
true si # no es igual a y, -alse en los dem(s casos
# D y
true si # es menor ?ue y, -alse en los dem(s casos
# E y
true si # es mayor ?ue y, -alse en los dem(s casos
# D+ y
true si # es menor o igual ?ue y, -alse en los dem(s casos
# E+ y
true si # es mayor o igual ?ue y, -alse en los dem(s casos
+...1 ,peradores de comparacin de enteros
8os operadores de comparaci-n de enteros prede0inidos sonG
bool o&erator ++(int # int y);
bool o&erator ++(uint # uint y);
bool o&erator ++(long # long y);
bool o&erator ++(ulong # ulong y);
bool o&erator @+(int # int y);
bool o&erator @+(uint # uint y);
bool o&erator @+(long # long y);
bool o&erator @+(ulong # ulong y);
bool o&erator D(int # int y);
bool o&erator D(uint # uint y);
bool o&erator D(long # long y);
bool o&erator D(ulong # ulong y);
bool o&erator E(int # int y);
bool o&erator E(uint # uint y);
bool o&erator E(long # long y);
bool o&erator E(ulong # ulong y);
bool o&erator D+(int # int y);
bool o&erator D+(uint # uint y);
bool o&erator D+(long # long y);
bool o&erator D+(ulong # ulong y);
bool o&erator E+(int # int y);
bool o&erator E+(uint # uint y);
bool o&erator E+(long # long y);
bool o&erator E+(ulong # ulong y);
Todos estos operadores comparan los valores num)ricos de los dos operandos enteros y devuelven un valor
bool ?ue indica si la relaci-n concreta es true o -alse.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2'!
Especificacin del lenguaje C#
+...2 ,peradores de comparacin de punto flotante
8os operadores de comparaci-n de punto 0lotante prede0inidos sonG
bool o&erator ++(-loat # -loat y);
bool o&erator ++(double # double y);
bool o&erator @+(-loat # -loat y);
bool o&erator @+(double # double y);
bool o&erator D(-loat # -loat y);
bool o&erator D(double # double y);
bool o&erator E(-loat # -loat y);
bool o&erator E(double # double y);
bool o&erator D+(-loat # -loat y);
bool o&erator D+(double # double y);
bool o&erator E+(-loat # -loat y);
bool o&erator E+(double # double y);
8os operadores comparan los operandos segHn las reglas del est(ndar !EEE *4G
.i uno de los operandos es 4a4, el resultado es -alse para todos los operadores excepto @+, cuyo resultado
es true. 'ara dos operandos cuales?uiera, # @+ y siempre produce el mismo resultado ?ue @(# ++ y). 4o
obstante, si uno o los dos operandos son 4a4, los operadores D, E, D+ y E+ no prodcen el mismo resultado
?ue la negaci-n l-gica del operador opuesto. 'or e$emplo, si # o y es 4a4, entonces # D y es -alse, pero @
(# E+ y) es true.
.i ninguno de los operandos es 4a4, los operadores comparan los valores de los dos operandos de punto
0lotante con respecto al orden
Ce D Cma# D ... D Cmin D C3.3 ++ <3.3 D <min D ... D <ma# D <e
donde min y ma# son los valores 0initos positivos m(ximo y m5nimo ?ue pueden representarse en el 0ormato
de punto 0lotante. .on e0ectos notables de este ordenG
o El cero negativo y el positivo se consideran iguales.
o 7n in0inito negativo se considera menor ?ue todos los dem(s valores, pero igual ?ue otro in0inito
negativo.
o 7n in0inito positivo se considera mayor ?ue todos los dem(s valores, pero igual ?ue otro in0inito
positivo.
+...3 ,peradores de comparacin decimales
8os operadores de comparaci-n de decimales prede0inidos sonG
bool o&erator ++(decimal # decimal y);
bool o&erator @+(decimal # decimal y);
bool o&erator D(decimal # decimal y);
bool o&erator E(decimal # decimal y);
bool o&erator D+(decimal # decimal y);
bool o&erator E+(decimal # decimal y);
Todos estos operadores comparan los valores num)ricos de los dos operandos decimales y devuelven un valor
bool ?ue indica si la relaci-n concreta es true o -alse. Cada comparaci-n de decimales e?uivale al uso del
operador relacional o de igualdad correspondiente de tipo System.6ecimal.
2'6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
+...! ,peradores de igualdad booleanos
8os operadores de igualdad booleanos prede0inidos sonG
bool o&erator ++(bool # bool y);
bool o&erator @+(bool # bool y);
El resultado de ++ es true si tanto # como y son true o si tanto # como y son -alse. 2e lo contrario, el
resultado es -alse.
El resultado de @+ es -alse si tanto # como y son true o si tanto # como y son -alse. 2e lo contrario, el
resultado es true. .i los operandos son de tipo bool, el operador @+ produce el mismo resultado ?ue G.
+...# ,peradores de comparacin de tipo de enumeracin
Todos los tipos de enumeraci-n proporcionan impl5citamente los siguientes operadores de comparaci-n
prede0inidosG
bool o&erator ++() # ) y);
bool o&erator @+() # ) y);
bool o&erator D() # ) y);
bool o&erator E() # ) y);
bool o&erator D+() # ) y);
bool o&erator E+() # ) y);
El resultado de evaluar # op y, donde # e y son expresiones de un tipo de enumeraci-n ) con un tipo subyacente
;, y op es uno de los operadores de comparaci-n, es exactamente el mismo ?ue el de evaluar ((;)#) op
((;)y). Esto es lo mismo ?ue decir ?ue los operadores de comparaci-n de tipo de enumeraci-n sencillamente
comparan los valores subyacentes integrales de los dos operandos.
+...$ ,peradores de igualdad de tipos de referencia
8os operadores de igualdad de tipos de re0erencia prede0inidos sonG
bool o&erator ++(object # object y);
bool o&erator @+(object # object y);
8os operadores devuelven el resultado de comparar la igualdad o desigualdad de las dos re0erencias.
2ado ?ue los operadores de igualdad de tipos de re0erencia prede0inidos aceptan operandos de tipo object, se
aplican a todos los tipos ?ue no declaran miembros aplicables o&erator ++ y o&erator @+. & la inversa,
cual?uier operador de igualdad aplicable de0inido por el usuario oculta los operadores de igualdad prede0inidos
de tipos de re0erencia.
8os operadores de igualdad de tipos de re0erencia prede0inidos re?uieren uno de los siguientes puntosG
bue los dos operandos sean valores de tipo de re0erencia Oreference-t#peR o el literal null. &dem(s,
re?uieren ?ue exista una conversi-n impl5cita est(ndar O[#.3.1R del tipo de uno de los operandos al tipo del
otro operando.
bue un operando sea un valor de tipo 1 donde 1 es un par(metro de tipo Ot#pe-para%eterR y el otro
operando sea el literal null. &dem(s, 1 no debe tener la restricci-n de tipo de valor.
& menos ?ue una de estas dos condiciones sean verdaderas, se producir( un error de compilaci-n. .on
implicaciones notables de estas reglasG
'roduce un error durante la compilaci-n utili1ar los operadores de igualdad de tipos de re0erencia
prede0inidos para comparar dos re0erencias de las ?ue se sabe ?ue son di0erentes en tiempo de compilaci-n.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2'(
Especificacin del lenguaje C#
'or e$emplo, si los tipos de los operandos en tiempo de compilaci-n 0ueran dos tipos de clases ' y :, y si ni
' ni : se derivaran del otro, no ser5a posible ?ue los operandos =icieran re0erencia al mismo ob$eto. 'or lo
tanto, la operaci-n se considera un error de compilaci-n.
8os operadores de igualdad de tipos de re0erencia prede0inidos no permiten la comparaci-n de operandos de
tipo de valor. 'or lo tanto, salvo ?ue un tipo struct declare sus propios operadores de igualdad, no es posible
comparar valores de ese tipo struct.
8os operadores de igualdad de tipos de re0erencia prede0inidos nunca causan operaciones boxing para sus
operandos. 4o tendr5a sentido reali1ar este tipo de operaciones boxing, puesto ?ue las re0erencias a las
instancias convertidas mediante boxing reci)n asignadas di0erir5an necesariamente de todas las dem(s
re0erencias.
.i un operando de un tipo 1 de par(metro de tipo se compara con null, y el tipo en tiempo de e$ecuci-n de
1 es un tipo de valor, el resultado de la comparaci-n es -alse.
En el siguiente e$emplo se comprueba si un argumento de un tipo de par(metro de tipo sin restricciones es null.
class CD1E
{
void V(1 #) {
i- (# ++ null) t"ro, ne, 'rgumentNull)#ce&tion();
...
!
!
8a construcci-n # ++ null se permite aun?ue 1 represente un tipo de valor y el resultado se de0ina simplemente
como -alse cuando 1 es un tipo de valor.
'ara una operaci-n con la 0orma # ++ y o # @+ y, si existe un o&erator ++ u o&erator @+ aplicable, las
reglas de resoluci-n de sobrecargas de operador O[R seleccionan este operador en lugar del operador de igualdad
de tipos de re0erencia prede0inido. 4o obstante, siempre es posible seleccionar el operador de igualdad de tipos
de re0erencia prede0inido mediante la conversi-n expl5cita de uno o los dos operandos al tipo object. En el
e$emplo
using System;
class 1est
{
static void Main() {
string s + "1est";
string t + string.Co&y(s);
Console.WriteLine(s ++ t);
Console.WriteLine((object)s ++ t);
Console.WriteLine(s ++ (object)t);
Console.WriteLine((object)s ++ (object)t);
!
!
produce el resultado
1rue
Valse
Valse
Valse
8as variables s y t =acen re0erencia a las dos instancias Hnicas de string ?ue contienen los mismos caracteres.
8a primera comparaci-n produce 1rue a causa de la selecci-n del operador de igualdad de cadenas prede0inido
O[*.+.*R cuando los dos operandos son de tipo string. Todas las comparaciones restantes producen Valse a
causa de la selecci-n del operador de igualdad de tipos de re0erencia prede0inido cuando uno o los dos
operandos son de tipo object.
2'$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
T)ngase en cuenta ?ue la t)cnica anterior no tiene sentido para los tipos de valor. En el e$emplo
class 1est
{
static void Main() {
int i + 289;
int j + 289;
System.Console.WriteLine((object)i ++ (object)j);
!
!
produce Valse por?ue las conversiones de tipos crean re0erencias a dos instancias distintas de valores int
convertidos mediante boxing.
+...+ ,peradores de igualdad de cadenas
8os operadores de igualdad de cadenas prede0inidos sonG
bool o&erator ++(string # string y);
bool o&erator @+(string # string y);
2os valores string se consideran iguales cuando una de las siguientes condiciones es verdaderaG
8os dos valores son null.
8os dos valores son re0erencias no nulas a instancias de cadenas ?ue tienen una longitud id)ntica y
caracteres id)nticos en cada posici-n de car(cter.
8os operadores de igualdad de cadenas comparan valores de cadenas y no referencias a cadenas. Cuando dos
instancias de cadena distintas contienen exactamente la misma secuencia de caracteres, los valores de las
cadenas son iguales, pero las re0erencias son di0erentes. Como se explica en la [*.+.#, los operadores de
igualdad de tipos de re0erencia sirve para comparar re0erencias de cadenas en lugar de valores de cadenas.
+...- ,peradores de igualdad de delegados
Todos los tipos delegados proporcionan impl5citamente los siguientes operadores de comparaci-n prede0inidosG
bool o&erator ++(System.6elegate # System.6elegate y);
bool o&erator @+(System.6elegate # System.6elegate y);
2os instancias de delegados se consideran iguales en los siguientes casosG
.i una de las instancias de delegado es null, son iguales si y solamente si las dos son null.
.i los dos delegados tienen un tipo en tiempo de e$ecuci-n di0erente, no ser(n nunca iguales.
.i ambas instancias de delegado tienen una lista de invocaciones O[1.1R, dic=as instancias son iguales si y
solamente si sus listas de invocaciones tienen la misma longitud, y cada entrada de la lista de invocaciones
de una es igual a la entrada correspondiente Ocomo se de0ine a continuaci-nR, por orden, de la lista de
invocaciones de la otra.
8as entradas de las listas de invocaciones deben cumplir las siguientes reglasG
.i dos entradas de las listas de invocaciones =acen re0erencia al mismo m)todo est(tico, entonces las
entradas se consideran iguales.
.i dos entradas de las listas de invocaciones =acen re0erencia al mismo m)todo no est(tico en el mismo
ob$eto de destino Otal como de0inen los operadores de igualdad de re0erenciaR, se considera ?ue las entradas
son iguales.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2'"
Especificacin del lenguaje C#
8as entradas de las listas de invocaci-n generadas en la evaluaci-n de expresiones de 0unciones an-nimas
Oanon#%os-fnction-e2pressionsR de sem(ntica id)ntica con el mismo con$unto Oposiblemente vac5oR de
instancias de variables externas capturadas pueden ser iguales Oaun?ue no es obligatorioR.
+.... ,peradores de igualdad y 1566
8os operadores ++ y Ei permiten ?ue un operando sea un valor de un tipo ?ue acepta valores 4788 y el otro el
literal null, incluso si no existe un operador prede0inido ni de0inido por el usuario Oen 0ormato de elevaci-n o
de no elevaci-nR para la operaci-n.
'ara una operaci-n con las estructuras
# ++ null null ++ # # @+ null null @+ #
donde # es una expresi-n de un tipo ?ue acepta valores 4788, si la resoluci-n de sobrecargas de operadores
O[*.2.4R no encuentra un operador aplicable, el resultado se calcula a partir de la propiedad HasUalue de #. En
concreto, las primeras dos estructuras se traducen como @#.HasUalue y las Hltimas dos estructuras se traducen
como #.HasUalue.
+...10 ,perador Is
El operador is se utili1a para comprobar din(micamente si el tipo en tiempo de e$ecuci-n de un ob$eto es
compatible con un tipo dado. El resultado de la operaci-n ) is 1, donde ) es una expresi-n y 1 es un tipo, es un
valor booleano ?ue indica si ) puede convertirse de 0orma satis0actoria al tipo 1 mediante una conversi-n de
re0erencias, una conversi-n boxing o una conversi-n unboxing. 8a operaci-n se evalHa de la siguiente manera,
una ve1 sustituidos los argumentos de tipo por todos los par(metros de tipoG
.i ) es una 0unci-n an-nima, se produce un error durante la compilaci-n
.i ) es un grupo de m)todos o el literal null, o si el tipo de ) es un tipo de re0erencia o un tipo ?ue acepta
valores 4788 y el valor de ) es null, el resultado es 0alse.
2e lo contrario, 6 representa el tipo din(mico de ) de la siguiente maneraG
o .i el tipo de ) es un tipo de re0erencia, 6 es el tipo en tiempo de e$ecuci-n de la instancia a la ?ue ) =ace
re0erencia.
o .i el tipo de ) es un tipo ?ue acepta valores 4788, 6 es el tipo subyacente del tipo ?ue acepta valores
4788.
o .i el tipo de ) es un tipo de valor ?ue no acepta valores 4788, 6 es el tipo de ).
El resultado de la operaci-n depende de 6 y 1 de la siguiente maneraG
o .i 1 es un tipo de re0erencia, el resultado es true si 6 y 1 son el mismo tipo, si 6 es un tipo de re0erencia
y existe una conversi-n de re0erencia impl5cita de 6 a 1 o si 6 es un tipo de valor y existe una
conversi-n boxing de 6 a 1.
o .i 1 es un tipo ?ue acepta valores 4788, el resultado es true si 6 es el tipo subyacente de 1.
o .i 1 es un tipo de valor ?ue no acepta valores 4788, el resultado es true si 6 y 1 son el mismo tipo.
o 2e lo contrario, el resultado es -alse.
Tenga en cuenta ?ue el operador is no tiene en cuenta las conversiones de0inidas por el usuario.
+...11 ,perador 's
El operador as permite convertir expl5citamente un valor a un tipo de re0erencia dado mediante una conversi-n
de re0erencia o tipo ?ue acepta valores 4788. & di0erencia de una expresi-n de conversi-n de tipos O[*.#.#R, el
21' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
operador as nunca inicia una excepci-n. En lugar de ello, si la conversi-n indicada no es posible, el valor
resultante es null.
En una operaci-n con la estructura ) as 1, ) debe ser una expresi-n y 1 debe ser un tipo de re0erencia, un
par(metro de tipo conocido como un tipo de re0erencia o un tipo ?ue acepta valores 4788. &l menos una de las
siguientes a0irmaciones debe ser trueV de lo contrario, se genera un error en tiempo de compilaci-nG
Existe una conversi-n de identidad O[#.1.1R, una conversi-n impl5cita ?ue acepta valores null, O[#.1.4R, una
conversi-n de re0erencia impl5cita O[#.1.#R, una conversi-n boxing O[#.1.*R, una conversi-n expl5cita ?ue
acepta valores nullO[#.2.3R una conversi-n de re0erencia O[#.2.4R o una conversi-n unboxing O[#.2.R
desde ) a 1.
El tipo de ) o 1 es un tipo abierto.
) es el literal null.
8a operaci-n ) as 1 genera el mismo resultado ?ue
) is 1 7 (1)()) / (1)null
salvo ?ue ) s-lo se evalHa una ve1. .e puede esperar ?ue el compilador optimice ) as 1 para reali1ar como
m(ximo una comprobaci-n de tipo din(mico por oposici-n a las dos comprobaciones de tipo din(mico
implicadas por la expansi-n anterior.
Tenga en cuenta ?ue algunas conversiones, como las de0inidas por el usuario, no son posibles con el operador
as y deben reali1arse mediante expresiones de conversi-n de tipos OcastR.
En el e$emplo
class I
{
&ublic string V(object o) {
return o as string; .. %a string is a re-erence ty&e
!
&ublic 1 SD1E(object o) ,"ere 1/ 'ttribute {
return o as 1; .. %( 1 "as a class constraint
!
&ublic ; HD;E(object o) {
return o as ;; .. )rror ; is unconstrained
!
!
el par(metro de tipo 1 de S es un tipo de re0erencia, por?ue tiene la restricci-n de clase. .in embargo, el
par(metro de tipo ; de H no lo esV por lo tanto, no se permite el uso del operador as en H.
+.10 ,peradores lgicos
8os operadores F, G y H se denominan operadores l-gicos.
and-e2pression1
e6alit#-e2pression
and-e2pression F e6alit#-e2pression
e2clsive-or-e2pression1
and-e2pression
e2clsive-or-e2pression G and-e2pression
inclsive-or-e2pression1
e2clsive-or-e2pression
inclsive-or-e2pression H e2clsive-or-e2pression
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 211
Especificacin del lenguaje C#
'ara una operaci-n con la 0orma # op y, donde op es uno de los operadores l-gicos, se aplica la resoluci-n de
sobrecargas de operadores binarios O[R para seleccionar una implementaci-n de operador concreta. 8os
operandos se convierten a los tipos de par(metro del operador seleccionado, y el tipo del resultado es el tipo de
valor devuelto por el operador.
8os operadores l-gicos prede0inidos se describen en las siguientes secciones.
+.10.1 ,peradores lgicos enteros
8os operadores l-gicos enteros prede0inidos sonG
int o&erator F(int # int y);
uint o&erator F(uint # uint y);
long o&erator F(long # long y);
ulong o&erator F(ulong # ulong y);
int o&erator H(int # int y);
uint o&erator H(uint # uint y);
long o&erator H(long # long y);
ulong o&erator H(ulong # ulong y);
int o&erator G(int # int y);
uint o&erator G(uint # uint y);
long o&erator G(long # long y);
ulong o&erator G(ulong # ulong y);
El operador F calcula la operaci-n l-gica 'N6 bit a bit de los dos operandos, el operador H calcula la operaci-n
l-gica %O bit a bit de los dos operandos y el operador G calcula la operaci-n l-gica %O exclusivo bit a bit de los
dos operandos. 8os desbordamientos no son posibles en estas operaciones.
+.10.2 ,peradores lgicos de enumeracin
Todo tipo de enumeraci-n ) proporciona impl5citamente los siguientes operadores l-gicos prede0inidosG
) o&erator F() # ) y);
) o&erator H() # ) y);
) o&erator G() # ) y);
El resultado de evaluar # op y, donde # e y son expresiones de un tipo de enumeraci-n ) con un tipo subyacente
;, y op es uno de los operadores l-gicos, es exactamente el mismo ?ue el de evaluar OER((;)# op (;)y). Esto
es lo mismo ?ue decir ?ue los operadores l-gicos de tipo de enumeraci-n sencillamente e$ecutan la operaci-n
l-gica en el tipo subyacente de los dos operandos.
+.10.3 ,peradores lgicos booleanos
8os operadores l-gicos booleanos prede0inidos sonG
bool o&erator F(bool # bool y);
bool o&erator H(bool # bool y);
bool o&erator G(bool # bool y);
El resultado de # F y es true si tanto # como y son true. 2e lo contrario, el resultado es -alse.
El resultado de # H y es true si # o y es true. 2e lo contrario, el resultado es -alse.
El resultado de # G y es true si # es true e y es -alse, o si # es -alse e y es true. 2e lo contrario,
el resultado es -alse. .i los operandos son de tipo bool, el operador G calcula el mismo resultado ?ue
el operador @+.
212 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
+.10.! ,peradores lgicos booleanos ;ue aceptan alores 1566
El tipo booleano bool7 ?ue acepta valores 4788 puede representar tres valores, true, -alse y null, y es
conceptualmente similar al tipo de tres valores utili1ado por expresiones booleanas en .b8. 'ara asegurarse de
?ue los resultados generados por los operadores F y H para los operandos bool7 son co=erentes con la l-gica de
tres valores de .b8 se proporcionan los siguientes operadores prede0inidosG
bool7 o&erator F(bool7 # bool7 y);
bool7 o&erator H(bool7 # bool7 y);
En la siguiente tabla se enumeran los resultados generados por estos operadores para todas las combinaciones de
los valores true, -alse y null.
# y # F y # H y
true true true true
true -alse -alse true
true null null true
-alse true -alse true
-alse -alse -alse -alse
-alse null -alse null
null true null true
null -alse -alse null
null null null null
+.11 ,peradores lgicos condicionales
8os operadores FF y HH se denominan operadores l-gicos condicionales. Tambi)n se conocen como operadores
l-gicos de evaluaci-n PcortocircuitadaQ.
conditional-and-e2pression1
inclsive-or-e2pression
conditional-and-e2pression FF inclsive-or-e2pression
conditional-or-e2pression1
conditional-and-e2pression
conditional-or-e2pression HH conditional-and-e2pression
8os operadores FF y HH son versiones condicionales de los operadores F y HG
8a operaci-n # FF y corresponde a la operaci-n # F y, excepto ?ue y se evalHa solamente si # no es -alse.
8a operaci-n # HH y corresponde a la operaci-n # H y, excepto ?ue y se evalHa solamente si # no es true.
7na operaci-n de la 0orma # FF y o # HH y se procesa mediante la aplicaci-n de la resoluci-n de sobrecargas
O[*.2.4R como si la operaci-n estuviera escrita como # F y o # H y. Entonces,
.i la resoluci-n de sobrecargas no encuentra un solo operador me$or o selecciona uno de los operadores
l-gicos enteros prede0inidos, se produce un error durante la compilaci-n.
En caso contrario, si el operador seleccionado es uno de los operadores l-gicos booleanos prede0inidos
O[*.1".3R u operadores l-gicos booleanos ?ue aceptan valores 4788 O[*.1".4R, la operaci-n se procesa
como se explica en la secci-n [*.11.1.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 213
Especificacin del lenguaje C#
/ bien, el operador seleccionado es un operador de0inido por el usuario y la operaci-n se procesa como se
explica en [*.11.2.
4o es posible sobrecargar directamente los operadores l-gicos condicionales. 4o obstante, dado ?ue los
operadores l-gicos condicionales se evalHan en t)rminos de los operadores l-gicos regulares, las sobrecargas de
)stos, con algunas restricciones, tambi)n se consideran sobrecargas de los operadores l-gicos condicionales.
Esta categor5a se explica con m(s detalle en la secci-n [*.11.2.
+.11.1 ,peradores lgicos condicionales booleanos
.i los operandos de FF o HH son de tipo bool, o si los operandos son de tipos ?ue no de0inen un o&erator F o
un o&erator H aplicable, pero s5 de0inen conversiones impl5citas a bool, la operaci-n se procesa como sigueG
8a operaci-n # FF y se evalHa como # 7 y / -alse. En otras palabras, primero se evalHa # y se convierte al
tipo bool. 2espu)s, si # es true, y se evalHa y se convierte al tipo bool, y se convierte en el resultado de
la operaci-n. 2e lo contrario, el resultado de la operaci-n es -alse.
8a operaci-n # HH y se evalHa como # 7 true / y. En otras palabras, primero se evalHa # y se convierte al
tipo bool. 2espu)s, si el valor de # es true, el resultado de la operaci-n es true. / bien, y se evalHa y se
convierte al tipo bool, y pasa a ser el resultado de la operaci-n.
+.11.2 ,peradores lgicos condicionales definidos por el usuario
.i los operandos de FF o de HH son de tipos ?ue declaran un operador o&erator F o un operador o&erator H
aplicable de0inidos por el usuario, las dos siguientes declaraciones deben ser verdaderas, donde 1 es el tipo en
?ue se declara el operador seleccionadoG
El tipo del valor devuelto y el tipo de todos los par(metros del operador seleccionado debe ser 1. Es decir, el
operador debe calcular el 'N6 l-gico o el %O l-gico de los dos operandos de tipo 1, y debe devolver un
resultado de tipo 1.
1 debe contener declaraciones de o&erator true y o&erator -alse.
.i alguno de estos re?uisitos no se satis0ace, se produce un error de compilaci-n. / bien, la operaci-n FF o HH
se evalHa mediante la combinaci-n de operadores o&erator true u o&erator -alse de0inidos por el
usuario con el operador seleccionado de0inido por el usuarioG
8a operaci-n # FF y se evalHa como 1.-alse(#) 7 # / 1.F(# y), donde 1.-alse(#) es una
invocaci-n del elemento o&erator -alse declarado en 1, y 1.F(# y) es una invocaci-n del elemento
o&erator F seleccionado. En otras palabras, # es el primero en evaluarse y se invoca o&erator -alse
en el resultado para averiguar si # es de0initivamente 0alse. 2espu)s, si # es de0initivamente 0alse, el
resultado de la operaci-n es el valor previamente calculado para #. 2e lo contrario, se evalHa y y se invoca
el operador o&erator F seleccionado en el valor previamente calculado para # y el valor calculado para y,
a 0in de producir el resultado de la operaci-n.
8a operaci-n # HH y se evalHa como 1.true(#) 7 # / 1.H(# y), donde 1.true(#) es una invocaci-n
del elemento o&erator true declarado en 1, y 1.H(# y) es una invocaci-n del elemento o&erator H
seleccionado. En otras palabras, # es el primero en evaluarse y se invoca o&erator true en el resultado
para averiguar si # es de0initivamente true. 2espu)s, si # es de0initivamente true, el resultado de la
operaci-n es el valor previamente calculado para #. 2e lo contrario, se evalHa y y se invoca el operador
o&erator H seleccionado en el valor previamente calculado para # y el valor calculado para y, a 0in de
producir el resultado de la operaci-n.
En cual?uiera de estas operaciones, la expresi-n dada por # se evalHa una sola ve1, y la expresi-n dada por y no
se evalHa o bien se evalHa exactamente una ve1.
'ara obtener un e$emplo de un tipo ?ue implementa o&erator true y o&erator -alse, vea [11.4.2.
21# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
+.12 El operador de uso combinado de 1566
El operador 77 se denomina operador de uso combinado de 4788.
nll-coalescin&-e2pression1
conditional-or-e2pression
conditional-or-e2pression 77 nll-coalescin&-e2pression
7na expresi-n de uso combinado de 4788 con la estructura a 77 b re?uiere ?ue a sea un tipo ?ue acepta
valores 4788 o un tipo de re0erencia. .i a no es 4788, el resultado de a 77 b es aV de lo contrario, el resultado
es b. 8a operaci-n evalHa b s-lo si a es 4788.
El operador de uso combinado de 4788 es asociativo por la derec=a, lo ?ue signi0ica ?ue las operaciones se
agrupan de derec=a a i1?uierda. 'or e$emplo, una expresi-n con la 0orma a 77 b 77 c se evalHa como a 77 (b
77 c). En t)rminos generales, una expresi-n con la estructura )2 77 )8 77 ... 77 )N devuelve el primero de los
operandos ?ue no es 4788 o ?ue lo es si todos son 4788.
El tipo de expresi-n a 77 b depende de ?u) conversiones impl5citas est(n disponibles entre los tipos de
operandos. En orden de pre0erencia, el tipo de a 77 b es '3, ', o :, donde ' es el tipo de a, : es el tipo de b
Osiempre ?ue b tenga un tipoR, y '3 es el tipo subyacente de ' si ' es un tipo ?ue acepta valores 4788, o, en
caso contrario, '. En concreto, a 77 b se procesa de la siguiente maneraG
.i ' no es un tipo ?ue acepta valores 4788 o un tipo de re0erencia, se genera un error en tiempo de
compilaci-n.
.i ' es un tipo ?ue acepta valores 4788 y existe una conversi-n impl5cita de b a '3, el tipo de resultado es
'3. En tiempo de e$ecuci-n, a se evalHa en primer lugar. .i a no es 4788, a se desa$usta en el tipo '3y )ste
se convierte en el resultado. 2e lo contrario, b se evalHa y se convierte al tipo '3y )ste se convierte en el
resultado.
2e lo contrario, si existe una conversi-n impl5cita de b a ', el tipo de resultado es '. En tiempo de
e$ecuci-n, a se evalHa primero. .i a no es 4788, a se convierte en el resultado. 2e lo contrario, b se evalHa
y se convierte al tipo ' y )ste se convierte en el resultado.
2e lo contrario, si b tiene un tipo : existe una conversi-n impl5cita de '3 a :, el tipo de resultado es :. En
tiempo de e$ecuci-n, a se evalHa primero. .i a no es 4788, a se desa$usta en el tipo '3 Oa menos ?ue ' y '3
sean del mismo tipoR y se convierte en tipo : y )ste se convierte en el resultado. 2e lo contrario, b se evalHa
y se convierte en el resultado.
2e lo contrario, a y b son incompatibles y se genera un error en tiempo de compilaci-n.
+.13 ,perador condicional
El operador 7/ se denomina operador condicional. & veces tambi)n se le denomina operador ternario.
conditional-e2pression1
nll-coalescin&-e2pression
nll-coalescin&-e2pression 7 e2pression / e2pression
7na expresi-n condicional con la estructura b 7 # / y evalHa en primer lugar la condici-n b. 2espu)s, si el
valor de b es true, se evalHa # y pasa a ser el resultado de la operaci-n. 2e lo contrario, se evalHa y, ?ue se
convierte en el resultado de la operaci-n. 7na expresi-n condicional nunca evalHa # e y.
El operador condicional es asociativo por la derec=a, lo ?ue signi0ica ?ue las operaciones se agrupan de derec=a
a i1?uierda. 'or e$emplo, una expresi-n con la 0orma a 7 b / c 7 d / e se evalHa como a 7 b / (c 7 d / e).
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 21!
Especificacin del lenguaje C#
El primer operando del operador 7/ debe ser una expresi-n de un tipo ?ue pueda convertirse impl5citamente a
bool o una expresi-n de un tipo ?ue implemente o&erator true. .i no se cumple ninguna de estas dos
condiciones, se producir( un error de compilaci-n.
El segundo y tercer operandos del operador 7/ controlan el tipo de la expresi-n condicional. .upongamos ?ue I
e ` sean los tipos del segundo y tercer operandos. EntoncesG
.i I e ` son del mismo tipo, entonces )ste es el tipo de la expresi-n condicional.
/ bien, si existe una conversi-n impl5cita O[#.1R de I a `, pero no de ` a I, entonces ` es el tipo de la
expresi-n condicional.
/ bien, si existe una conversi-n impl5cita O[#.1R de ` a I, pero no de I a `, entonces I es el tipo de la
expresi-n condicional.
En caso contrario, no puede determinarse una expresi-n y se produce un error de compilaci-n.
El procesamiento en tiempo de e$ecuci-n de una expresi-n condicional con la estructura b 7 # / y consta de los
siguientes pasosG
En primer lugar, se evalHa b y se determina el valor bool de bG
o .i existe una conversi-n impl5cita del tipo de b a bool, se e$ecuta dic=a conversi-n para generar un
valor bool.
o 2e lo contrario, se invoca el o&erator true de0inido por el tipo de b para generar un valor bool.
.i el valor bool producido por el paso anterior es true, entonces se evalHa # y se convierte al tipo de la
expresi-n condicional, ?ue pasa a ser el resultado de la expresi-n condicional.
/ bien, y se evalHa y se convierte al tipo de la expresi-n condicional, y pasa a ser el resultado de dic=a de
expresi-n.
+.1! E"presiones de funciones annimas
7na f!nci,n an,nia es una expresi-n ?ue representa una de0inici-n de m)todo Pen l5neaQ. 7na 0unci-n
an-nima no tiene un valor de por s5, pero se puede convertir en un tipo de (rbol de expresiones o un tipo
delegado compatible. 8a evaluaci-n de una conversi-n de 0unci-n an-nima depende del tipo de destino de la
conversi-n. .i es un tipo delegado, la conversi-n se evalHa para un valor delegado ?ue =ace re0erencia al m)todo
en el ?ue se de0ine la 0unci-n an-nima. .i es un tipo de (rbol de expresiones, la conversi-n se evalHa para un
(rbol de expresiones ?ue representa la estructura del m)todo como una estructura de ob$etos.
'or motivos =ist-ricos =ay dos tipos sint(cticos de 0unciones an-nimas, las expresiones lambda Ola%-da-
e2pressionsR y las expresiones de m)todos an-nimos Oanon#%os-%ethod-e2pressionsR. En casi todos los casos,
las expresiones lambda Ola%-da-e2pressionsR son m(s concisas y expresivas ?ue las expresiones de m)todos
an-nimos Oanon#%os-%ethod-e2pressionsR, ?ue siguen presentes en el lengua$e para mantener la
compatibilidad con versiones anteriores.
la%-da-e2pression1
anon#%os-fnction-si&natre +E anon#%os-fnction--od#
anon#%os-%ethod-e2pression1
delegate e2plicit-anon#%os-fnction-si&natre
opt
-loc3
anon#%os-fnction-si&natre1
e2plicit-anon#%os-fnction-si&natre
i%plicit-anon#%os-fnction-si&natre
216 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
e2plicit-anon#%os-fnction-si&natre1
( e2plicit-anon#%os-fnction-para%eter-list
opt
)
e2plicit-anon#%os-fnction-para%eter-list
e2plicit-anon#%os-fnction-para%eter
e2plicit-anon#%os-fnction-para%eter-list e2plicit-anon#%os-fnction-para%eter
e2plicit-anon#%os-fnction-para%eter1
anon#%os-fnction-para%eter-%odifier
opt
t#pe identifier
anon#%os-fnction-para%eter-%odifier1
re-
out
i%plicit-anon#%os-fnction-si&natre1
( i%plicit-anon#%os-fnction-para%eter-list
opt
)
i%plicit-anon#%os-fnction-para%eter
i%plicit-anon#%os-fnction-para%eter-list
i%plicit-anon#%os-fnction-para%eter
i%plicit-anon#%os-fnction-para%eter-list i%plicit-anon#%os-fnction-para%eter
i%plicit-anon#%os-fnction-para%eter1
identificador
anon#%os-fnction--od#1
e2pression
-loc3
El operador +E tiene la misma prioridad ?ue la asignaci-n O+R y es asociativo por la derec=a.
8os par(metros de una 0unci-n an-nima con la estructura de una expresi-n lambda Ola%-da-e2pressionR pueden
tener asignaci-n de tipo impl5cita o expl5cita. En una lista de par(metros con asignaci-n de tipo expl5cita, el tipo
de cada par(metro se indica de manera expl5cita. En una lista de par(metros con asignaci-n de tipo impl5cita, los
tipos de los par(metros se in0ieren del contexto en el ?ue tiene lugar la 0unci-n an-nima. Concretamente, cuando
la 0unci-n an-nima se convierte a un tipo delegado compatible o un tipo de (rbol de expresiones, ese tipo
proporciona los tipos de par(metros O[#.R.
En una 0unci-n an-nima con un solo par(metro con asignaci-n de tipo impl5cita, los par)ntesis de la lista de
par(metros se pueden omitir. En otras palabras, una 0unci-n an-nima con la 0orma
( para% ) +E e2pr
se puede abreviar a
para% +E e2pr
8a lista de par(metros de una 0unci-n an-nima con la 0orma de una expresi-n de m)todo an-nimo Oanon#%os-
%ethod-e2pressionR es opcional. 8os par(metros deben tener asignaci-n de tipo expl5cita, en caso de tener tipo.
.i no, la 0unci-n an-nima es convertible a un delegado con cual?uier lista de par(metros ?ue no contenga
par(metros out.
& continuaci-n, se muestran algunos e$emplos de 0unciones an-nimasG
# +E # < 2 .. $m&licitly ty&ed e#&ression body
# +E { return # < 2; ! .. $m&licitly ty&ed statement body
(int #) +E # < 2 .. )#&licitly ty&ed e#&ression body
(int #) +E { return # < 2; ! .. )#&licitly ty&ed statement body
(# y) +E # > y .. Multi&le &arameters
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 21(
Especificacin del lenguaje C#
() +E Console.WriteLine() .. No &arameters
delegate (int #) { return # < 2; ! .. 'nonymous met"od e#&ression
delegate { return 2 < 2; ! .. *arameter list omitted
El comportamiento de las expresiones lambda Ola%-da-e2pressionsR y las expresiones de m)todos an-nimos
Oanon#%os-%ethod-e2pressionsR es igual excepto en los siguientes puntosG
8as expresiones de m)todos an-nimos Oanon#%os-%ethod-e2pressionsR permiten ?ue una lista de
par(metros se omita por completo, lo ?ue tiene como resultado la convertibilidad a tipos delegados de
cual?uier lista de par(metros de valor.
8as expresiones lambda Ola%-da-e2pressionsR permiten ?ue los tipos de par(metros se omitan y sean
in0eridos mientras ?ue las expresiones de m)todos an-nimos Oanon#%os-%ethod-e2pressionsR re?uieren
?ue los tipos de par(metros se indi?uen de manera expl5cita.
El cuerpo de una expresi-n lambda Ola%-da-e2pressionR puede ser una expresi-n o un blo?ue de
instrucciones mientras ?ue el cuerpo de una expresi-n de m)todos an-nimos Oanon#%os-%ethod-
e2pressionR debe ser un blo?ue de instrucciones.
2ado ?ue las expresiones lambda Ola%-da-e2pressionsR pueden tener un cuerpo de expresi-n Oe2pressionR,
no se puede convertir ninguna expresi-n de m)todos an-nimos Oanon#%os-%ethod-e2pressionR a un tipo de
(rbol de expresiones O[4.#R.
+.1!.1 7irmas de funcin annima
8a 0irma opcional de 0unci-n an-nima Oanon#%os-fnction-si&natreR de una 0unci-n an-nima de0ine los
nombres y, opcionalmente, los tipos de los par(metros 0ormales para la 0unci-n an-nima. El (mbito de los
par(metros de la 0unci-n an-nima es el cuerpo de la 0unci-n an-nima Oanon#%os-fnction--od#R. O[3.*R Junto
con la lista de par(metros Osi la =ayR el cuerpo de m)todo an-nimo constituye un espacio de declaraci-n O[3.3R.
'or tanto, si el nombre de un par(metro de la 0unci-n an-nima coincide con el nombre de una variable local, una
constante o un par(metro local cuyo (mbito incluya la expresi-n de m)todos an-nimos Oanon#%os-%ethod-
e2pressionR o la expresi-n lambda Ola%-da-e2pressionR se produce un error en tiempo de compilaci-n.
.i una 0unci-n an-nima tiene una 0irma de 0unci-n an-nima expl5cita Oe2plicit-anon#%os-fnction-si&natreR,
el con$unto de tipos delegados compatibles y los tipos de (rbol de expresiones se limitan a a?uellos con los
mismos tipos de par(metros y modi0icadores en el mismo orden. &l contrario de lo ?ue ocurre con las
conversiones de grupo de m)todos O[#.#R, no se admite la contravarian1a de tipos de par(metros de 0unci-n
an-nima. .i una 0unci-n an-nima no tiene una 0irma de 0unci-n an-nima Oanon#%os-fnction-si&natreR,
el con$unto de tipos delegados compatibles y tipos de (rbol de expresiones se limita a a?uellos ?ue no tienen
par(metros out.
Tenga en cuenta ?ue una 0irma de 0unci-n an-nima Oanon#%os-fnction-si&natreR no puede incluir atributos
ni una matri1 de par(metros. 4o obstante, una 0irma de 0unci-n an-nima Oanon#%os-fnction-si&natreR puede
ser compatible con un tipo delegado cuya lista de par(metros contenga una matri1 de par(metros.
Tenga en cuenta ?ue una conversi-n a un tipo de (rbol de expresiones, incluso si es compatible, puede no
producirse durante la compilaci-n O[4.#R.
+.1!.2 %uerpos de funcin annima
El cuerpo Oe2pression o -loc3R de una 0unci-n an-nima est( su$eto a las siguientes reglasG
.i la 0unci-n an-nima incluye una 0irma, los par(metros especi0icados en la 0irma est(n disponibles en el
cuerpo. .i la 0unci-n an-nima no tiene 0irma, se puede convertir en un tipo delegado o un tipo de expresi-n
con par(metros O[#.R, pero no se puede obtener acceso a ellos en el cuerpo.
21$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Excepto por los par(metros re- u out especi0icados en la 0irma Osi los =ubieraR de la 0unci-n an-nima
envolvente m(s cercana, si el cuerpo obtiene acceso a un par(metro re- u out se generar( un error en
tiempo de compilaci-n.
Cuando el tipo de t"is es un tipo de estructura y el cuerpo obtiene acceso a t"is, se generar( un error en
tiempo de compilaci-n. Esta a0irmaci-n es cierta independientemente de si se trata de un acceso expl5cito
Ocomo en t"is.#R o impl5cito Ocomo en #, donde # es un miembro de instancia de la estructuraR. Esta regla
simplemente pro=5be dic=o acceso y no a0ecta si la bHs?ueda de miembros da como resultado un miembro
de la estructura.
El cuerpo tiene acceso a las variables externas O[*.14.4R de la 0unci-n an-nima. El acceso de una variable
externa =ar( re0erencia a la instancia de la variable activa en el momento de la evaluaci-n de la expresi-n
lambda Ola%-da-e2pressionR o la expresi-n de m)todo an-nimo Oanon#%os-%ethod-e2pressionR O[*.14.R.
.i el cuerpo contiene una instrucci-n goto, brea( o continue cuyo destino se encuentra 0uera o dentro
del cuerpo de una 0unci-n an-nima contenida, se generar( un error en tiempo de compilaci-n.
7na instrucci-n return del cuerpo devuelve el control desde una invocaci-n de la 0unci-n an-nima
envolvente m(s cercana, no desde el miembro de 0unci-n envolvente. 7na expresi-n especi0icada en una
instrucci-n return debe ser compatible con el tipo de delegado o un tipo de (rbol de expresiones al ?ue se
convierte la expresi-n lambda Ola%-da-e2pressionR o la expresi-n de m)todo an-nimo Oanon#%os-%ethod-
e2pressionR envolvente m(s cercana O[#.R.
4o se especi0ica expl5citamente si se puede e$ecutar el blo?ue de una 0unci-n an-nima de otra manera ?ue no
sea mediante la evaluaci-n y la invocaci-n de la expresi-n lambda Ola%-da-e2pressionR o la expresi-n de
m)todo an-nimo Oanon#%os-%ethod-e2pressionR. En concreto, el compilador puede implementar una 0unci-n
an-nima si sinteti1a uno o m(s m)todos o tipos con nombre. 8os nombres de dic=os elementos sinteti1ados
deben tener la 0orma reservada para uso del compilador.
+.1!.3 9esolucin de sobrecargas
8as 0unciones an-nimas de una lista de argumentos participan en la resoluci-n de sobrecargas y en la in0erencia
de tipos. 'ara conocer las reglas exactas vea la secci-n [*.4.2.3.
El e0ecto de las 0unciones an-nimas en la resoluci-n de las sobrecargas se ilustra en el siguiente e$emploG
class $temListD1E/ ListD1E
{
&ublic int Sum(VuncD1intE selector) {
int sum + 3;
-oreac" (1 item in t"is) sum <+ selector(item);
return sum;
!
&ublic double Sum(VuncD1doubleE selector) {
double sum + 3;
-oreac" (1 item in t"is) sum <+ selector(item);
return sum;
!
!
8a clase $temListD1E tiene dos m)todos Sum. Cada uno toma un argumento selector, ?ue extrae el valor
?ue se va a sumar de un elemento de la lista. El valor extra5do puede ser int o double, y la suma resultante es
igualmente int o double.
8os m)todos Sum podr5an por e$emplo utili1arse para calcular sumas de una lista de l5neas de datos en un
pedido.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 21"
Especificacin del lenguaje C#
class 6etail
{
&ublic int ;nitCount;
&ublic double ;nit*rice;
...
!
void Com&uteSums() {
$temListD6etailE order6etails + Set%rder6etails(...);
int total;nits + order6etails.Sum(d +E d.;nitCount);
double order1otal + order6etails.Sum(d +E d.;nit*rice > d.;nitCount);
...
!
En la primera invocaci-n de order6etails.Sum, ambos m)todos Sum son aplicables por?ue la 0unci-n
an-nima d +E d.;nitCount es compatible tanto con VuncD6etailintE como con
VuncD6etaildoubleE. .in embargo, la resoluci-n de sobrecargas elige el primer m)todo Sum por?ue la
conversi-n a VuncD6etailintE es me$or ?ue la conversi-n a VuncD6etaildoubleE.
En la segunda invocaci-n de order6etails.Sum, s-lo es aplicable el m)todo Sum por?ue la 0unci-n an-nima
d +E d.;nit*rice > d.;nitCount produce un valor de tipo double. 'or tanto, la resoluci-n de sobrecargas
elige el segundo m)todo Sum para esa invocaci-n.
+.1!.! Variables e"ternas
Cual?uier variable local, par(metro de valor o matri1 de par(metros en cuyo (mbito se incluya la expresi-n
lambda Ola%-da-e2pressionR o una expresi-n de m)todo an-nimo Oanon#%os-%ethod-e2pressionR se denomina
varia/le e.terna de la expresi-n de 0unci-n an-nima. En un miembro de 0unci-n de instancia de una clase, el
valor t"is se considera un par(metro de valor y es una variable externa de cual?uier expresi-n de 0unci-n
an-nima contenida dentro del miembro de 0unci-n.
#.14.4.1 .ariables e2ternas capturadas
Cuando una 0unci-n an-nima =ace re0erencia a una variable externa, se dice ?ue la 0unci-n an-nima capt!r, la
variable externa. 2e manera general, la duraci-n de una variable local est( limitada por la e$ecuci-n del blo?ue o
de una instrucci-n a la ?ue est( asociada O[.1.*R. .in embargo, la duraci-n de una variable externa capturada se
ampl5a al menos =asta ?ue el delegado o el (rbol de expresiones creado a partir de la 0unci-n an-nima pueda
convertirse en una recolecci-n de elementos no utili1ados.
En el e$emplo
using System;
delegate int 6();
class 1est
{
static 6 V() {
int # + 3;
6 result + () +E <<#;
return result;
!
static void Main() {
6 d + V();
Console.WriteLine(d());
Console.WriteLine(d());
Console.WriteLine(d());
!
!
22' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
la 0unci-n an-nima captura la variable local # y el per5odo de duraci-n de # se ampl5a =asta ?ue el delegado
devuelto desde V pasa a 0ormar parte de la recolecci-n de elementos no utili1ados O?ue no ocurre =asta el 0inal
del programaR. 'uesto ?ue todas las invocaciones de la 0unci-n an-nima operan en la misma instancia ?ue #, el
resultado de este e$emplo es el siguienteG
2
8
9
Cuando una 0unci-n an-nima captura una variable local o un par(metro de valor, la variable local o el par(metro
ya no se considera una variable de tipo 0i$o O[18.3R, sino una variable m-vil. 'or lo tanto, todo c-digo unsa-e
?ue adopte la direcci-n de una variable externa capturada debe primero utili1ar la instrucci-n -i#ed para 0i$ar la
variable.
#.14.4.2 Creacin de instancias de variables locales
.e considera ?ue se crearon instancias de una variable local cuando la e$ecuci-n entra dentro del (mbito de la
variable. 'or e$emplo, cuando se invoca el siguiente m)todo, se crean instancias de la variable local #, ?ue se
iniciali1a tres veces, una para cada iteraci-n del bucle.
static void V() {
-or (int i + 3; i D 9; i<<) {
int # + i > 8 < 2;
...
!
!
.in embargo, si la declaraci-n de # se despla1a 0uera del bucle, s-lo se crear( una Hnica instancia de #G
static void V() {
int #;
-or (int i + 3; i D 9; i<<) {
# + i > 8 < 2;
...
!
!
Cuando no existe captura, no se puede saber con ?u) 0recuencia exacta se crean instancias de una variable local.
'uesto ?ue los per5odos de creaci-n de instancias son independientes es posible ?ue cada ve1 ?ue se crean
instancias se utilice la misma ubicaci-n de almacenamiento. .in embargo, cuando una 0unci-n an-nima captura
una variable local, los e0ectos de la creaci-n de instancias son obvios.
En el e$emplo
using System;
delegate void 6();
class 1est
{
static 645 V() {
645 result + ne, 6495;
-or (int i + 3; i D 9; i<<) {
int # + i > 8 < 2;
result4i5 + () +E { Console.WriteLine(#); !;
!
return result;
!
static void Main() {
-oreac" (6 d in V()) d();
!
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 221
Especificacin del lenguaje C#
se genera el siguiente resultadoG
2
9
K
.in embargo, cuando la declaraci-n de # se traslada 0uera del bucleG
static 645 V() {
645 result + ne, 6495;
int #;
-or (int i + 3; i D 9; i<<) {
# + i > 8 < 2;
result4i5 + () +E { Console.WriteLine(#); !;
!
return result;
!
el resultado esG
K
K
K
.i un bucle 0or declara una variable de iteraci-n, la propia variable se considera declarada 0uera del bucle. 'or
tanto, si el e$emplo cambia para capturar la variable de iteraci-n en s5G
static 645 V() {
645 result + ne, 6495;
-or (int i + 3; i D 9; i<<) {
result4i5 + () +E { Console.WriteLine(i); !;
!
return result;
!
s-lo se captura una instancia de la variable de iteraci-n, ?ue produce el resultadoG
9
9
9
8a 0unci-n an-nima puede compartir algunas de las variables capturadas y tener instancias separadas de otras.
'or e$emplo, si V se cambia a
static 645 V() {
645 result + ne, 6495;
int # + 3;
-or (int i + 3; i D 9; i<<) {
int y + 3;
result4i5 + () +E { Console.WriteLine("{3! {2!" <<# <<y); !;
!
return result;
!
los tres delegados capturan la misma instancia de # y di0erentes instancias de y, y el resultado esG
2 2
8 2
9 2
2istintas 0unciones an-nimas pueden capturar la misma instancia de una variable externa. En el siguiente
e$emploG
using System;
delegate void Setter(int value);
delegate int Setter();
222 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class 1est
{
static void Main() {
int # + 3;
Setter s + (int value) +E { # + value; !;
Setter g + () +E { return #; !;
s(K);
Console.WriteLine(g());
s(23);
Console.WriteLine(g());
!
!
las dos 0unciones an-nimas capturan la misma instancia de la variable local # y, por lo tanto, se pueden
PcomunicarQ a trav)s de dic=a variable. El resultado del e$emplo es el siguienteG
K
23
+.1!.# E"presiones de ealuacin de funciones annimas
7na 0unci-n an-nima V siempre se debe convertir a un tipo delegado 6 o un tipo de (rbol de expresiones ), ya
sea directamente o mediante la e$ecuci-n de una expresi-n de creaci-n de delegado ne, 6(V). Esta conversi-n
determina el resultado de la 0unci-n an-nima, como se describe en la secci-n [#..
+.1# E"presiones de consulta
8as e.presiones de cons!lta proporcionan una sintaxis integrada de lengua$es para las consultas ?ue son
similares a los lengua$es de consulta $er(r?uicos y relacionales, como .b8 y Nbuery.
6er#-e2pression1
fro%-clase 6er#--od#
fro%-clase1
-rom t#pe
opt
identifier in e2pression
6er#--od#1
6er#--od#-clases
opt
select-or-&rop-clase 6er#-contination
opt
6er#--od#-clases1
6er#--od#-clase
6er#--od#-clases 6er#--od#-clase
6er#--od#-clase1
fro%-clase
let-clase
where-clase
>oin-clase
>oin-into-clase
order-#-clase
let-clase1
let identifier + e2pression
where-clase1
,"ere -oolean-e2pression
>oin-clase1
join t#pe
opt
identifier in e2pression on e2pression eQuals e2pression
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 223
Especificacin del lenguaje C#
>oin-into-clase1
join t#pe
opt
identifier in e2pression on e2pression eQuals e2pression into identifier
order-#-clase1
orderby orderin&s
orderin&s1
orderin&
orderin&s orderin&
orderin&1
e2pression orderin&-direction
opt
orderin&-direction1
ascending
descending
select-or-&rop-clase1
select-clase
&rop-clase
select-clase1
select e2pression
&rop-clase1
grou& e2pression by e2pression
6er#-contination1
into identifier 6er#--od#
7na expresi-n de consulta empie1a con una cl(usula -rom y termina con una cl(usula select o grou&. 8a
cl(usula -rom inicial puede ir seguida de cero o m(s cl(usulas -rom, let, ,"ere, join u orderby. Cada
cl(usula -rom es un generador ?ue introduce una varia/le de intervalo en los elementos de una sec!encia. Cada
cl(usula let introduce una variable de intervalo ?ue representa un valor calculado mediante variables de
intervalo anteriores. Cada cl(usula ,"ere es un 0iltro ?ue excluye elementos del resultado. Cada cl(usula join
compara las claves especi0icadas de la secuencia de origen con las claves de otra secuencia, dando como
resultado pares coincidentes. Cada cl(usula orderby reordena los elementos segHn criterios especi0icados. 8a
cl(usula select o grou& 0inal especi0ica la 0orma del resultado en t)rminos de variables de intervalo. 'or
Hltimo, una cl(usula into se puede usar para P$untarQ consultas tratando los resultados de una consulta como un
generador en una consulta subsiguiente.
+.1#.1 'mbigAedad en e"presiones de consulta
8as expresiones de consulta contienen varias Ppalabras clave contextualesQ, es decir, identi0icadores ?ue tienen
un signi0icado especial en un contexto dado. Concretamente, se trata de -rom, ,"ere, join, on, eQuals,
into, let, orderby, ascending, descending, select, grou& y by. 'ara evitar ambigIedades en las
expresiones de consultas originadas por la me1cla en el uso de estos identi0icadores como palabras clave o como
nombres comunes, los identi0icadores se consideran palabras clave cuando tienen lugar dentro de una expresi-n
de consulta.
Con este 0in, una expresi-n de consulta siempre empe1ar( con P-rom identifierQ OP-rom identificadorQR e ir(
seguida de un to6en especial excepto P;Q, P+Q o PQ.
'ara poder utili1ar estas palabras como identi0icadores dentro de una expresi-n de consulta, pueden ir pre0i$adas
con P[Q O[2.4.2R.
22# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
+.1#.2 Traduccin de e"presiones de consulta
El lengua$e C# no especi0ica la sem(ntica de e$ecuci-n en expresiones de consulta. En lugar de eso, las
expresiones de consulta se traducen en invocaciones de m)todos ?ue se ad=ieren al patr-n de expresiones de
consulta O[*.1.3R. Concretamente, las expresiones de consulta se traducen en invocaciones de m)todos
denominados W"ere, Select, SelectMany, ]oin, Srou&]oin, %rder:y, %rder:y6escending, 1"en:y,
1"en:y6escending, Srou&:y y Cast. .e espera ?ue estos m)todos tengan tipos de resultados y 0irmas
particulares, tal como se describe en la secci-n [. Estos m)todos pueden ser m)todos de instancia del ob$eto
sobre el ?ue se reali1a la consulta o m)todos de extensi-n externos al ob$eto, e implementan la e$ecuci-n real de
la consulta.
8a traducci-n de expresiones de consulta a invocaciones de m)todo es una asignaci-n sint(ctica ?ue tiene lugar
antes de ?ue se produ1ca cual?uier enlace de tipos o resoluci-n de sobrecargas. .e garanti1a ?ue la traducci-n es
correcta desde el punto de vista sint(ctico, pero no se garanti1a ?ue produ1ca c-digo de C# correcto desde el
punto de vista sem(ntico. 2espu)s de la traducci-n de las expresiones de consulta, las invocaciones de m)todo
resultantes se procesan como invocaciones de m)todo comunes, y este procesamiento puede a su ve1 descubrir
errores, por e$emplo si los m)todos no existen, si los argumentos tienen tipos err-neos, o si los m)todos son
gen)ricos y se produce un error en la inter0a1 de tipos.
7na expresi-n de consulta se procesa aplicando repetidamente las siguientes traducciones =asta ?ue no =ay m(s
reducciones posibles. 8as traducciones se enumeran en orden de aplicaci-nG cada secci-n asume ?ue las
traducciones de las secciones precedentes se =an reali1ado de manera ex=austiva, y una ve1 agotada, una secci-n
no volver( a ser visitada en el procesamiento de la misma expresi-n de consulta.
8a asignaci-n a variables de intervalo no est( permitida en expresiones de consulta. .in embargo, se permite ?ue
una implementaci-n de C# no siempre exi$a esta restricci-n por?ue algunas veces no es posible con el es?uema
de conversi-n sint(ctico a?u5 presentado.
2eterminadas traducciones insertan variables de intervalo con identificadores transparentes ?ue se denotan
mediante >. 8as propiedades especiales de los identi0icadores transparentes se discuten con m(s detalle en la
secci-n [*.1.2.*.
#.1.2.1 Clusulas !elect y 9roupby con continuaciones
7na expresi-n de consulta con una continuaci-n
-rom A into 2 A
se traduce en
-rom 2 in ( -rom A ) A
8as traducciones en las siguientes secciones asumen ?ue las consultas no tienen continuaciones into.
El e$emplo
-rom c in customers
grou& c by c.Country into g
select ne, { Country + g.aey CustCount + g.Count() !
se traduce en
-rom g in
-rom c in customers
grou& c by c.Country
select ne, { Country + g.aey CustCount + g.Count() !
cuya traducci-n 0inal es
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 22!
Especificacin del lenguaje C#
customers.
Srou&:y(c +E c.Country).
Select(g +E ne, { Country + g.aey CustCount + g.Count() !)
#.1.2.2 :ipos de variable de intervalo e2plCcitos
7na cl(usula -rom ?ue especi0ica expl5citamente un tipo de variable de intervalo
-rom B 2 in e
se traduce en
-rom 2 in ( e ) . Cast D B E ( )
7na cl(usula join ?ue especi0ica expl5citamente un tipo de variable de intervalo
join B 2 in e on 3
1
eQuals 3
2
se traduce en
join 2 in ( e ) . Cast D B E ( ) on 3
1
eQuals 3
2
8as traducciones en las siguientes secciones asumen ?ue las consultas no tienen tipos de variables de intervalo
expl5citos.
El e$emplo
-rom Customer c in customers
,"ere c.City ++ "London"
select c
se traduce en
-rom c in customers.CastDCustomerE()
,"ere c.City ++ "London"
select c
cuya traducci-n 0inal es
customers.
CastDCustomerE().
W"ere(c +E c.City ++ "London")
8os tipos de variable de intervalo expl5citos son Htiles para reali1ar consultas en colecciones ?ue implementan la
inter0a1 $)numerable no gen)rica, pero no la inter0a1 $)numerableD1E gen)rica. En el e$emplo anterior, )ste
ser5a el caso si customers 0uera de tipo 'rrayList.
#.1.2.3 &2presiones de consulta de"eneradas
7na expresi-n de consulta con la estructura
-rom 2 in e select 2
se traduce en
( e ) . Select ( 2 +E 2 )
El e$emplo
-rom c in customers
select c
se traduce en
customers.Select(c +E c)
226 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
7na expresi-n de consulta degenerada es a?uella ?ue selecciona de manera trivial los elementos del origen. En una
0ase posterior de la traducci-n se ?uitan las consultas degeneradas introducidas por otros pasos de traducci-n
reempla1(ndolas por su origen. Es importante, no obstante, asegurar ?ue el resultado de una expresi-n de consulta
nunca sea el propio ob$eto de origen, ya ?ue esto revelar5a el tipo y la identidad del origen al cliente de la consulta.
2e este modo, este paso protege las consultas degeneradas escritas directamente en el c-digo de origen llamando a
Select en el origen. & partir de ese momento corresponde a los implementadores de Select y los dem(s
operadores de consulta garanti1ar ?ue estos m)todos nunca devuelvan el ob$eto de origen en s5.
#.1.2.4 Clusulas 3rom, let, ,-ere, =oin y orderby
7na expresi-n de consulta con una segunda cl(usula -rom seguida de una cl(usula select
-rom 2
1
in e
1
-rom 2
2
in e
2
select v
se traduce en
( e
1
) . SelectMany( 2
1
+E e
2
( 2
1
2
2
) +E v )
7na expresi-n de consulta con una segunda cl(usula -rom seguida de otra cl(usula ?ue no sea selectG
-rom 2
1
in e
1
-rom 2
2
in e
2
b
se traduce en
-rom > in ( e
1
) . SelectMany( 2
1
+E e
2
( 2
1
2
2
) +E ne, { 2
1
2
2
! )
b
7na expresi-n de consulta con una cl(usula let
-rom 2 in e
let # + f
A
se traduce en
-rom > in ( e ) . Select ( 2 +E ne, { 2 # + f ! )
b
7na expresi-n de consulta con una cl(usula ,"ere
-rom 2 in e
,"ere f
A
se traduce en
-rom 2 in ( e ) . W"ere ( 2 +E f )
b
7na expresi-n de consulta con una cl(usula join sin una cl(usula into, y seguida de una cl(usula select
-rom 2
1
in e
1
join 2
2
in e
2
on 3
1
eQuals 3
2
select v
se traduce en
( e
1
) . ]oin( e
2
2
1
+E 3
1
2
2
+E 3
2
( 2
1
2
2
) +E v )
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 22(
Especificacin del lenguaje C#
7na expresi-n de consulta con una cl(usula join sin una cl(usula into, y seguida de una cl(usula ?ue no es
select
-rom 2
1
in e
1
join 2
2
in e
2
on 3
1
eQuals 3
2

b
se traduce en
-rom > in ( e
1
) . ]oin(
e
2
2
1
+E 3
1
2
2
+E 3
2
( 2
1
2
2
) +E ne, { 2
1
2
2
!)
b
7na expresi-n de consulta con una cl(usula join y una cl(usula into, y seguida de una cl(usula select
-rom 2
1
in e
1
join 2
2
in e
2
on 3
1
eQuals 3
2
into &
select v
se traduce en
( e
1
) . Srou&]oin( e
2
2
1
+E 3
1
2
2
+E 3
2
( 2
1
& ) +E v )
7na expresi-n de consulta con una cl(usula join y una cl(usula into, y seguida de una cl(usula ?ue no es
select
-rom 2
1
in e
1
join 2
2
in e
2
on 3
1
eQuals 3
2
into &
b
se traduce en
-rom > in ( e
1
) . Srou&]oin(
e
2
2
1
+E 3
1
2
2
+E 3
2
( 2
1
& ) +E ne, { 2
1
& !)
b
7na expresi-n de consulta con una cl(usula orderby
-rom 2 in e
orderby 3
1
3
2
b 3
n
A
se traduce en
-rom 2 in ( e ) .
%rder:y ( 2 +E 3
1
) .
1"en:y ( 2 +E 3
2
) .
A .
1"en:y ( 2 +E 3
n
)
b
.i una cl(usula de tipo order especi0ica un indicador de direcci-n descending, se produce en su lugar una
invocaci-n de %rder:y6escending o 1"en:y6escending.
8as siguientes traducciones asumen ?ue no =ay ninguna cl(usula let, ,"ere, join u orderby, y no m(s de
una cl(usula -rom inicial en cada expresi-n de consulta.
El e$emplo
-rom c in customers
-rom o in c.%rders
select ne, { c.Name o.%rder$6 o.1otal !
22$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
se traduce en
customers.
SelectMany(c +E c.%rders
(co) +E ne, { c.Name o.%rder$6 o.1otal !
)
El e$emplo
-rom c in customers
-rom o in c.%rders
orderby o.1otal descending
select ne, { c.Name o.%rder$6 o.1otal !
se traduce en
-rom > in customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !)
orderby o.1otal descending
select ne, { c.Name o.%rder$6 o.1otal !
cuya traducci-n 0inal es
customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !).
%rder:y6escending(# +E #.o.1otal).
Select(# +E ne, { #.c.Name #.o.%rder$6 #.o.1otal !)
donde # es un identi0icador generado por el compilador ?ue de otro modo es invisible e inaccesible.
El e$emplo
-rom o in orders
let t + o.6etails.Sum(d +E d.;nit*rice > d.^uantity)
,"ere t E+ 2333
select ne, { o.%rder$6 1otal + t !
se traduce en
-rom > in orders.
Select(o +E ne, { o t + o.6etails.Sum(d +E d.;nit*rice > d.^uantity) !)
,"ere t E+ 2333
select ne, { o.%rder$6 1otal + t !
cuya traducci-n 0inal es
orders.
Select(o +E ne, { o t + o.6etails.Sum(d +E d.;nit*rice > d.^uantity) !).
W"ere(# +E #.t E+ 2333).
Select(# +E ne, { #.o.%rder$6 1otal + #.t !)
donde # es un identi0icador generado por el compilador ?ue de otro modo es invisible e inaccesible.
El e$emplo
-rom c in customers
join o in orders on c.Customer$6 eQuals o.Customer$6
select ne, { c.Name o.%rder6ate o.1otal !
se traduce en
customers.]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c o) +E ne, { c.Name o.%rder6ate o.1otal !)
El e$emplo
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 22"
Especificacin del lenguaje C#
-rom c in customers
join o in orders on c.Customer$6 eQuals o.Customer$6 into co
let n + co.Count()
,"ere n E+ 23
select ne, { c.Name %rderCount + n !
se traduce en
-rom > in customers.
Srou&]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c co) +E ne, { c co !)
let n + co.Count()
,"ere n E+ 23
select ne, { c.Name %rderCount + n !
cuya traducci-n 0inal es
customers.
Srou&]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c co) +E ne, { c co !).
Select(# +E ne, { # n + #.co.Count() !).
W"ere(y +E y.n E+ 23).
Select(y +E ne, { y.#.c.Name %rderCount + y.n)
donde # e y son identi0icadores generados por el compilador ?ue de otro modo son invisibles e inaccesibles.
El e$emplo
-rom o in orders
orderby o.Customer.Name o.1otal descending
select o
tiene la traducci-n 0inal
orders.
%rder:y(o +E o.Customer.Name).
1"en:y6escending(o +E o.1otal)
#.1.2. Clusulas !elect
7na expresi-n de consulta con la estructura
-rom 2 in e select v
se traduce en
( e ) . Select ( 2 +E v )
excepto cuando v es el identi0icador 2, la traducci-n es simplemente
( e )
'or e$emploG
-rom c in customers.W"ere(c +E c.City ++ RLondonT)
select c
se traduce simplemente en
customers.W"ere(c +E c.City ++ RLondonT)
#.1.2.6 Clusulas 9roupby
7na expresi-n de consulta con la estructura
-rom 2 in e grou& v by 3
se traduce en
23' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
( e ) . Srou&:y ( 2 +E 3 2 +E v )
excepto cuando v es el identi0icador 2, la traducci-n es
( e ) . Srou&:y ( 2 +E 3 )
El e$emplo
-rom c in customers
grou& c.Name by c.Country
se traduce en
customers.
Srou&:y(c +E c.Country c +E c.Name)
#.1.2.# $denti3icadores transparentes
2eterminadas traducciones insertan variables de intervalo con identificadores transparentes ?ue se denotan
mediante >. 8os identi0icadores transparentes no son una caracter5stica propia del lengua$eV existen s-lo como
un paso intermedio en el proceso de traducci-n de expresiones de consulta.
Cuando una traducci-n de consulta inserta un identi0icador transparente, los siguientes pasos de traducci-n
propagan el identi0icador transparente en 0unciones an-nimas e iniciali1adores de ob$etos an-nimos. En estos
contextos, los identi0icadores transparentes tienen el siguiente comportamientoG
Cuando un identi0icador transparente tiene lugar como par(metro en una 0unci-n an-nima, los miembros del
tipo an-nimo asociado est(n autom(ticamente en el (mbito del cuerpo de la 0unci-n an-nima.
Cuando un miembro con un identi0icador transparente est( en el (mbito, los miembros de ese miembro est(n
en el (mbito tambi)n.
Cuando un identi0icador transparente tiene lugar como un declarador de miembro en un iniciali1ador de
ob$eto an-nimo, )ste introduce un miembro con un identi0icador transparente.
En los pasos de traducci-n descritos antes, los identi0icadores transparentes siempre se introducen $unto con
tipos an-nimos, con la intenci-n de capturar varias variables de intervalo como miembros de un solo ob$eto.
.e permite ?ue una implementaci-n de C# utilice un mecanismo di0erente ?ue los tipos an-nimos para
agrupar $untas varias variables de intervalo. En la siguiente traducci-n se asume el uso de los tipos
an-nimos, y se muestra c-mo se pueden traducir los identi0icadores transparentes.
El e$emplo
-rom c in customers
-rom o in c.%rders
orderby o.1otal descending
select ne, { c.Name o.1otal !
se traduce en
-rom > in customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !)
orderby o.1otal descending
select ne, { c.Name o.1otal !
?ue se traduce a su ve1 en
customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !).
%rder:y6escending(> +E o.1otal).
Select(> +E ne, { c.Name o.1otal !)
?ue, cuando se eliminan los identi0icadores transparentes, e?uivale a
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 231
Especificacin del lenguaje C#
customers.
SelectMany(c +E c.%rders (co) +E ne, { c o !).
%rder:y6escending(# +E #.o.1otal).
Select(# +E ne, { #.c.Name #.o.1otal !)
donde # es un identi0icador generado por el compilador ?ue de otro modo es invisible e inaccesible.
El e$emplo
-rom c in customers
join o in orders on c.Customer$6 eQuals o.Customer$6
join d in details on o.%rder$6 eQuals d.%rder$6
join & in &roducts on d.*roduct$6 eQuals &.*roduct$6
select ne, { c.Name o.%rder6ate &.*roductName !
se traduce en
-rom > in customers.
]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c o) +E ne, { c o !)
join d in details on o.%rder$6 eQuals d.%rder$6
join & in &roducts on d.*roduct$6 eQuals &.*roduct$6
select ne, { c.Name o.%rder6ate &.*roductName !
?ue a su ve1 se reduce a
customers.
]oin(orders c +E c.Customer$6 o +E o.Customer$6 (c o) +E ne, { c o !).
]oin(details > +E o.%rder$6 d +E d.%rder$6 (> d) +E ne, { > d !).
]oin(&roducts > +E d.*roduct$6 & +E &.*roduct$6 (> &) +E ne, { > & !).
Select(> +E ne, { c.Name o.%rder6ate &.*roductName !)
cuya traducci-n 0inal es
customers.
]oin(orders c +E c.Customer$6 o +E o.Customer$6
(c o) +E ne, { c o !).
]oin(details # +E #.o.%rder$6 d +E d.%rder$6
(# d) +E ne, { # d !).
]oin(&roducts y +E y.d.*roduct$6 & +E &.*roduct$6
(y &) +E ne, { y & !).
Select(? +E ne, { ?.y.#.c.Name ?.y.#.o.%rder6ate ?.&.*roductName !)
donde #, y y ? son identi0icadores generados por el compilador ?ue de otro modo son invisibles e inaccesibles.
+.1#.3 El patrn de e"presiones de consulta
El patr,n de e.presiones de cons!lta establece un patr-n de m)todos ?ue los tipos pueden implementar para
poder admitir expresiones. 2ado ?ue las expresiones de consulta se traducen en invocaciones de m)todo
mediante una asignaci-n sint(ctica, los tipos tienen una 0lexibilidad considerable a la =ora de implementar el
patr-n de expresiones de consulta. 'or e$emplo, los m)todos de un patr-n se pueden implementar como m)todos
de instancia o como m)todos de extensi-n, por?ue los dos tienen la misma sintaxis de invocaci-n, y los m)todos
pueden solicitar delegados o (rboles de expresiones, por?ue las 0unciones an-nimas son convertibles a ambos.
8a 0orma recomendada de un tipo gen)rico CD1E ?ue admite el patr-n de expresiones de consulta se muestra a
continuaci-n. El tipo gen)rico se usa para poder ilustrar la relaci-n adecuada entre par(metro y tipos de
resultado, pero es posible implementar el patr-n tambi)n para tipos no gen)ricos.
delegate O VuncD12OE(12 arg2);
delegate O VuncD1218OE(12 arg2 18 arg8);
class C
{
&ublic CD1E CastD1E();
!
232 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
class CD1E / C
{
&ublic CD1E W"ere(VuncD1boolE &redicate);
&ublic CD;E SelectD;E(VuncD1;E selector);
&ublic CDUE SelectManyD;UE(VuncD1CD;EE selector
VuncD1;UE resultSelector);
&ublic CDUE ]oinD;aUE(CD;E inner VuncD1aE outeraeySelector
VuncD;aE inneraeySelector VuncD1;UE resultSelector);
&ublic CDUE Srou&]oinD;aUE(CD;E inner VuncD1aE outeraeySelector
VuncD;aE inneraeySelector VuncD1CD;EUE resultSelector);
&ublic %D1E %rder:yDaE(VuncD1aE (eySelector);
&ublic %D1E %rder:y6escendingDaE(VuncD1aE (eySelector);
&ublic CDSDa1EE Srou&:yDaE(VuncD1aE (eySelector);
&ublic CDSDa)EE Srou&:yDa)E(VuncD1aE (eySelector
VuncD1)E elementSelector);
!
class %D1E / CD1E
{
&ublic %D1E 1"en:yDaE(VuncD1aE (eySelector);
&ublic %D1E 1"en:y6escendingDaE(VuncD1aE (eySelector);
!
class SDa1E / CD1E
{
&ublic a aey { get; !
!
8os m)todos anteriores utili1an tipos delegados gen)ricos VuncD12 OE y VuncD12 18 OE, pero igualmente
podr5an =aber usado otros tipos delegados o de (rbol de expresiones con las mismas relaciones en par(metro y
tipos de resultado.
Tenga en cuenta la relaci-n recomendada entre CD1E y %D1E ?ue asegura ?ue los m)todos 1"en:y y
1"en:y6escending est(n disponibles s-lo en el resultado de %rder:y u %rder:y6escending. Tambi)n la
0orma recomendada del resultado de Srou&:y Ouna secuencia de secuenciasR, donde cada secuencia interna
tiene una propiedad aey adicional.
El espacio de nombres System.LinQ proporciona una implementaci-n del patr-n del operador de consultas
para cual?uier tipo ?ue implementa la inter0a1 System.Collections.Seneric.$)numerableD1E.
+.1$ ,peradores de asignacin
8os operadores de asignaci-n se utili1an para asignar un valor nuevo a una variable, propiedad, evento o
elemento de indi1ador.
assi&n%ent1
nar#-e2pression assi&n%ent-operator e2pression
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 233
Especificacin del lenguaje C#
assi&n%ent-operator1
+
<+
=+
>+
.+
B+
F+
H+
G+
DD+
ri&ht-shift-assi&n%ent
El operando i1?uierdo de una asignaci-n debe ser una expresi-n clasi0icada como una variable, un acceso a
propiedad, un acceso a indi1ador o un acceso a evento.
El operador + se denomina operador de asignaci,n siple. &signa el valor del operando derec=o a la variable,
propiedad o elemento de indi1ador dado por el operando i1?uierdo. El operando de la i1?uierda del operador de
asignaci-n simple puede no ser un acceso a evento Oexcepto en las condiciones descritas en [1".8.1R. El
operador de asignaci-n simple se explica en [*.1#.1.
8os operadores de asignaci-n distintos del operador + se denominan operadores de asignaci,n cop!estos.
2ic=os operadores e$ecutan la operaci-n indicada en los dos operandos y despu)s asignan el valor resultante a la
variable, propiedad o elemento de indi1ador dado por el operando i1?uierdo. 8os operadores de asignaci-n
compuesta se explican en [*.1#.2.
8os operadores <+ y =+ con una expresi-n de acceso a eventos como operando i1?uierdo se denominan
operadores de asi&naci/n de eventos. 4ingHn otro operador de asignaci-n es v(lido si incluye un acceso a
eventos como operando i1?uierdo. 8os operadores de asignaci-n de eventos se explican en [*.1#.3.
8os operadores de asignaci-n son asociativos por la derec=a, lo ?ue signi0ica ?ue las operaciones se agrupan de
derec=a a i1?uierda. 'or e$emplo, una expresi-n con la 0orma a + b + c se evalHa como a + (b + c).
+.1$.1 'signacin simple
El operador + se denomina operador de asignaci-n simple. En una asignaci-n simple, el operando derec=o debe
ser una expresi-n de un tipo ?ue pueda convertirse impl5citamente al tipo del operando i1?uierdo. 8a operaci-n
asigna el valor del operando derec=o a la variable, propiedad o elemento de indi1ador dado por el operando
i1?uierdo.
El resultado de una expresi-n de asignaci-n simple es el valor asignado al operando i1?uierdo. El resultado tiene
el mismo tipo ?ue el operando i1?uierdo y siempre se clasi0ica como un valor.
.i el operando i1?uierdo es una propiedad o un acceso a indi1ador, debe tener un descriptor de acceso set.
.i no es )ste el caso, se produce un error en tiempo de compilaci-n.
El procesamiento en tiempo de e$ecuci-n de una asignaci-n simple de la 0orma # + y consta de los siguientes pasosG
.i # se clasi0ica como una variableG
o .e evalHa # para producir la variable.
o .e evalHa y y, si es necesario, se convierte al tipo de # mediante una conversi-n impl5cita O[#.1R.
o .i la variable dada por # es un elemento de matri1 de un tipo de re0erencia Oreference-t#peR, se lleva a
cabo una comprobaci-n en tiempo de e$ecuci-n para garanti1ar ?ue el valor calculado de y es
compatible con la instancia de matri1 a la cual pertenece #. 8a comprobaci-n es satis0actoria si y es
23# Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
null o si existe una conversi-n de re0erencia impl5cita O[#.1.#R del tipo real de la instancia a ?ue =ace
re0erencia y al tipo del elemento real de la instancia de matri1 ?ue contiene a #. 2e lo contrario, se inicia
una excepci-n System.'rray1y&eMismatc")#ce&tion.
o El valor resultante de la evaluaci-n y conversi-n de y se almacena en la ubicaci-n dada por la
evaluaci-n de #.
.i # se clasi0ica como una propiedad o un acceso a indi1adorG
o .e evalHan la expresi-n de instancia Osi # no es staticR y la lista de argumentos Osi # es un acceso
a indi1adorR asociadas con #, y el resultado se utili1a en la posterior invocaci-n de descriptor de
acceso set.
o .e evalHa y y, si es necesario, se convierte al tipo de # mediante una conversi-n impl5cita O[#.1R.
o .e invoca el descriptor de acceso set de # con el valor calculado para y como su argumento value.
8as reglas de covarian1a matricial O[12.R permiten ?ue un valor de un tipo de matri1 '45 se trate como una
re0erencia a una instancia de un tipo matricial :45, siempre ?ue exista una conversi-n impl5cita de re0erencias
de : a '. 2ebido a estas reglas, la asignaci-n de un tipo de re0erencia Oreference-t#peR a un elemento de matri1
re?uiere una comprobaci-n en tiempo de e$ecuci-n para garanti1ar ?ue el valor asignado es compatible con la
instancia de matri1. En el e$emplo
string45 sa + ne, string4235;
object45 oa + sa;
oa435 + null; .. %(
oa425 + "Hello"; .. %(
oa485 + ne, 'rrayList(); .. 'rray1y&eMismatc")#ce&tion
la Hltima asignaci-n produce el inicio de la excepci-n System.'rray1y&eMismatc")#ce&tion, debido a
?ue la instancia de 'rrayList no se puede almacenar en un elemento de una cadena string45.
Cuando una propiedad o un indi1ador declarado en un tipo struct Ostrct-t#peR es el destino de una asignaci-n, la
expresi-n de instancia asociada al acceso a propiedad o a indi1ador debe estar clasi0icada como una variable. .i
la expresi-n de instancia est( clasi0icada como un valor, se produce un error de compilaci-n. Con0orme a la
[*..4, la misma regla tambi)n es aplicable a los campos.
2adas las declaracionesG
struct *oint
{
int # y;
&ublic *oint(int # int y) {
t"is.# + #;
t"is.y + y;
!
&ublic int I {
get { return #; !
set { # + value; !
!
&ublic int ` {
get { return y; !
set { y + value; !
!
!
struct Oectangle
{
*oint a b;
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 23!
Especificacin del lenguaje C#
&ublic Oectangle(*oint a *oint b) {
t"is.a + a;
t"is.b + b;
!
&ublic *oint ' {
get { return a; !
set { a + value; !
!
&ublic *oint : {
get { return b; !
set { b + value; !
!
!
del e$emploG
*oint & + ne, *oint();
&.I + 233;
&.` + 233;
Oectangle r + ne, Oectangle();
r.' + ne, *oint(23 23);
r.: + &;
las asignaciones a &.I, &.`, r.' y r.: est(n permitidas por?ue & y r son variables. 4o obstante, en el e$emploG
Oectangle r + ne, Oectangle();
r.'.I + 23;
r.'.` + 23;
r.:.I + 233;
r.:.` + 233;
las asignaciones no son v(lidas, puesto ?ue r.' y r.: no son variables.
+.1$.2 'signacin compuesta
7na operaci-n con la 0orma # op+ y se procesa mediante la aplicaci-n de la resoluci-n de sobrecargas de
operadores binarios O[*.2.4R como si la operaci-n se =ubiera escrito # op y. Entonces,
.i el tipo de valor devuelto del operador seleccionado es convertible i%pl*cita%ente al tipo de #, la
operaci-n se evalHa como # + # op y, excepto en ?ue # se evalHa una sola ve1.
/ bien, si el operador seleccionado es un operador prede0inido, si el tipo del valor devuelto del operador
seleccionado es convertible e2pl*cita%ente al tipo de #, y si y es convertible i%pl*cita%ente al tipo de #,
entonces la operaci-n se evalHa como # + (1)(# op y), donde 1 es el tipo #, excepto en ?ue # se evalHa
una sola ve1.
/ bien, la asignaci-n compuesta no es v(lida y se produce un error en tiempo de compilaci-n.
8a expresi-n Pse evalHa una sola ve1Q implica ?ue, en la evaluaci-n de # op y, el resultado de cual?uier
expresi-n ?ue 0orme parte de # se guarda temporalmente y se reutili1a cuando se reali1a la asignaci-n a #. 'or
e$emplo, en la asignaci-n '()4:()5 <+ C(), donde ' es un m)todo ?ue devuelve int45, y : y C son m)todos
?ue devuelven int, los m)todos se invocan solamente una ve1, en el orden ', :, C.
.i el operando i1?uierdo de una asignaci-n compuesta es un acceso a propiedad o un acceso a indi1ador, la
propiedad o el indi1ador debe tener un descriptor de acceso get y un descriptor de acceso set. .i no es )ste el
caso, se produce un error en tiempo de compilaci-n.
8a segunda regla mencionada permite ?ue # op+ y se evalHe como # + (1)(# op y) en ciertos contextos. 8a
regla existe para permitir utili1ar los operadores prede0inidos como operadores compuestos cuando el operando
i1?uierdo es de tipo sbyte, byte, s"ort, us"ort o c"ar. &un?ue los dos argumentos sean de uno de estos
236 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
tipos, los operadores prede0inidos producen un resultado de tipo int, como se explica en [*.2.#.2. 'or lo tanto,
sin una conversi-n, no ser5a posible asignar el resultado al operando i1?uierdo.
El e0ecto intuitivo de la regla de los operadores prede0inidos es, sencillamente, ?ue # op+ y est( permitido si
est(n permitidos # op y, y # + y. En el e$emplo
byte b + 3;
c"ar c" + WZ3W;
int i + 3;
b <+ 2; .. %(
b <+ 2333; .. )rror b + 2333 not &ermitted
b <+ i; .. )rror b + i not &ermitted
b <+ (byte)i; .. %(
c" <+ 2; .. )rror c" + 2 not &ermitted
c" <+ (c"ar)2; .. %(
el motivo intuitivo de cada error es ?ue una asignaci-n simple correspondiente tambi)n =abr5a sido un error.
Esto tambi)n signi0ica ?ue las operaciones de asignaci-n compuesta admiten operaciones de elevaci-n. En el
e$emplo
int7 i + 3;
i <+ 2; .. %(
se utili1a el operador de elevaci-n <(int7int7).
+.1$.3 'signacin de eentos
.i el operando i1?uierdo de un operador Si o Bi se clasi0ica como acceso a evento, la expresi-n se evalHa de la
siguiente 0ormaG
.i existe una expresi-n de instancia del acceso a evento, se evalHa.
.e evalHa el operando de la derec=a del operador <+ o =+ y, si 0uera necesario, se convierte al tipo del
operando de la i1?uierda mediante una conversi-n impl5cita O[#.1R.
2espu)s de la evaluaci-n y, si es necesario, tambi)n despu)s de la conversi-n, se invoca un descriptor de
acceso del evento, con la lista de argumentos 0ormada por el operando derec=o. .i el operador 0uera <+, se
invoca el descriptor de acceso addV si el operador 0uera =+, se invoca el descriptor de acceso remove.
7na expresi-n de asignaci-n de evento no produce ningHn valor. 'or tanto, una expresi-n de asignaci-n de
eventos s-lo ser( v(lida en el contexto de una expresi-n de instrucci-n Ostate%ent-e2pressionR O[8.#R.
+.1+ E"presin
7na expresi-n Oe2pressionR es una expresi-n de no asignaci-n Onon-assi&n%ent-e2pressionR o una asignaci-n
Oassi&n%entR.
e2pression1
non-assi&n%ent-e2pression
assi&n%ent
non-assi&n%ent-e2pression1
conditional-e2pression
la%-da-e2pression
6er#-e2pression
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 23(
Especificacin del lenguaje C#
+.1- E"presiones constantes
7na expresi-n constante Oconstant-e2pressionR es una expresi-n ?ue se puede evaluar totalmente en tiempo de
compilaci-n.
constant-e2pression1
e2pression
7na expresi-n constante debe ser el literal null o un valor con uno de los siguientes tiposG sbyte, byte,
s"ort, us"ort, int, uint, long, ulong, c"ar, -loat, double, decimal, bool, string, o cual?uier tipo
de enumeraci-n. .-lo las siguientes construcciones se permiten en expresiones de constantesG
8iterales Oincluido nullR.
;e0erencias a miembros const y tipos de clase y estructura.
;e0erencias a miembros de tipos de enumeraci-n.
;e0erencias a par(metros const o a variables locales
.ubexpresiones entre par)ntesis, ?ue son en s5 mismas expresiones constantes.
Expresiones de conversi-n, siempre ?ue el tipo de destino sea uno de los antes indicados.
Expresiones c"ec(ed y unc"ec(ed
Expresiones de valor predeterminadas
8os operadores unarios prede0inidos <, C, @ y A.
8os operadores binarios prede0inidos <, C, >, ., B, DD, EE, F, H, G, FF, HH, ++, @+, D, E, D+ y E+, siempre
?ue todos los operandos sean de uno de los tipos indicados anteriormente.
El operador condicional 7/.
.e permiten las siguientes conversiones en expresiones de constantesG
Conversiones de identidad
Conversiones num)ricas
Conversiones de enumeraci-n
Conversiones de expresi-n constante
Conversiones de re0erencia impl5cita y expl5cita, siempre y cuando el origen de las conversiones sea una
expresi-n constante ?ue se evalHe como null.
/tras conversiones, incluidas las conversiones boxing y unboxing, y las conversiones de re0erencia impl5cita de
valores distintos de null no se permiten en expresiones constantes. 'or e$emploG
class C {
const object i + K; .. error/ bo#ing conversion not &ermitted
const object str + R"elloT; .. error/ im&licit re-erence conversion
!
la iniciali1aci-n de i es un error por?ue es necesaria una conversi-n boxing. 8a iniciali1aci-n de str es un
error por?ue es necesaria una conversi-n de re0erencia impl5cita desde un valor distinto de null.
.iempre ?ue una expresi-n cumple los re?uisitos antes mencionados, la expresi-n se evalHa en tiempo de
compilaci-n. Esto ocurre as5 aun?ue la expresi-n sea una subBexpresi-n de una expresi-n mayor ?ue contiene
construcciones no constantes.
23$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a evaluaci-n en tiempo de compilaci-n de expresiones constantes est( regida por las mismas reglas ?ue la
evaluaci-n en tiempo de e$ecuci-n de expresiones no constantes, excepto por?ue donde la evaluaci-n en tiempo de
e$ecuci-n iniciar5a una excepci-n, la evaluaci-n en tiempo de compilaci-n causa un error de tiempo de compilaci-n.
.alvo ?ue una expresi-n constante se colo?ue expl5citamente en un contexto unc"ec(ed, los desbordamientos
?ue ocurran en las conversiones y operaciones aritm)ticas de tipo integral durante la evaluaci-n en tiempo de
compilaci-n de la expresi-n siempre causar(n errores de tiempo de compilaci-n O[*.18R.
8as expresiones constantes ocurren en los contextos ?ue se enumeran a continuaci-n. En estos contextos, se
produce un error durante la compilaci-n si una expresi-n no puede evaluarse totalmente en tiempo de compilaci-n.
2eclaraciones de constantes O[1".4R.
2eclaraciones de miembros de enumeraci-n O[14.3R.
Eti?uetas case de una instrucci-n s,itc" O[8.*.2R.
!nstrucciones goto case O[8.+.3R.
8ongitudes de dimensi-n en una expresi-n de creaci-n de matri1 O[*..1".4R ?ue incluye un iniciali1ador.
&tributos O[1*R.
7na conversi-n impl5cita de expresi-n constante O[#.1.8R permite la conversi-n de una expresi-n constante de
tipo int al tipo sbyte, byte, s"ort, us"ort, uint o ulong, siempre ?ue el valor de la expresi-n constante
?uede dentro del intervalo del tipo de destino.
+.1. E"presiones booleanas
7na expresi-n booleana O-oolean-e2pressionR es una expresi-n ?ue devuelve un resultado de tipo boolV ya sea
directamente o a trav)s de la aplicaci-n del operador true en ciertos contextos tal y como se especi0ica a
continuaci-n.
-oolean-e2pression1
e2pression
8a expresi-n condicional ?ue controla una instrucci-n i0 Oif-state%entR O[8.*.1R, instrucci-n 9=ile Owhile-
state%entR O[8.8.1R, instrucci-n do Odo-state%entR O[8.8.2R o instrucci-n 0or Ofor-state%entR O[8.8.3R es una
expresi-n booleana O-oolean-e2pressionR. 8a expresi-n condicional de control del operador 7/ O[*.13R sigue las
mismas reglas ?ue una expresi-n booleana O-oolean-e2pressionR pero, por motivos de prioridad de operadores,
se clasi0ica como una expresi-n or condicional Oconditional-or-e2pressionR.
7na expresi-n booleana O-oolean-e2pressionR debe ser de un tipo ?ue pueda convertirse impl5citamente a bool
o de un tipo ?ue implemente o&erator true. .i no se satis0ace ninguno de los re?uisitos, se produce un error
de compilaci-n.
.i una expresi-n booleana es de un tipo ?ue no puede convertirse impl5citamente a bool pero ?ue implementa
o&erator true, despu)s de la evaluaci-n de la expresi-n, se llama a la implementaci-n de o&erator true
suministrada por ese tipo para generar un valor bool.
El tipo struct 6::ool de la secci-n [11.4.2 proporciona un e$emplo de un tipo ?ue implementa o&erator
true y o&erator -alse.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 23"
Especificacin del lenguaje C#
-. Instrucciones
C# proporciona una gran variedad de instrucciones. 8a mayor5a de ellas son conocidas por los programadores de
C y CSS.
state%ent1
la-eled-state%ent
declaration-state%ent
e%-edded-state%ent
e%-edded-state%ent1
-loc3
e%pt#-state%ent
e2pression-state%ent
selection-state%ent
iteration-state%ent
>%p-state%ent
tr#-state%ent
chec3ed-state%ent
nchec3ed-state%ent
loc3-state%ent
sin&-state%ent
#ield-state%ent
8a instrucci-n incrustada Oe%-edded-state%enR sin terminaci-n se utili1a en instrucciones ?ue aparecen dentro
de otras instrucciones. El uso de una instrucci-n incrustada Oe%-edded-state%entR en lugar de una instrucci-n
Ostate%entR permite ?ue no sea necesario utili1ar instrucciones de declaraci-n y con eti?ueta en dic=os
contextos. El e$emplo
void V(bool b) {
i- (b)
int i + JJ;
!
da como resultado un error en tiempo de compilaci-n, ya ?ue una instrucci-n i- re?uiere una instrucci-n
incrustada Oe%-edded-state%entR en lugar de una instrucci-n Ostate%entR para su rama i0. .i se admitiera este
c-digo, la variable i se declarar5a pero no se utili1ar5a nunca. /bserve, sin embargo, ?ue si coloca la declaraci-n
de i en un blo?ue, el e$emplo es v(lido.
-.1 (untos finales y alcance
Toda instrucci-n tiene un p!nto final. 2e manera intuitiva, el punto 0inal de una instrucci-n es la ubicaci-n ?ue
sigue a la instrucci-n. 8as reglas para la e$ecuci-n de instrucciones compuestas Oinstrucciones ?ue contienen
instrucciones incrustadasR especi0ican las acciones a tomar cuando el control llega al punto 0inal de una
instrucci-n incrustada. 'or e$emplo, cuando el control llega al punto 0inal de una instrucci-n dentro de un
blo?ue, pasa a la siguiente instrucci-n del blo?ue.
.i una instrucci-n tiene posibilidades de e$ecutarse, se dice ?ue la instrucci-n es alcan-a/le. 2e manera inversa,
si una instrucci-n no tiene ninguna posibilidad de e$ecutarse, se dice ?ue es una instrucci-n inalcan-a/le.
2#' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
En el e$emplo
void V() {
Console.WriteLine("reac"able");
goto Label;
Console.WriteLine("unreac"able");
Label/
Console.WriteLine("reac"able");
!
la segunda llamada a Console.WriteLine es inalcan1able por?ue no =ay posibilidad de ?ue se e$ecute la
instrucci-n.
.i el compilador determina ?ue existe alguna instrucci-n inalcan1able, emite una advertencia. bue una
instrucci-n sea inalcan1able no es un error propiamente dic=o.
'ara determinar si una determinada instrucci-n o punto 0inal es o no alcan1able, el compilador reali1a un
an(lisis del 0lu$o del programa de acuerdo con las reglas de alcance de0inidas para cada instrucci-n. El an(lisis
de 0lu$o tiene en cuenta los valores de expresiones de constantes O[*.18R ?ue controlan el comportamiento de las
instrucciones, pero no considera los posibles valores de expresiones de variables. En otras palabras, en el
an(lisis de 0lu$o se considera ?ue una expresi-n de variable de un determinado tipo puede tener cual?uier valor
posible de dic=o tipo.
En el e$emplo
void V() {
const int i + 2;
i- (i ++ 8) Console.WriteLine("unreac"able");
!
la expresi-n booleana de la instrucci-n i- es una expresi-n constante por?ue los dos operandos del operador ++
son constantes. 8a expresi-n constante se evalHa en tiempo de compilaci-n y, como devuelve el valor -alse, la
llamada a Console.WriteLine se considera inalcan1able. .in embargo, si i se convierte en una variable local
void V() {
int i + 2;
i- (i ++ 8) Console.WriteLine("reac"able");
!
la invocaci-n a Console.WriteLine se considera alcan1able, aun?ue en realidad no se e$ecutar( nunca.
El blo?ue O-loc3R de un miembro de 0unci-n siempre se considera alcan1able. Evaluando sucesivamente las
reglas de alcance de cada instrucci-n de un blo?ue, puede determinarse el alcance de una determinada
instrucci-n.
En el e$emplo
void V(int #) {
Console.WriteLine("start");
i- (# D 3) Console.WriteLine("negative");
!
el alcance de la segunda instrucci-n Console.WriteLine se determina de la 0orma siguienteG
8a primera instrucci-n de la expresi-n Console.WriteLine es alcan1able, ya ?ue el blo?ue del m)todo
V tambi)n lo es.
El punto 0inal de la primera instrucci-n Console.WriteLine es alcan1able por?ue esta instrucci-n
tambi)n lo es.
8a instrucci-n i- es alcan1able por?ue el punto 0inal de la primera instrucci-n Console.WriteLine
tambi)n lo es.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2#1
Especificacin del lenguaje C#
'or Hltimo, como la expresi-n booleana de la instrucci-n i- no tiene el valor constante -alse, la segunda
instrucci-n Console.WriteLine es alcan1able.
Existen dos situaciones en las ?ue supone un error en tiempo de compilaci-n ?ue el punto 0inal de una
instrucci-n sea alcan1ableG
Como la instrucci-n s,itc" no admite ?ue de una secci-n Pse paseQ a la siguiente secci-n, supone un error
en tiempo de compilaci-n ?ue el punto 0inal de la lista de instrucciones de una secci-n de s9itc= sea
alcan1able. Este error suele producirse cuando 0alta una instrucci-n brea(.
Es un error ?ue sea alcan1able el punto 0inal del blo?ue de un miembro de 0unci-n ?ue calcula un valor. Este
error suele producirse cuando 0alta una instrucci-n return.
-.2 <lo;ues
7n blo?ue O-loc3R permite escribir varias instrucciones en contextos donde se permite una Hnica instrucci-n.
-loc31
{ state%ent-list
opt
!
7n blo?ue O-loc3R est( 0ormado por una lista de instrucciones Ostate%ent-listR opcional O[8.2.1R, encerrada entre
llaves. .i se omite la lista de instrucciones, se dice ?ue el blo?ue es un blo?ue vac5o.
7n blo?ue puede contener instrucciones de declaraci-n O[8.R. El (mbito de una variable o constante local
declarada en un blo?ue es el propio blo?ue.
2entro de un blo?ue, el signi0icado de un nombre utili1ado en un contexto de expresi-n siempre debe ser el
mismo O[*..2.1R.
7n blo?ue se e$ecuta de la siguiente 0ormaG
.i el blo?ue est( vac5o, el control se trans0iere al punto 0inal del blo?ue.
.i no est( vac5o, el control se trans0iere a la lista de instrucciones. Cuando el control alcan1a el punto 0inal
de la lista de instrucciones, se trans0iere al punto 0inal del blo?ue.
8a lista de instrucciones de un blo?ue es alcan1able si el propio blo?ue es alcan1able.
El punto 0inal de un blo?ue es alcan1able si el blo?ue est( vac5o o si el punto 0inal de la lista de instrucciones es
alcan1able.
7n blo?ue O-loc3R ?ue contiene una o m(s instrucciones yield O[8.14R se denomina blo?ue de iteradores. 8os
blo?ues de iteradores se utili1an para implementar miembros de 0unci-n como iteradores O[1".14R. & los
blo?ues de iteradores se les aplican algunas restricciones adicionalesG
.e trata de un error en tiempo de compilaci-n si una instrucci-n return aparece en un blo?ue de iteradores
Opero se permiten instrucciones yield returnR.
.e trata de un error en tiempo de compilaci-n si un blo?ue de iteradores contiene contexto no seguro
O[18.1R. 7n blo?ue de iteradores siempre de0ine un contexto seguro incluso si su declaraci-n est( anidada en
un contexto ?ue no lo es.
-.2.1 6istas de instrucciones
7na lista de instr!cciones est( 0ormada por una o varias instrucciones escritas secuencialmente. 8as listas de
instrucciones aparecen en blo?ues O-loc3sR O[8.2R y en blo?ues de modi0icadores Oswitch--loc3sR O[8.*.2R.
state%ent-list1
state%ent
state%ent-list state%ent
2#2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
Cuando se e$ecuta una lista de instrucciones, se trans0iere el control a la primera instrucci-n. Cuando el control
alcan1a el punto 0inal de una instrucci-n, se trans0iere a la siguiente instrucci-n. Cuando el control alcan1a el
punto 0inal de la Hltima instrucci-n, se trans0iere al punto 0inal de la lista de instrucciones.
7na instrucci-n ?ue 0orma parte de una lista de instrucciones es alcan1able si se cumple al menos una de las
siguientes condicionesG
Es la primera instrucci-n y la propia lista de instrucciones es alcan1able.
El punto 0inal de la instrucci-n anterior es alcan1able.
8a instrucci-n es una instrucci-n con eti?ueta y la eti?ueta es re0erenciada por una instrucci-n goto
alcan1able.
El punto 0inal de una lista de instrucciones es alcan1able si el punto 0inal de la Hltima instrucci-n de la lista es
alcan1able.
-.3 Instruccin ac2a
7na instrucci-n vac5a Oe%pt#-state%entR no =ace nada.
e%pt#-state%ent1
;
7na instrucci-n vac5a se utili1a cuando no =ay operaciones ?ue reali1ar en un contexto donde se re?uiere una
instrucci-n.
Cuando se e$ecuta una instrucci-n vac5a, simplemente se trans0iere el control al punto 0inal de la instrucci-n. 'or
lo tanto, el punto 0inal de una instrucci-n vac5a es alcan1able si la instrucci-n vac5a es alcan1able.
'uede utili1ar una instrucci-n vac5a cuando escriba una instrucci-n ,"ile sin cuerpoG
bool *rocessMessage() {...
void *rocessMessages() {
,"ile (*rocessMessage())
;
!
Tambi)n puede utili1arla para declarar una eti?ueta $usto antes de la llave de cierre P!Q de un blo?ueG
void V() {
...
i- (done) goto e#it;
...
e#it/ ;
!
-.! Instrucciones con eti;ueta
7na instrucci-n con eti?ueta Ola-eled-state%entR permite agregar una eti?ueta por delante de una instrucci-n.
8as instrucciones con eti?ueta se pueden incluir en blo?ues, pero no est(n permitidas como instrucciones
incrustadas.
la-eled-state%ent1
identifier / state%ent
7na instrucci-n con eti?ueta declara una eti?ueta con el nombre especi0icado en el identi0icador OidentifierR. El
(mbito de una eti?ueta es el blo?ue entero en el cual se declara, incluyendo los blo?ues anidados. .e produce un
error en tiempo de compilaci-n cuando se de0inen dos eti?uetas con el mismo nombre para ?ue sus (mbitos se
solapen.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2#3
Especificacin del lenguaje C#
.e puede =acer re0erencia a una eti?ueta desde instrucciones goto O[8.+.3R dentro del (mbito de la eti?ueta.
Esto signi0ica ?ue las instrucciones goto pueden trans0erir el control dentro y 0uera de los blo?ues, pero nunca
en los blo?ues.
8as eti?uetas tienen su propio espacio de declaraci-n y no inter0ieren con otros identi0icadores. El e$emplo
int V(int #) {
i- (# E+ 3) goto #;
# + =#;
#/ return #;
!
es un e$emplo v(lido ?ue utili1a el nombre # como par(metro y como eti?ueta.
7na instrucci-n con eti?ueta se e$ecuta tal y como se e$ecute la instrucci-n ?ue sigue a la eti?ueta.
&dem(s de la capacidad de alcance ?ue proporciona el 0lu$o normal de control, una instrucci-n con eti?ueta es
alcan1able si una instrucci-n goto alcan1able =ace re0erencia a la eti?ueta. OExcepci-nG si una instrucci-n goto
se encuentra dentro de otra try ?ue incluye un blo?ue -inally, la instrucci-n con eti?ueta est( 0uera de try y
el extremo del blo?ue -inally no es alcan1able, entonces la instrucci-n con eti?ueta tampoco es alcan1able
desde esta instrucci-n gotoR.
-.# Instrucciones de declaracin
7na instrucci-n de declaraci-n Odeclaration-state%entR declara una variable o una constante local. 8as
instrucciones de declaraci-n se pueden incluir en blo?ues, pero no est(n permitidas como instrucciones
incrustadas.
declaration-state%ent1
local-varia-le-declaration ;
local-constant-declaration ;
-.#.1 /eclaraciones de ariables locales
7na declaraci-n de variable local Olocal-varia-le-declarationR declara una o varias variables locales.
local-varia-le-declaration1
local-varia-le-t#pe local-varia-le-declarators
local-varia-le-t#pe1
t#pe
var
local-varia-le-declarators1
local-varia-le-declarator
local-varia-le-declarators local-varia-le-declarator
local-varia-le-declarator1
identificador
identifier @ local-varia-le-initiali0er
local-varia-le-initiali0er1
e2pression
arra#-initiali0er
El tipo de variable local Olocal-varia-le-t#peR de una declaraci-n de variable local Olocal-varia-le-declarationR
especi0ica directamente el tipo de las variables introducidas por la declaraci-n, o indica con la palabra clave var
?ue el tipo se deber5a in0erir bas(ndose en un iniciali1ador. El tipo aparece seguido de una lista de declaradores
de variable local Olocal-varia-le-declaratorsR, cada una de las cuales incluye una nueva variable. 7n declarador
2## Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
de variable local Olocal-varia-le-declaratorR est( 0ormado por un identi0icador OidentifierR ?ue da nombre a la
variable, ?ue opcionalmente puede ir seguido del s5mbolo Oto6enR P+Q y de un iniciali1ador de variable local
Olocal-varia-le-initiali0erR ?ue establece el valor inicial de la variable.
Cuando el tipo de variable local Olocal-varia-le-t#peR se especi0ica como var y no =ay ningHn tipo con nombre
var en el (mbito, la declaraci-n es una declaraci,n de varia/le local con asignaci,n de tipo iplcita, cuyo
tipo se in0iere del tipo de la expresi-n de iniciali1ador asociada. 8as declaraciones de variable local con
asignaci-n de tipo impl5cita est(n su$etas a las siguientes restriccionesG
8a declaraci-n de variable local Olocal-varia-le-declarationR no puede incluir varios declaradores de
variable local Olocal-varia-le-declaratorsR.
El declarador de variable local Olocal-varia-le-declaratorR debe incluir un iniciali1ador de variable local
Olocal-varia-le-initiali0erR.
El iniciali1ador de variable local Olocal-varia-le-initiali0erR debe ser una expresi-n Oe2pressionR.
8a expresi-n Oe2pressionR del iniciali1ador debe tener un tipo en tiempo de compilaci-n.
8a expresi-n Oe2pressionR del iniciali1ador no puede =acer re0erencia a la variable declarada en s5
& continuaci-n, se muestran e$emplos de declaraciones de variable local con asignaci-n de tipo impl5citaG
var #; .. )rror no initiali?er to in-er ty&e -rom
var y + {2 8 9!; .. )rror array initiali?er not &ermitted
var ? + null; .. )rror null does not "ave a ty&e
var u + # +E # < 2; .. )rror anonymous -unctions do not "ave a ty&e
var v + v<<; .. )rror initiali?er cannot re-er to variable itsel-
'ara obtener el valor de una variable local en una expresi-n se utili1a un nombre simple Osi%ple-na%eR O[*..2R
y, para modi0icarlo, se reali1a una asignaci-n Oassi&n%entR O[*.1#R. 7na variable local debe estar asignada
de0initivamente O[.3R en cada ubicaci-n donde se obtenga su valor.
El (mbito de una variable local declarada en una declaraci-n de variable local Olocal-varia-le-declarationR es el
blo?ue donde se produce la declaraci-n. .upone un error =acer re0erencia a una variable local en una posici-n
textual ?ue precede al declarador de la variable local Olocal-varia-le-declaratorR. 2entro del (mbito de una
variable local, supone un error en tiempo de compilaci-n declarar otra variable o constante local con el mismo
nombre.
7na declaraci-n de variable local ?ue declara varias variables e?uivale a varias declaraciones de una sola
variable con el mismo tipo. 7n iniciali1ador de variable Ovaria-le-initiali0erR en una declaraci-n de variable
local es en realidad una instrucci-n de asignaci-n ?ue se inserta inmediatamente despu)s de la declaraci-n.
El e$emplo
void V() {
int # + 2 y ? + # > 8;
!
es id)ntico a
void V() {
int #; # + 2;
int y;
int ?; ? + # > 8;
!
En una declaraci-n de variable local con asignaci-n de tipo impl5cita, se toma el tipo de la variable local ?ue se
declara para ?ue sea el mismo tipo de la expresi-n utili1ada para iniciali1ar la variable. 'or e$emploG
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2#!
Especificacin del lenguaje C#
var i + K;
var s + "Hello";
var d + 2.3;
var numbers + ne, int45 {2 8 9!;
var orders + ne, 6ictionaryDint%rderE();
8as declaraciones de variable local con asignaci-n de tipo impl5cita de arriba son precisamente e?uivalentes a
las siguientes declaraciones con asignaci-n de tipo expl5citaG
int i + K;
string s + "Hello";
double d + 2.3;
int45 numbers + ne, int45 {2 8 9!;
6ictionaryDint%rderE orders + ne, 6ictionaryDint%rderE();
-.#.2 /eclaraciones de constantes locales
7na declaraci-n de constante local Olocal-varia-le-declaratorR declara una o varias constantes locales.
local-constant-declaration1
const t#pe constant-declarators
constant-declarators1
constant-declarator
constant-declarators constant-declarator
constant-declarator1
identifier @ constant-e2pression
El tipo Ot#peR de una declaraci-n de constante local Olocal-constant-declarationR especi0ica el tipo de las
constantes ?ue se incluyen en la declaraci-n. El tipo viene seguido de una lista de declaradores de constante
Oconstant-declaratorsR, cada uno de los cuales incluye una nueva constante. 7n declarador de constante
Oconstant-declaratorR consta de un identi0icador OidentifierR ?ue da nombre a la constante, seguido del s5mbolo
Oto6enR P+Q y de una expresi-n constante Oconstant-e2pressionR O[*.18R ?ue establece el valor de la constante.
El tipo Ot#peR y la e2presi/n constante Oconstant-e2pressionR de una declaraci-n de constante local deben seguir
las reglas de declaraci-n de miembros de constantes O[1".4R.
'ara obtener el valor de una constante local en una expresi-n, se utili1a el no%-re si%ple Osi%ple-na%eR
O[*..2R.
El (mbito de una constante local es el blo?ue donde se produce la declaraci-n. Es un error =acer re0erencia a una
constante local en una posici-n textual anterior a su declarador de constante Oconstant-declaratorR. 2entro del
(mbito de una constante local, supone un error en tiempo de compilaci-n declarar otra variable o constante local
con el mismo nombre.
7na declaraci-n de constante local ?ue declara varias constantes e?uivale a varias declaraciones de una sola
constante con el mismo tipo.
-.$ Instrucciones de e"presiones
7na instrucci-n de expresi-n Oe2pression-state%entR evalHa una expresi-n determinada. El valor calculado por
la expresi-n, en el caso de =aber alguno, se descarta.
e2pression-state%ent1
state%ent-e2pression ;
2#6 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
state%ent-e2pression1
invocation-e2pression
o->ect-creation-e2pression
assi&n%ent
post-incre%ent-e2pression
post-decre%ent-e2pression
pre-incre%ent-e2pression
pre-decre%ent-e2pression
4o todas las expresiones pueden ser instrcciones. En concreto, expresiones como # < y y # ++ 2, ?ue
simplemente calculan un valor Oel cual ser( descartadoR, no se admiten como instrucciones.
8a e$ecuci-n de una instrucci-n de expresi-n Oe2pression-state%entR evalHa la expresi-n ?ue contiene y despu)s
trans0iere el control al punto 0inal de la instrucci-n de expresi-n. 'or lo tanto, el punto 0inal de una instrucci-n
de expresi-n Oe2pression-state%enR es alcan1able si dic=a instrucci-n tambi)n lo es.
-.+ Instrucciones de seleccin
8as instrucciones de selecci-n Oselection-state%entR seleccionan una de las instrucciones ?ue se van a e$ecutar
en 0unci-n del valor de alguna expresi-n.
selection-state%ent1
if-state%ent
switch-state%ent
-.+.1 Instruccin If
8a instrucci-n i- selecciona una instrucci-n ?ue se va a e$ecutar bas(ndose en el valor de una expresi-n
booleana.
if-state%ent1
i- ( -oolean-e2pression ) e%-edded-state%ent
i- ( -oolean-e2pression ) e%-edded-state%ent else e%-edded-state%ent
8a secci-n else se asocia a la instrucci-n i- anterior m(s cercana permitida por la sintaxis. 'or lo tanto, una
instrucci-n i- con la estructura
i- (#) i- (y) V(); else S();
e?uivale a
i- (#) {
i- (y) {
V();
!
else {
S();
!
!
7na instrucci-n i- se e$ecuta de la siguiente 0ormaG
.e evalHa la e2presi/n -ooleana O-oolean-e2pressionR O[*.1+R.
.i la expresi-n booleana devuelve true, el control se trans0iere a la primera instrucci-n incrustada. Cuando
el control alcan1a el punto 0inal de dic=a instrucci-n, se trans0iere al punto 0inal de la instrucci-n i-.
.i la expresi-n booleana devuelve -alse y existe una secci-n else, el control se trans0iere a la segunda
instrucci-n incrustada. Cuando el control alcan1a el punto 0inal de dic=a instrucci-n, se trans0iere al punto
0inal de la instrucci-n i-.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2#(
Especificacin del lenguaje C#
.i la expresi-n booleana devuelve -alse y no existe una secci-n else, el control se trans0iere al punto
0inal de la instrucci-n i-.
8a primera instrucci-n incrustada de una instrucci-n i- es alcan1able si la instrucci-n i- es alcan1able y la
expresi-n booleana no tiene el valor constante -alse.
8a segunda instrucci-n incrustada de una instrucci-n i-, si existe, es alcan1able si la instrucci-n i- es
alcan1able y la expresi-n booleana no tiene el valor constante true.
El punto 0inal de una instrucci-n i- es alcan1able si el punto 0inal de al menos una de sus instrucciones
incrustadas es alcan1able. &dem(s, el punto 0inal de una instrucci-n i- ?ue no tiene secci-n else es alcan1able
si la instrucci-n i- es alcan1able y la expresi-n booleana no tiene el valor constante true.
-.+.2 Instruccin 4@itc?
8a instrucci-n s9itc= Oswitch-state%entR selecciona una lista de instrucciones ?ue se van a e$ecutar ?ue tengan
asociada una eti?ueta s9itc= Oswitch-la-elR ?ue se corresponda con el valor de la expresi-n s9itc=.
switch-state%ent1
s,itc" ( e2pression ) switch--loc3
switch--loc31
{ switch-sections
opt
!
switch-sections1
switch-section
switch-sections switch-section
switch-section1
switch-la-els state%ent-list
switch-la-els1
switch-la-el
switch-la-els switch-la-el
switch-la-el1
case constant-e2pression /
de-ault /
7na instrucci-n s9itc= Oswitch-state%entR est( 0ormada por la palabra clave s,itc", seguida de una expresi-n
entre par)ntesis Odenominada expresi-n s9itc=R y de un blo?ue s9itc= Oswitch--loc3R. El blo?ue s9itc= consiste
en varias o ninguna secciones de s9itc= Oswitch-sectionsR, encerradas entre llaves. Cada secci/n de switch
Oswitch-sectionR est( 0ormada por una o varias eti?uetas de s9itc= Oswitch-la-elsR seguidas de una lista de
instrucciones Ostate%ent-listR O[8.2.1R.
El tipo aplica/le en una instrucci-n s,itc" est( establecido por la expresi-n s9itc=.
.i el tipo de la expresi-n s9itc= es sbyte, byte, s"ort, us"ort, int, uint, long, ulong, bool, c"ar,
string o un tipo enum Oen%-t#peR, o si es el tipo ?ue acepta valores null correspondiente a uno de estos
tipos, entonces es el tipo aplicable de la instrucci-n s,itc".
En caso contrario, debe existir una conversi-n impl5cita de0inida por el usuario O[#.4R del tipo de la
expresi-n s9itc= a uno de los posibles tipos aplicablesG sbyte, byte, s"ort, us"ort, int, uint, long,
ulong, c"ar, string o un tipo ?ue acepta valores null correspondiente a uno de esos tipos.
2e lo contrario, si no existe tal conversi-n impl5cita o existe m(s de una, se producir( un error en tiempo de
compilaci-n.
2#$ Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a expresi-n constante de cada eti?ueta case debe denotar un valor de tipo convertible impl5citamente O[#.1R al
tipo aplicable en la instrucci-n s,itc". .i dos o m(s eti?uetas case de la misma instrucci-n s,itc"
especi0ican el mismo valor constante, se producir( un error en tiempo de compilaci-n.
'uede existir como m(ximo una eti?ueta de-ault en una instrucci-n s9itc=.
7na instrucci-n s,itc" se e$ecuta de la siguiente 0ormaG
.e evalHa la expresi-n s9itc= y se convierte en el tipo aplicable.
.i una de las constantes especi0icadas en una eti?ueta case de una instrucci-n s,itc" es igual al valor de
la expresi-n s9itc=, el control se trans0iere a la lista de instrucciones ?ue est(n a continuaci-n de dic=a
eti?ueta case.
.i ninguna de las constantes especi0icadas en las eti?uetas case de una instrucci-n s,itc" es igual al valor
de la expresi-n s9itc= y existe una eti?ueta de-ault, el control se trans0iere a la lista de instrucciones ?ue
aparece a continuaci-n de la eti?ueta de-ault.
.i ninguna de las constantes especi0icadas en las eti?uetas case de una instrucci-n s,itc" es igual al valor
de la expresi-n s9itc= y no existe una eti?ueta de-ault, el control se trans0iere al punto 0inal de la
instrucci-n s,itc".
.i el punto 0inal de la lista de instrucciones de una secci-n de s9itc= es alcan1able, se producir( un error en
tiempo de compilaci-n. Esto se conoce como regla Psin paso expl5citoQ. El e$emplo
s,itc" (i) {
case 3/
CasePero();
brea(;
case 2/
Case%ne();
brea(;
de-ault/
Case%t"ers();
brea(;
!
es v(lido por?ue ninguna secci-n de s9itc= tiene un punto 0inal alcan1able. & di0erencia de C y CSS, la
e$ecuci-n de una secci-n s9itc= no permite el Ppaso expl5citoQ a la siguiente secci-n de s9itc=, y el e$emplo
s,itc" (i) {
case 3/
CasePero();
case 2/
CasePero%r%ne();
de-ault/
Case'ny();
!
da como resultado un error en tiempo de compilaci-n. 'ara e$ecutar una secci-n de s9itc= despu)s de la
e$ecuci-n de otra secci-n de s9itc=, debe utili1ar una instrucci-n goto case o goto de-ault expl5citaG
s,itc" (i) {
case 3/
CasePero();
goto case 2;
case 2/
CasePero%r%ne();
goto de-ault;
de-ault/
Case'ny();
brea(;
!
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2#"
Especificacin del lenguaje C#
7na secci-n s9itc= Oswitch-sectionR admite varias eti?uetas. El e$emplo
s,itc" (i) {
case 3/
CasePero();
brea(;
case 2/
Case%ne();
brea(;
case 8/
de-ault/
Case1,o();
brea(;
!
es v(lido. El e$emplo no in0ringe la regla Psin paso expl5citoQ por?ue las eti?uetas case 8/ y de-ault/
0orman parte de la misma secci-n de s9itc= Oswitch-sectionR.
8a regla Psin paso expl5citoQ evita una clase de errores comunes ?ue se producen en C y CSS cuando se omiten
involuntariamente instrucciones brea(. &dem(s, gracias a esta regla, las secciones de s9itc= de una instrucci-n
s,itc" se pueden reorgani1ar arbitrariamente sin a0ectar al comportamiento de la instrucci-n. 'or e$emplo, las
secciones de la instrucci-n s,itc" anterior se pueden colocar en orden inverso sin modi0icar el
comportamiento de la instrucci-nG
s,itc" (i) {
de-ault/
Case'ny();
brea(;
case 2/
CasePero%r%ne();
goto de-ault;
case 3/
CasePero();
goto case 2;
!
8a lista de instrucciones de una secci-n de s9itc= termina normalmente con una instrucci-n brea(, goto case
o goto de-ault, pero tambi)n se admite cual?uier sintaxis ?ue represente el punto 0inal de la lista de
instrucciones en inalcan1able. 'or e$emplo, una instrucci-n ,"ile controlada mediante la expresi-n booleana
true nunca alcan1ar( su punto 0inal. !gualmente, una instrucci-n t"ro, o return siempre trans0iere el control
a otra parte y nunca alcan1a su punto 0inal. 'or tanto, el siguiente e$emplo es correctoG
s,itc" (i) {
case 3/
,"ile (true) V();
case 2/
t"ro, ne, 'rgument)#ce&tion();
case 8/
return;
!
2!' Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
El tipo aplicable en una instrucci-n s,itc" puede ser el tipo string. 'or e$emploG
void 6oCommand(string command) {
s,itc" (command.1oLo,er()) {
case "run"/
6oOun();
brea(;
case "save"/
6oSave();
brea(;
case "Quit"/
6o^uit();
brea(;
de-ault/
$nvalidCommand(command);
brea(;
!
!
2e la misma 0orma ?ue los operadores de igualdad O[*.+.*R, la instrucci-n s,itc" distingue mayHsculas de
minHsculas y e$ecutar( una determinada secci-n s-lo si la cadena de expresi-n s9itc= coincide exactamente con
una constante de eti?ueta case.
Cuando el tipo aplicable en una instrucci-n s,itc" es string, se admite el valor null como constante de
eti?ueta case.
8as listas de instrucciones Ostate%ent-listsR de blo?ue s9itc= Oswitch--loc3R pueden contener instrucciones de
declaraci-n O[8.R. El (mbito de una variable o constante local declarada en un blo?ue s9itc= es el propio
blo?ue.
2entro de un blo?ue s9itc=, el signi0icado de un nombre utili1ado en un contexto de expresi-n siempre debe ser
el mismo O[*..2.1R.
8a lista de instrucciones de una secci-n de s9itc= determinada es alcan1able si la instrucci-n s,itc" es
alcan1able y se cumple al menos una de las condiciones siguientesG
8a expresi-n s9itc= no es un valor constante.
8a expresi-n s9itc= es un valor de constante ?ue coincide con una eti?ueta case de la secci-n de s9itc=.
8a expresi-n s9itc= es un valor de constante ?ue no coincide con ninguna eti?ueta case y la secci-n de
s9itc= contiene la eti?ueta de-ault.
7na instrucci-n goto case o goto de-ault alcan1able =ace re0erencia a una eti?ueta s9itc= de la
secci-n.
El punto 0inal de una instrucci-n s,itc" es alcan1able si se cumple al menos una de las siguientes condicionesG
8a instrucci-n s,itc" contiene una instrucci-n brea( alcan1able ?ue provoca la salida de la instrucci-n
s,itc".
8a instrucci-n s,itc" es alcan1able, la expresi-n s9itc= no es un valor constante y no existe eti?ueta
de-ault.
8a instrucci-n s,itc" es alcan1able, la expresi-n s9itc= es una constante ?ue no coincide con ninguna
eti?ueta case y no existe eti?ueta de-ault.
Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos. 2!1
Especificacin del lenguaje C#
-.- Instrucciones de iteracin
8as instrucciones de iteraci-n Oiteration-state%entR e$ecutan repetidas veces una instrucci-n incrustada.
iteration-state%ent1
while-state%ent
do-state%ent
for-state%ent
foreach-state%ent
-.-.1 Instruccin B?ile
8a instrucci-n ,"ile e$ecuta una instrucci-n incrustada cero o varias veces dependiendo de una condici-n.
while-state%ent1
,"ile ( -oolean-e2pression ) e%-edded-state%ent
7na instrucci-n ,"ile se e$ecuta de la siguiente 0ormaG
.e evalHa la e2presi/n -ooleana O-oolean-e2pressionR O[*.1+R.
.i la expresi-n booleana devuelve true, el control se trans0iere a la instrucci-n incrustada. Cuando el
control alcan1a el punto 0inal de la instrucci-n incrustada Oposiblemente desde la e$ecuci-n de una
instrucci-n continueR, se trans0iere al inicio de la instrucci-n ,"ile.
.i la expresi-n booleana devuelve -alse, el control se trans0iere al punto 0inal de la instrucci-n ,"ile.
2entro de la instrucci-n incrustada de la instrucci-n ,"ile, puede utili1ar una instrucci-n brea( O[8.+.1R para
trans0erir el control al punto 0inal de la instrucci-n ,"ile Oterminando as5 la iteraci-n de la instrucci-n
incrustadaR, y una instrucci-n continue O[8.+.2R para trans0erir el control al punto 0inal de la instrucci-n
incrustada Ode esta 0orma se reali1ar( otra iteraci-n de la instrucci-n ,"ileR.
8a instrucci-n incrustada de una instrucci-n ,"ile es alcan1able si la instrucci-n ,"ile es alcan1able y la
expresi-n booleana no tiene el valor constante -alse.
El punto 0inal de una instrucci-n ,"ile es alcan1able si se cumple al menos una de las siguientes condicionesG
8a instrucci-n ,"ile contiene una instrucci-n brea( alcan1able ?ue provoca la salida de la instrucci-n
,"ile.
8a instrucci-n ,"ile es alcan1able y la expresi-n booleana no tiene el valor constante true.
-.-.2 Instruccin /o
8a instrucci-n do e$ecuta una instrucci-n incrustada una o varias veces dependiendo de una condici-n.
do-state%ent1
do e%-edded-state%ent ,"ile ( -oolean-e2pression ) ;
7na instrucci-n do se e$ecuta de la siguiente 0ormaG
El control se trans0iere a la instrucci-n incrustada.
Cuando el control alcan1a el punto 0inal de la instrucci-n incrustada Oposiblemente desde la e$ecuci-n de
una instrucci-n continueR, se evalHa la expresi-n booleana O-oolean-e2pressionR O[*.1+R. .i la expresi-n
booleana devuelve true, el control se trans0iere al inicio de la instrucci-n do. En caso contrario, el control
se trans0iere al punto 0inal de la instrucci-n do.
2entro de la instrucci-n incrustada de la instrucci-n do, puede utili1ar una instrucci-n brea( O[8.+.1R para
trans0erir el control al punto 0inal de la instrucci-n do Oterminando as5 la iteraci-n de la instrucci-n incrustadaR,
y una instrucci-n continue O[8.+.2R para trans0erir el control al punto 0inal de la instrucci-n incrustada.
2!2 Copyright Microsoft Corporation 1999-2008. Reservados todos los derechos.
Cap0tulo 1' Clases
8a instrucci-n incrustada de una instrucci-n do es alcan1able si la instrucci-n do es alcan1able.
El punto 0inal de una instrucci-n es alcan1able si se cumple al menos una de las siguientes condicionesG
8a instrucci-n do contiene una instrucci-n brea( alcan1able ?ue provoca la salida de la instrucci-n do.
El punto 0inal de la instrucci-n incrustada es alcan1able y la expresi-n booleana no tiene el valor
constante true.
-.-.3 Instruccin 7or
8a instrucci-n -or evalHa primero una secuencia de expresiones de iniciali1aci-n y, mientras se cumpla una
determinada condici-n, e$ecuta repetidas veces una instrucci-n incrustada y evalHa una secuencia de expresiones
de iteraci-n.
for-state%ent1
-or ( for-initiali0er
opt
; for-condition
opt
; for-iterator
opt
) e%-edded-state%ent
for-initiali0er1
local-varia-le-declaration
state%ent-e2pression-list