Professional Documents
Culture Documents
Diego G. Ruz
Es ingeniero en Sistemas de Informacin, egresado de la Univer
sidad Tecnolgica Nacional Argentina. Su inters por la progra
macin comenz a los 10 aos de edad, cuando tuvo en sus ma
nos su primera computadora, la Commodore 64. A partir de
aquel momento, inici una carrera que lo llevara de computado
ra en computadora y de un lenguaje de programacin a otro.
Actualmente se desempea como programador lder en el depar
tamento de sistemas de la empresa Bioscience, dedicado a la cons
truccin de software para la adquisicin, visualizacin y anlisis
de seales biolgicas. Dicta clases de programacin de videojue
gos en el instituto Image Campus y es colaborador de la revista de
programacin users.code en el rea multimedia. Es, adems, au
tor del libro C++ Programacin orientada a objetos.
D edicatoria
A mi compaera de vida, Ana, quien a pesar de mis defectos, per
manece a mi lado.
A g ra d e cim ien to s
A mi familia, a la que agradezco profundamente su contencin y
afecto.
2 ^ SOBRE LA EDITORIAL
MP Ediciones S.A. es una editorial especializada en temas de tecnologa
(computacin, IT, telecomunicaciones).
Entre nuestros productos encontrar: revistas, libros, fascculos, sitios en Internet y eventos.
Nuestras principales marcas son: USERS, Aprendiendo PC, Dr. Max y TecTimes.
u M .c o d e
Prlogo
PRLOGO
Desde que Microsoft present al mundo su nueva plataforma estratgica de desa
rrollo, .NET, sta no ha parado de crecer y extenderse. Hoy en da, forma parte
de una de las tecnologas ms importantes que un programador debera conocer.
En este libro aprender a programar en C#, el lenguaje ms importante de la platafor
ma .NET, el cual le permitir explotar al mximo sus capacidades.
El lenguaje fue diseado para crear sistemas en el mundo actual, donde la necesidad
de comunicarse con otras aplicaciones y servicios por una red de informacin -co
mo Internet- es moneda corriente, donde conviven bases de datos de distintos fabri
cantes, donde los sistemas son construidos a partir de componentes locales o remo
tos, donde se requieren soluciones integrales para diversos tipos de plataformas.
Con C# podremos crear sistemas de una gran diversidad, simples o complejos,
aplicacior.es de consola, de escritorio o para la Web, para computadoras persona
les o para dispositivos mviles, etc. Tambin ofrece una excelente puerta de en
trada a quienes deseen iniciarse en la programacin orientada a objetos, ya que es
fuerte en los aspectos ms importantes del paradigma y simplifica las tareas me
nos agradables que suelen convivir con otros lenguajes ms antiguos.
Este libro ofrece una introduccin en los aspectos ms importantes del lenguaje
C# y la plataforma .NET. Pretende ser ideal para el principiante, para el no tan
principiante y para los programadores que provengan de otros lenguajes, atrados
por esta grande y maravillosa plataforma de desarrollo. Espero que el lector dis
frute tanto su lectura como yo disfrut en escribirlo.
u s r .c o d e
PROGRAMACIN C#
EL LIBRO DE UN VISTAZO
En la prim era parte de este m anual, d esarro llarem o s los conceptos
fu ndam entales y las caractersticas particulares que hacen a este len
guaje, para luego introducirnos de lleno en la program acin de aplica
ciones de escritorio y para la Web.
DELEGADOS Y EVENTOS
Los delegados y los eventos son elementos
muy utilizados en la programacin Windows.
CLASES Y OBJETOS
ENCAPSULAMIENTO, HERENCIA Y
POLIMORFISMO
Captulo 5
Captulo 9
COLECCIONES
MANEJO DE EXCEPCIONES
u s r .c o d e
El libro de un vistazo
: Captulo 13
mximo provecho de l.
: Captulo 10
CARACTERISTICAS AVANZADAS
DEL LENGUAJE
SU
DOCUMENTACIN DE CDIGO
importante tarea.
Captulo 11
SERVICIOS WEB
Apndice C
tulo 12
UML
SOCKETS
orientada a objetos.
INFORMACIN COMPLEMENTARIA
A lo largo de este manual encontrar una serie de recuadros que le brindarn informacin com
u s r .c o d e
W E B J E C J |.M E S': C ;p M
S ?
e.
sus conocimientos.
DE 0NWEE-.
0 N W E I . I E C 1 I M E S . C O M
Contenido
CONTENIDO
Espacios de nombres
36
La sentencia using
37
Sobre et autor
Prlogo
El libro de un vistazo
Los comentarios
38
Informacin complementaria
Las variables
39
Introduccin
14
40
Ejemplos de identificadores
40
Convenciones de nombramiento
41
EL LENGUAJE C#
42
Y LA PLATAFORMA .NET
47
16
Constantes
48
.NET
19
50
19
Operadores
Elframevvork.NET
E J E i B E
Eipttcadoncwwr.t tefl*uaet
(CIR/
53
55
Sentencias condicionales
55
Sentencia de bucle
66
VtaMl
.1
fWMMlk.Nn
WMwt
El lenguaje C#
20
Caractersticas fundamentales
del lenguaje
21
21
C# contra C++
22
CU contra Java
23
Resumen
El entorno de desarrollo
Visual Studio .NET
24
79
Actividades
28
Captulo 3
Resumen
33
CLASES Y OBJETOS
Actividades
34
Qu es una clase
82
82
conVisualStudio.NET
36
Modificadores de acceso
84
Instanciacin
86
PROGRAMACION C*
Variables estticas
Mtodos virtuales
145
Los mtodos
Interfaces
153
Clases abstractas
154
I[
Resumen
155
Actividades
156
1JO
^ identificador j
COLECCIONES
Arrays
158
164
166
169
171
Recorriendo arrays
172
El modificador params
172
Arrays multidimensionales
173
Inicializacin de un array
de dos dimensiones
176
Arrays de arrays
176
Indexadores
179
109
Resumen
111
Actividades
112
184
Colecciones
185
lEnumerable y lEnumerator
m t e if a j
innumerable
185
ntertar- lEnumerator
ENCAPSULAMIENTO, HERENCIA
Y POLIMORFISMO
Herencia
Uso de los modificadores de acceso
Las propiedades
j CloscEnumcrabie 1
114
*-----1'etlriumeratorf,
1 ClaseEmimeraooi
Cuf<ent
+MoveUat!;
Resety
----------- O
122
123
Invocar constructores
128
ICollection
188
Invocar destructores
132
IComparable
189
Composicin
133
135
Polimorfismo
137
IList
Diccionarios
El diccionario Hashtable
189
19G
191
Sobrecarga de mtodos
137
Resumen
193
Sobrecarga de operadores
141
Actividades
194
Contenido
Convencin de nombramiento
DELEGADOS Y EVENTOS
para controles
Delegados
232
196
Qu es un delegado?
199
bsicos
201
Caso de estudio 1
201
Caso de estudio 2
239
204
Caso de estudio 3
241
Caso de estudio 4
246
Eventos
Invocar mltiples mtodos
234
234
25G
Caso de estudio 5
Resumen
253
Actividades
254
256
File
void Ktodo2
i
tiro t u * Bxeeptiool*
256
Tipos de streams
256
257
260
Bases de datos
263
SQL
265
La clase System.Timers.Timer
207
Caso de estudio
208
266
------ ]r ---.NETDataProvidct
DUAdJpt-':
| Comando5E1ECT |
Resolucin
209
Coiwctioa
| j | ComandoINSERI j
Resumen
213
Comrnar.d
j ! | Coma* UMWl |
Actividades
214
DataRcadr
1 j CcmanooDEtfTE j
L _ -------- J i
iL
216
221
Un ejemplo sencillo
269
279
Controles
222
Formularios
227
Resumen
281
229
Actividades
281
PROGRAMACION C*
Atributos predefinidos
MANEJO DE EXCEPCIONES
305
Tratamiento de errores
284
286
Clases de excepciones
287
Generar excepciones
294
de ejecucin
Reflection
306
307
308
311
Punteros
312
Resumen
315
Actividades
316
W ix * un
i /
r f :
i
>
kr,:
SERVICIOS WEB
J j .
- V ...
J/t* CUMtill
' IwwdruMonay.
,
318
318
KiioaoiUnJi
296
Resumen
297
Actividades
298
s.
Captulo 1$
327
CARACTERISTICAS AVANZADAS
Resumen
331
DEL LENGUAJE
Actividades
332
Boxing/Unboxing
300
Atributos
301
SOCKETS
Qu es un socket?
334
334
334
335
La clase Socket
335
Resumen
341
Actividades
342
Introduccin
LA NOTACIN HNGARA
INTRODUCCION
La convencin
370
344
Un tipo base
370
344
Un prefijo
370
345
Un calificador
37!
371
A MNAGED DIRECTX
Managed DirectX
Qu necesitamos?
El sistema de coordenadas 3D
Antes de empezar
346
Algunos ejemplos
Inicializar Direct3D
347
Ventajas y desventajas
372
de la convencin
UML
374
Introduccin
374
356
Dibujar objetos
Diagramas de clases
375
Diagramas de objetos
375
Diagramas de secuencia
376
El mtodo ProcsVerts
de la clase Renderer
359
Ejecutar la aplicacin
360
Resumen
361
Actividades
362
* de la e l* *
rbeouewCoiiun vi
peticin! 10
pMitn y - C
* I
rtiacior-di*
, |* " * -c o m p o n
'Apndice A
i
tutC-1: T tilu j
DOCUMENTACION DE CDIGO
nombre M vtOl.brfi
U h k - 12?
364
i w v W t .............. - prcpietok-
367
........
368
r#
tix&sszffCMM
Diagramas de estados
377
Diagramas de colaboracin
378
Diagramas de actividad
379
Diagramas de componentes
380
Extensiones a UML
381
Servicios al lector
Lenguajes .NET
382
ndice temtico
385
PROGRAMACIN C *
INTRODUCCIN
Este libro se encuentra dirigido, principalmente, al programador novato y de nivel
medio, as como al estudiante o al aficionado autodidacto.
Quienes estn dando sus primeros pasos en el mundo de la programacin no po
drn dejar de sumergirse en los primeros dos captulos, donde se realiza una intro
duccin a la plataforma .N ET y a la sintaxis bsica del lenguaje. Tambin ambos re
sultarn muy tiles para quienes provengan de otros lenguajes de programacin, ya
que se evidencian las diferencias sustanciales que stos poseen respecto a C .
Si acaso a usted le atrae la programacin orientada a objetos y desea conocer sus
conceptos fundamentales y cmo C# la soporta, los captulos 3 y 4 le sern de gran
utilidad.
Si, en cambio, desea crear aplicaciones de escritorio, no puede dejar de visitar el ca
ptulo 7, donde veremos cmo generar este tipo de programas haciendo uso de la
gran diversidad de controles que la plataforma .N ET nos ofrece. Pero claro, ningu
na aplicacin es demasiado til si no puede interactuar con datos externos. En el
captulo 8 veremos de qu trata AD O .NET y cmo nos facilita la tarea de trabajar
con diversas fuentes de datos.
Y esto no termina aqu! C# y la plataforma .NET son tan verstiles, que nos per
mitirn publicar los servicios de una aplicacin en una red de un modo muy senci
llo. En el captulo 11 veremos cmo generar servicios web, y en el captulo 12
aprenderemos a crear aplicaciones de red utilizando sockets.
Desea crear aplicaciones grficas de alto desempeo? Acaso le interesa programar
juegos? Entonces la librera Managed DirectX ser una gran aliada en su misin, y
el captulo 13 ofrece una introduccin a sus principales caractersticas.
Y como si todo esto fuera poco, en los apndices encontrar cmo crear documenta
cin a partir del cdigo escrito en G?, de que trata la notacin de nombramiento Hn
gara, un listado de lenguajes .NET que podr encontrar en la Red -son ms de cin
cuenta!- y, por ltimo, una introduccin al lenguaje unificado de modelado (UMLj.
No es exagerado enunciar que C# y la plataforma .NET son el sueo de todo pro
gramador. Si acaso duda de mi palabra, qu espera para comprobarlo!
PROGRAMACIN C#
Captulo
El lenguaje C#
y la plataforma
.NET
En este p rim er captulo estudiarem os
qu nos ofrece este nuevo lenguaje
y por qu habra de interesarnos.
R ealizarem os una com paracin
con lenguajes sim ilares y analizarem os
cul es la arquitectura de la plataform a
sobre la que esta construido.
16
.NET
19
El framework .NET
El lenguaje CU
19
20
Caracterstica: fundamentales
del lenguaje
21
21
CS contra C++
22
CS contra Java
23
El entorno de desarrolle
Visual SturiiG .NET
24
2?
32
34
PROGRAMACIN C<
[Microsoft ioiimiation
--i-
nera bastante sencilla, y poseen la capacidad de fijar casi la totalidad de las pro
piedades necesarias en tiempo de diseo y con base en dos de los lenguajes ms
exitosos de todos los tiempos.
7/
rl ** vm* vtw paJc- Pjr.
C\i' j *
SKI-.
4?
y: 5 ~
H*
'Manr
W r X ,
J.! : *
i <K>er.i
H
_Co>**r
tl C I At>J * W5ke:
>
>Ino**./.. J
<1
r j:-i : r-
. r.* ;
J'-i*::!* fSU'xri: , .
Jjee'*
V
tu
vt-W.
, ;|1MN(*Jl.aI,Kfl*!*:
, KHL'.IH.T TI'H! IHClOi
> HKOJll WHEIHOtf!
.
,
,
,
,
,
HKMU11 f K.r:HOf
v k rwiv
Hfit'jlT $7'Hf
v r f .r 'ii^ .
HRt-iKT'.T<MWp'Cl
V livjl
uw/.
HflfSaT ST5METH0WA1
r.*ww<r
:*i\
i i *.-v
rv< ,1.:
fw*. i* . :
hHv . v .
''r.iifi riAjr
i
.
"
x. v .
* *' '
' M .
.* iir'.U V
t
i- . i "
:>nxJiM
.(TMftdfcwluflorlvrf/
.CflMMHfcMfaBrf
'f T
\>
Jn1.twjiwlh/lw
/
Figura i . El entorno ele programacin Borland C++ Buiider 6.0.
| 2 | ONWEB.TECTIMES.COM
En el sitio onweb.tectimes.com encontrar contenido adicional vinculado a los temas tratados en
este manual, incluyendo el cdigo fuente de los ejemplos que se desarrollarn en este libro, listo
bajar y probar, as como una completa guia de sitios web recomendados.
17
PROGRAMACIN C*
Pero no todo es color de rosa para estos entornos. Las aplicaciones son cada da ms
complejas y los programadores requieren, cada vez en mayor medida, un buen so
porte a la colaboracin entre componentes. Sera deseable poder emplear desde
Delphi una librera C++ ya existente, de una manera sencilla, sin tener que estar
utilizando herramientas de conversin.
En el caso de C++ Builder, hasta existen inconvenientes para acceder a libreras
creadas en Visual C++ debido a que utilizan formatos de libreras distintos (OM F
en el caso de C++ Builder y COFF en el caso de Visual C++), y esto es malo dado
que Visual C++ es el entorno ms popular (por lejos) para la creacin de libreras
para Windows, y muchsimos recursos que podemos encontrar en la Red fueron
creados con este entorno.
Si deseamos, por ejemplo, crear una aplicacin que utilice DirectX desde C++ Buil
der, tendremos que buscar en la Red las libreras .LIB correspondientes en formato
OM F (existe una herramienta provista por el entorno para la conversin de forma
to COFF a OMF, pero la importacin de libreras complejas, como lo es DirectX,
no es para nada trivial).
Finalmente, en los ltimos aos ha surgido una gran variedad de plataformas m
viles muy poderosas: PDAs, telfonos celulares, Tablet PCs, etc. Estos dispositivos
no son compatibles con binarios creados para microprocesadores Intel x86, ya que
poseen su propia familia de microprocesadores con su propio paquete de herra
mientas para la construccin de aplicaciones nativas.
Ni Delphi ni C++ Builder se encuentran presentes en otras plataformas ms all
de Windows (y Linux, si tomamos en consideracin a Kylix, que es un entorno
de desarrollo creado por Borland, muy similar a Delphi y a C++Builder). Visual
Basic y Visual C.++ se hallan en versiones especiales para algunos dispositivos m
viles, pero el subconjunto de funciones del API de Win32 que estn en dichos
dispositivos hace que la migracin de una aplicacin de una plataforma se con
vierta en una tarea bastante engorrosa.
BORLAND KYLIX
Kylix es un entorno de programacin para sistemas Linux muy similar a Delphi y a C++ Builder.
Con l es posible crear aplicaciones con ventanas y controles (botones, cuadros de texto, cuadros
de lista, etc.) y compilar en Windows y en Linux. Ms info: www.borland.com/kylix.
.NE7
.NET
.NET es un conjunto de tecnologas construidas a partir de una estrategia de M i
crosoft para la cual ha destinado gran parte de su presupuesto de investigacin. Es
ta estrategia surge: a su vez, del nuevo mapa de necesidades y requerimientos que
Microsoft advirti que se suscitaran en el futuro.
.NET son aplicaciones de servidor (SQL Server 2000, Exchange 2000, etc.), es un
entorno de desarrollo (Visual Studio .NET), son componentes clave que se integran
al sistema operativo, son servicios, y es, finalmente, una plataforma de desarrollo
denominada firamework .NET.
E! framework .NET
Es una infraestructura de desarrollo que est compuesta por diversos recursos, en
tre los cuales se destaca el ms importante, que es una mquina virtual conocida co
mo CLR ( Common
Language Runtime),
De este modo, nuestros programas ya no poseern cdigo nativo de ningn microprocesador en particular, sino instrucciones M SIL (Microsoft Intermedate Langua-
Language Specificeation).
El desarrollo del framework .NET no se detiene. Actualmente la versin 2.0 se encuentra en eta
pa beta. Es posible acceder a ms informacin acerca de esta nueva versin en el sitio oficial:
http://msdn.microsoft.com/netframework.
PROGRAMACIN CU
Es posible crear recursos en cualquiera de estos lenguajes que hagan uso de recur
sos escritos en otros; de hecho, es posible crear una clase en C# que herede de una
clase creada en Managed C++.
c#
C++
VB.NET |
JScript
Visual
Studio
.NET
Framework.NET
Windows
EL LENGUAJE C#
CJ es un lenguaje que cumple con la especificacin CLS. El cdigo que crearemos
con l ser traducido a instrucciones M SIL para entonces ser traducido, justo an
tes de su ejecucin, a instrucciones nativas que correspondan a la plataforma con
creta sobre la cual estemos trabajando.
Cabe destacar que el compilador J1T
El lenguaje C ti
Cada lenguaje posee sus caractersticas que lo tornan ideal para ciertos usos; ade
ms, presenta diversos grados de expresividad que pueden permitir implementar
el mismo algoritmo de maneras diversas, por lo que un modo puede resultar ms
eficiente que otro.
1 No confundir con el autor del lenguaje Pascal, que fue Niklaus Wirth. Anders Hejlsberg fue el
creador de un compilador llamado Turbo Pascar, que fue muy popular en sus tiempos por su
velocidad y bajo costo.
PROGRAMACIN CS
C# contra C++
Admito que C++ es mi lenguaje preferido; trabaj durante muchos aos con l c,
incluso, escrib un libro de C++ (C++ Programacin Orientada a Objetos, de esta
misma editorial), pero prob C# y fue como probar ambrosa.
En el enlace de referencia es posible encontrar una comparativa entre Visual Basic .NET y C# es
crita por Mario Flix Guerrero.
Enlace: www.microsoft.com/spanish/msdn/comunidad/mtj.net/voices/MTJ_2128.asp,
El lenguaje Cf?
C# contra Java
Muchos sostienen que C# es una copia de Java. Si tomamos ciertos trozos de cdi
go (convenientemente) escritos en alguno de estos lenguajes, podra ser imposible
determinar si es C# o es Java.
Lo cierto es que parte de la filosofa empleada por ambos lenguajes es la misma. Am
bos se ejecutan sobre una mquina virtual, y esta caracterstica los convierte en lengua
jes potencialmente multiplatabrma; ambos poseen especificaciones de subconjuntos
de recursos de lenguaje para implemenraciones en diversos dispositivos (por ejemplo,
mviles), y ambos tienen una librera de clases con muchas caractersticas en comn.
En el enlace de referencia podrn encontrar una breve comparativa entre estos lenguajes. Enla
ce: www.microsoft.com/spanish/MSDN/estudiantes/desarrollo/lenguajes/c-sharp.asp.
PROGRAMACIN Cfl
EL ENTORNO DE DESARROLLO
VISUAL STUDIO .NET
En el desarrollo de este libro trabajaremos con Visual Studio .NET 2003, que es la l
tima versin de produccin del entorno en el momento de escribir estas lneas. Exis
te una versin 2005 Express en estado beta que tambin podra utilizar el lector.
Por otro lado, el libro se basa principalmente en la versin 1.1 del framework, que
tambin es la ltima versin de produccin a la fecha de publicacin de esta obra.
Quienes no posean el entorno Microsoft Visual Studio pueden utilizar Mono en
ambientes Windows. GNU/Linux y Mac Os X.
El entorno Visual Studio .NET 2003 es una excelente herramienta de desarrollo.
Con ella podremos crear soluciones que, a su vez, podrn contener uno o ms pro
yectos de diversos lenguajes en funcin de los paquetes que tengamos instalados; en
sual Studio .NET hace uso del framework .N ET SDK y funciona como front end
para evitar que nosotros tengamos que interactuar con herramientas en comando
de lnea. El framework .NET SDK puede ser descargado desde el siguiente enlace:
http://msdn.microsoft.com/netframework.
Sin embargo. Visual Studio .NET es mucho ms que un simple front
de las tareas que podremos realizar con l son las siguientes:
end. Algunas
Navegar fcilmente por las clases por medio del visor de clases.
Navegar por los archivos de nuesrros proyectos por medio del explorador de so
luciones.
Entender ms rpidamente el cdigo escrito gracias a que el editor colorea las pa
labras reservadas y los tipos de datos conocidos.
Organizar mltiples proyectos y editar fcilmente sus propiedades.
Configurar el entorno para que ejecute herramientas externas (como precompiladores).
Depurar nuestros proyectos fcilmente y consultar valores de objetos de modo in
teractivo, as como realizar depuraciones remotas desde otras computadoras.
Acceder a facilidades de bsqueda y reemplazo por hoja de cdigo fuente activo y
en archivos.
Editar recursos (bitmaps, iconos, archivos binarios, etc.) por medio de herramien
tas integradas, y navegar por ellos por medio del visor de recursos.
Agregar tareas por realizar haciendo uso de la lista de tareas pendientes, que ade
ms inserta automticamente tareas a partir de comentarios prefijados.
Generar documentacin en formato H TM L por medio de una herramienta pro
vista con el entorno. Esta documentacin es generada a partir del cdigo fuente y
comentarios con formatos especficos que escribiremos en l.
Colapsar y expandir trozos de cdigo para mejorar la legibilidad de nuestras fuentes.
Posibilidad de integrar herramientas al entorno por medio de un sistema de plug-ins.
[ j | j QU ES MONO'/
Desde el ao 2001, la empresa Ximian (adquirida luego por Novell) comenz a desarrollar el pro
yecto Mono, que es una plataforma de desarrollo Open Source basada en el framework .NET. Con
Mono es posible escribir aplicaciones en C# (o VB.NET) y ejecutarlas no slo en Windows, sino
r.c o d e
PROGRAMACIN Cg
[ Q ] QU ES UNA DLL?
Una DLL (Dynamic Link Library\ es un conjunto de funciones y/o clases que pueden ser accedi
das y utilizadas por otros programas en tiempo de ejecucin. Estas libreras pueden ser creadas
desde C# o desde otros lenguajes.
iK r .r n r ip
i
i
Y
i
i
Y
Luego, cuando construimos la solucin se construyen todos los proyectos (que pue
den estar relacionados directamente o no), es decir que se procesan todos los ele
mentos de cada proyecto para generar los archivos de salida que correspondan.
u s r .c o d e
27
PIRAMACiUN C#
Proceso de
Compilacin
(csc.exe)
archivosl.cs
i-
i
i
i
i
i
i
archivos2.cs
i
i
i
archivos3.cs
.-
programa.exe
ri
nuestro programa
,N E1
Pero veamos cmo crear nuestra primera aplicacin C# con l. En primer lugar, cabe
destacar que el entorno es sumamente configuradle y que la organizacin de los pane
les, as como la pantalla de inicio, puede variar en funcin de cmo la configuremos.
Si es la primera vez que ejecuta la aplicacin o si no ha modificado las opciones
de inicio predeterminadas, debera encontrarse con la pgina de inicio que se
muestra en la siguiente figura:
Start Pag** j
E s a a g iE s g r
};fit
'Visu4!C++;
v-'tfiiov- U v
s*: ffl. i
i Visual C++
Show Help:
At Startup:
Irteti! iiclr C z m i r t
Show
Gfivironn-iefd
v '.c o d e
tambin es una cuestin de gustos, y lo que especifica es que cada vez que inicie
mos la aplicacin veremos lo que muestra la siguiente figura:
29
PHOGRAMACION C*
Nuevo proyecto
GUA VISUAL 1
New Project
'-i,3&k~ 1
Project Types:
Im p fe te s :
C j | Visual C # Project:
- D
Visual C++Pro)ects
ASF.NET Web
Service
_ i Othei Project:
[ _ j Visual Stufo SoM ions
ASP.NET
M cbileW ...
Web Control
Library
i j i '
Consol
Application
Windows
Service
Enipty Proiecl
ame:
location:
Canee!
Help
CU Projects, luego es
pecificaremos la plantilla del tipo de proyecto que deseemos crear. Lo que hace la
plantilla del proyecto es fijar opciones predeterminadas al modo de compilacin de
nuestro proyecto, que finalmente especificar los parmetros que se enviarn al
compilador C# cuando construyamos el proyecto para generar un archivo ejecuta
ble (con instrucciones M SIL).
Para comenzar con algo sencillo, seleccionaremos la plantilla
(en ingls. Consol
Application),
Aplicacin de consola
cin, si es que no nos gustan las opciones que nos sugiere el entorno, y finalmente
presionaremos el botn OK.
Hecho esto, el entorno crear un proyecto C# que poseer dos archivos del tipo .CS
(por C#, que se pronuncia C Sharp y usualmente se abrevia CS). Los .CS son archi
vos con cdigo fuente C#; no sern distribuidos con nuestra aplicacin, solamente
los utilizaremos para crearla.
Si por medio del explorador de soluciones miramos los nombres de los archivos que
componen nuestro proyecto, veremos estos dos archivos .CS, que se llaman:
30
a s r .c o d e
Assenxlyinfo.cs
Classl.cs
* Ciassl:
Main
u s r .c o d e
31
PROGRAMACIN GS
WriteLine
Build,
Build Solution.
Si hacemos esto, podremos ver que en el panel llamado Output (salida) se observa el
progreso de la construccin de nuestra aplicacin. Si existe algn error, tambin se
mostrar all como informacin, y podremos hacer doble clic sobre i para que ei
entorno nos lleve automticamente a la lnea donde se encontr la falla.
- Build started: Project: consoleApplicationl, Configuration:
Debug .NET --Preparing resources...
pdating references...
Perfonning main compilation...
Build complete - 0 errors, 0 warnings
Building satellite as3eniblies...
----------- Done ----------Build: 1 succeeded, 0 failed, 0 skipped
Si hemos ripeado todo bien, deberemos ver lo que indica ei cuadro anterior, es de
cir, a notificacin de que la aplicacin ha sido construida satisfactoriamente.
Luego, podremos ingresar nuevamente en el men Build y seleccionar la opcin
Start (comienzo) o Start without debuggina (comienzo sin depurar). Lo bueno de es
ta ltima opcin es que no cierra la ventana donde est nuestro programa cuando
ste termina, sino que nos solicita que ingresemos una tecla para continuar.
i
. : .c o d e
Claro que si no tenemos Visual Studio a mano, pero hemos instalado el framework
.NET, podremos realizar la compilacin de modo manual (o para expresarnos mejor: utilizando el compilador desde comando de lnea). Al fin y al cabo, habamos
end al compi
programa.es,
Esto nos dejar como salida, en el directorio donde nos encontremos y si no hubo
errores en la compilacin, un archivo llamado programa.exe. Si ejecuta la aplica
cin csc.exe con el parmetro /?, se listarn los switchs vlidos del compilador.
RESUMEN
Est bien, nuestra primera aplicacin no ha sido muy excitante, pero al menos hemos dado el
primer paso y eso no es poco. Tambin es cierto que algunas cuestiones han quedado sin mu
cha explicacin: qu es una clase?, qu es un mtodo esttico?, qu es System? No nos de
sesperemos; a medida que avancemos en el libro, iremos tratando todos estos temas de ma
nera detallada. Ya hemos visto el conejo blanco, ahora slo deberemos seguirlo.
.c o d e
33
PKOGRAMAWf
ACTIVIDADES
TEST DE AUTOEVALUACIN
je C# de C++?
A Qu es elCLR?
Q S EEi
tjrufcnKft m w. o
(*:
fnme**yc
5 En
2 Qu es el cdigo MSIL?
34
u s r .c o d e
PROGRAMACIN C#
Captulo
Fundamentos
de lenguaje CU
En el captulo anterior presentam os
la plataform a y el lenguaje que
tratarem os en esle libre. Ahora
nos sum ergirem os en los conceptos
fundam entales de C#, lo que ser
provechoso tanto para quienes der,
sus prim eros pasos en la program acin
come para quienes vengan de lenguajes
36
La sentencia using
37
Los comentarios
tas,lrllblK
Operadores
36
Espacios de nombres
38
35
40
40
41
4?
47
46
50
53
55
55
Sentencia de bucle
Resumen
66
79
Actividades
80
PROGRAMACIN C#
ESPACIOS DE NOMBRES
Los espacios de nombres son un recurso que utilizan algunos lenguajes para la or
ganizacin de un gran conjunto de tipos de datos. As como los directorios (o car
petas) permiten organizar archivos de modo que ficheros del mismo nombre con
vivan en directorios distintos, los espacios de nombres realizan una tarea similar, pe
ro de manera lgica, para tipos de datos extendidos como clases y estructuras.
De este modo, dos clases distintas con el mismo nombre podran ser utilizadas en
el mismo proyecto sin que se suscite ningn error.
Los espacios de nombres tambin pueden ser anidados, por lo que puede haber unos
dentro de otros y, de este modo, mejorar la organizacin de las libreras de un proyecto.
Gracias a esta facilidad, los nombres de los tipos de datos que nosotros crearemos
en el futuro podrn ser de lo ms sencillos, sin temor a que ya exista alguna clase o
estructura de nombre igual en otra librera que luego podremos querer utilizar.
36
u s ! .c o d e
Espacios de nombres
Veamos cules son los espacios de nombres ms populares que posee la librera BCL:
1 -ESPAaOS.OENCMBRES
Clase base de toda la librera.
[. System,Collecticns
System.Data
j System.Drawing
java.util
java.sql
java.awt
System. 10
java.io
System.Net
System.Reflection
java.net
java.text
System.Threading
java.util.concurrent
System.Security
System.Windov/s.Forms
: System.Xml
java.securjty, javax.crypto
javax.swing
javax.xml
mentacin que provee Visual Studio .NET o la provista por MSDN {MSDNLibrary).
Ahora, si volvemos a ver el cdigo de nuestro primer programa creado en el captu
lo anterior, entenderemos mejor aquello de System.Console.WriteLine. Consol es
una clase cue pertenece al espacio de nombres System. Si no lo hubisemos ante
puesto al nombre de la clase, el compilador habra arrojado un error, oues no ha
bra encontrado a Consol en el espacio de nombres global.
La sentencia using
37
PROGRAMACIN C I
V
Consol.WriteLina("Nuestro primer programa');
}
}
LOS COMENTARIOS
En un principio, nuestro programa ser pequeo, y analizar qu sucede dentro de
l ser sencillo, ya que bastar con echar un ojo al cdigo escrito. Sin embargo, a
medida que ste crece, se vuelve muy conveniente poder introducir notas aclarato
rias sobre qu es lo que pretendemos que el programa haga. As, si escribimos un
algoritmo en particular, podemos agregar un texto que indique qu debe hacer di
cho algoritmo, y de este modo otro programador podr entenderlo rpidamente, o
quiz nosotros mismos, releyendo el cdigo que hayamos escrito tiempo atrs.
Para que el compilador no interprete el texto aclaratorio como intentos fallidos de
instrucciones, debemos indicarle que estamos introduciendo un comentario.
C# acepta dos tipos de comentarios. Uno es el comentario de lnea, que debe co
menzar con los caracteres //, como por ejemplo:
; // Este es un comentario
38
u s r .c o d e
Las variables
El otro es el comentario clsico de! lenguaje C, que comienza con los caracteres f*
y termina de manera inversa, con los caracteres */:
/* Este es un comentario */
'
Este ltimo tipo de comentario puede ser multilnea; el siguiente es ejemplo de esto:
LAS VARIABLES
Las variables son utilizadas para almacenar datos. Sin embargo, para poder utilizar
una variable, en primer lugar deberemos declararla, a diferencia de lo que ocurra
en Visual Basic 6.0 o en algunos lenguajes de scripts.
La declaracin de una variable est compuesta mnimamente por dos elementos:
El tipo de dato.
El identificador.
fin de
sentencia
A
int contador ;
la luego en el programa.
tipo identificador
Figura
1.
Para que el compilador los acepte como vlidos, los identificadores debern seguir
ciertas reglas, similares a las existentes en otros lenguajes como C, C++, Visual Ba
sic o Java. Veamos:
Deben comenzar con una letra o un carcter de guin bajo (underscore).
Deben continuar con una letra, un nmero o un carcter de guin bajo.
No deben coincidir con una palabra reservada.
u s r .c o d e
39
PROGRAMACIN CU
' enum
8 long
8 stackalloc
* event
explicit
extern
false
8 namespace
8 new
8 static
finally
Fixed
0 float
for
foreach
goto
* if
8 implicit
8 in
inr
interace
8 internal
8 is
8 lock
8 nuil
8 object
8 operator
8 out
8 overtide
* params
8 private
8 proceded
8 public
8 readonly
8 re
8 return
8 sbyte
8 sealed
8 shori
8sizeof
string
8 struct
8 switch
8 this
throw
8 true
8 try
8 typeof
8 uint
8 ulong
8 unchecked
8 unsafe
* ushort
using
8virtual
8 void
8while
Ejemplos de dentificadores
Algunos dentificadores vlidos son:
MiVariable
contador
Contado_
mi_variable
40
u t.c o d e
Las variables
Convenciones de nombramiento
Existen diversas convenciones de nombramiento para clases, variables, funciones,
etc. La idea detrs de estas convenciones es especificar reglas para la creacin de los
identificadores y que, de este modo, especialmente en grupos de trabajo, los nom
bres asignados sean similares en cuanro a estructura.
Una convencin que Microsoft sola recomendar era la notacin hngara. A gran
des rasgos, en dicha notacin se antepona como prefijo a los nombres de las varia
bles su tipo de dato (codificado en una o dos letras) y una m_ si era una variable
miembro, tina p_ si era un puntero, una g_. si era una variable global, etc.
Hoy da, esta notacin ya no es aconsejada con el mismo iervor, pues los editores
modernos rpidamente nos indican el tipo de dato al cual pertenece una variable, y
de este modo se pierde una de sus grandes ventajas. Sin embargo, a fin de cuentas,
es una cuestin de gustos. Lo importante ser mantener la misma convencin a lo
largo de todo el proyecto.
Este libro adopta la misma notacin que utiliza la librera BCL: notacin camello
para variables, y notacin Pascal para clases, estructuras, enumeradores, funciones,
mtodos, constantes y propiedades.
La notacin camello consiste en crear identificadores concatenando palabras sin ha
cer uso de caracteres especiales (como el underscore o el guin), sino colocando en
mayscula la primera letra de cada palabra, a excepcin de la primera.
unaVariableEntera
. .c o d e
contador
nombrePersona
41
PROGRAMACIN Cs
La notacin Pascal es similar a la camello, slo que la primera letra debe ser colocaa. e n m a y s c u l a .
ImprimirValor
FijarLargo
DameAltura
(montculo). Los tipos de datos por valor sern almacenados en el stack, mientra.-.
Las variables
que los tipos de datos por referencia sern almacenados en el heap (en el stack que
dar una referencia de la ubicacin en dicha zona de memoria).
Nmeros enteros
C# ofrece tres tipos de nmeros enteros:
short: nmero entero corto signado.
int: nmero entero signado.
long: nmero entero largo signado.
Si ambos son enteros, qu diferencia existe entre ellos? La respuesta es sencilla: la
cantidad de memoria que se deber reservar y cun grande es el nmero que cabr
dentro de nuestra variable.
En 2 bytes (short) es posible especificar un nmero con rango (-32768, 32767),
mientras que en 4 bytes (int) es posible especificar un nmero dentro del rango
(-2147483648,2147483647).
Por otro lado, los tipos de datos numricos enteros pueden ser signados o no. Si es
pecificamos un nmero entero corto no signado (ushort), seguimos ocupando 2 by
tes, pero al ser todos positivos, el rango vlido ahora es (0, 65533). Si intentamo:
asignar un nmero negativo a una variable no signada, se producir una excepcin.
Declarando algunas variables enteras:
short a;
ushort b;
int d;
uint e;
long ;
ulong g;
UJ
ti
1!
Entero signado
// Entero no signado
Entero largo signado
Entere largo no signado
Y LOS PUNTEROS?
Quienes vengan de C o C*+ podran preguntar: dnde estn los punteros? C# permite el uso de
punteros igual queC++, pero para esto se deber marcar el bloque o funcin comounsafe (no rn
gurnj, adems de- modificar parmetros de compilacin, En C# su uso oueda relegado a necesi
dades especificas, como intersetuar con recursos no gestionados creados en otros lenguajes.
COOt
PROGRAMACIN CE
int a;
unit a;
La idea de reemplazar el unsigned int por un simple uint tiene que ver con facilitar
nos la vida a nosotros, los programadores.
Finalmente, existe tambin un tipo de dato llamado byte, en el cual se puede almace
nar, como su nombre lo indica, el valor de un byte. Su rango es (0,255) y es no signa
do, aunque es posible declarar un byte signado por medio del tipo de dato sbyte.
Nmeros no enteros
C# diferencia en tipo a un nmero entero de un nmero con parte fraccionaria: pa
ra estos nmeros de datos existen tres tipos: float, double y decimal.
La diferencia entre ellos es la precisin. Las computadoras se llevan muy bien con los
nmeros enteros, pero para trabajar con nmeros decimales necesitan utilizar un re
curso matemtico llamado coma florante. De esta manera es posible almacenar una
cantidad no fija de decimales, pero con una determinada precisin mxima; esta pre
cisin, en definitiva, se encuentra determinada por el tamao toral que ocupa la va
riable en memoria. Los tres tipos de datos de nmeros no enteros que maneja C# son:
float:
: .c o d e
Las variables
// Precisin simple
double b;
// Precisin doble
decimal c;
// Precisin mxima
Booleanos
Las variables booleanas pueden albergar dos valores: true (verdadero) o false
[falso).
Caracteres
Para almacenar un carcter en una variable debemos especificar su tipo en
char.
Ejemplo:
char a;
Este tipo de datos puede albergar un carcter del tipo Unicode, pensado especial
mente para alfabetos orientales que poseen una cantidad de elementos mayor a 256.
Existen ciertos tipos de caracteres especiales que son interpretados por el compi
lador dentro de una cadena de texto. stos son conocidos como caracteres de esca
pe, y en la siguiente tabla pueden apreciarse algunos de ellos:
lnea nueva
. tab horizontal
backspace
retomo de carra
barra invertida
comilia doble
\n
\t
V
w
.c o d e
45
PROGRAMACIN Cfl
El primer carcter (\t) ser interpretado como un tab horizontal, y el carcter \n,
como una lnea nueva, por lo que en pantalla podremos observar:
Textol
Texto2
Lista de tipos de datos primitivos
En la siguiente tabla se describen los tipos de datos fundamentales del lenguaje.
UPO DE DATO
FUNDAMENTAL
bool
TAMAO EN BYTES
1
TIPO ESTRUCTURA
System.Boolean
DESCRIPCIN
Booleano. Su valor puede
ser tnie (verdadero) o false (falso)
sbyte
System.SByte
Byte no signado
byte
System.Byte
Byte
; char
System.Qtar
Carcter
short
System.lnll6
Entero corto
ushort
System.UIntl6
int
System.lnt32
Entero
uint
System.Ulnt32
Entero no signado
long
System.lnt64
Entero largo
: ulong
System.Ulnt64
float
System.Singie
double
System.Double
decimal
16
System.Decimal
Como se puede observar en la tabla anterior, todo tipo de dato primitivo que defi
ne el lenguaje se mapea con una estructura de la librera BCL. Todos los lenguajes
que se construyen para la plataforma .NET debern hacer esta tarea, y de este mo
do la intercomunicacin entre ellos ser mucho ms sencilla debido a que, en defi
nitiva. utilizan ios mismos tipos de datos fundamentales
As es que declarar una variable entera como:
int a;
4(
COC
Las variables
System.Int32 a;
Notemos que el nombre de la estructura relacionada est compuesto por dos par
tes: el tipo de dato (con la primera letra en mayscula) y la cantidad de bits que
ocupa en memoria. De este modo tambin podemos inferir que un int siempre ocu
par 4 bytes, ms all de la plataforma en la cual estemos trabajando (algo que no
sucede en C o C++, donde la especificacin no ata los tipos de datos a tamaos f
sicos, sino que simplemente exige una relacin entre stos).
En el caso expuesto hemos fijado el valor 1 a la variable a del tipo nmero entero
en la misma lnea en que declaramos la variable. Esto podra no ser as; los siguien
tes tambin son ejemplos vlidos:
int a;
I I ...
a = 1;
l r . c o d e
47
PROGRAMACIN C*
operador de
asignacin
, ,
i
fin de
^
X - sentencia
a 4 ;
TT
variable i expresin
Constantes
Existen tres constantes:
Literales: especificadas por medio de un valor escrito en el cdigo.
int a = 25;
string nombre = "Tito";
En el caso citado,
25
46
i : .c o d e
Las variables
{
Enero,
Febrero,
Marzo,
Abril,
Mayo,
Junio,
Julio,
Agosto,
Septiembre,
Octubre,
Noviembre,
Diciembre
Luego, podramos declarar una variable como del tipo Mes. Veamos:
Mes m;
Ahora, m slo podr adoptar los valores constantes especificados en el enumerador Mes.
m = Mes.Enero;
49
PROGRAMACIN C#
Estas constantes podran poseer un valor literal asignado a ellas por medio del ope
rador de asignacin:
enum Mes
{
Enero = 1,
Febrero = 2,
Marzo = 3 ,
Abril = 4,
Mayo = 5,
Junio a 6,
Julio = 7,
Agosto a 8,
Septiembre a 9,
Octubre a 10,
Noviembre a 11,
Diciembre a 12
}
III
Dos constantes definidas dentro de un enumerador podran poseer el mismo valor numrico.
Esto seria til para definir constantes que sean sinnimos; por ejemplo, tanto "setiembre" como
"septiembre" podran estar relacionados con el valor 9.
Las variables
Las implcitas son las que realiza el compilador sin requerir de nosotros la especifica
cin de ninguna sentencia adicional. Este tipo de conversiones se caracteriza por el he
cho de que nunca se pierde informacin ni precisin. La conversin es siempre vlida.
En el siguiente ejemplo vemos cmo un nmero entero es convertido a un entero
largo. La conversin se da en la segunda lnea y es implcita.
int ni o 10;
long n2 = ni;
PROGRAMACIN CU
long ni a Int64.MaxValue;
checked
{
checked.
No hace falta ser un genio para saber que lo escrito en el cdigo anterior fracasar. El
rango de un short es de (-32768, 32767), por lo que 60000 es un nmero demasia
do grande. Tal vez el ejemplo sea trivial, pero si queremos que dicho cdigo sea com
pilado de todos modos, entonces deberemos encerrarlo en un bloque unchecked:
unchecked
{
short ni 60000;
}
La clase Convert
La librera BC L nos ofrece una clase llamada Convert dentro del espacio de nom
bres System, que es muy til en el momento de realizar conversiones. La gran va-
ERRORES DE CONVERSIN
Cuando el compilador no pueda realizar una conversin de tipos de datos, arrojar un error del tipo
"Cannot implicity convert type...". Un doble clic sobre dicho error nos llevar a la lnea desde la cual
proviene el mensaje. Deberemos pensar si hemos cometido algn error o si nos olvidamos de espe
cificar la conversin de modo explcito para sobrescribir el sistema de revisiones del compilador.
52
u s r .c o d e
Las variables
riedad de mtodos estticos que posee Convert nos permite pasar un tipo de dato
primitivo a cualquier otro tipo de dato primitivo.
Por ejemplo, la siguiente operacin no es vlida debido a que intentamos pasar de
un nmero entero a un tipo booleano.
bool a = 1;
Operadores
Es posible combinar nmeros y variables en expresiones por medio de operadores
matemticos. Veamos:
int a
= 3+ 4;
int a
= 4;
int b
o a/ 2?
//
//
Almaceno el nmero 7 en a
Almaceno en b el
contenido de la variable
dividido por 2
int a
=10;
int b
= a* 14; //
Almaceno en b el
contenido de la variable
multiplicado por 14
u s r .c o d e
53
PROGRAMACIN CU
Sin embargo, cuando operamos de este modo es conveniente tener mucho cuidado,
ya que el tipo de dato resultante estar en funcin de la operacin que realicemos.
Por ejemplo, la suma de dos nmeros enteros dar como resultado un nmero en
tero, y la divisin de dos nmeros enteros tambin dar como resultado un nme
ro entero; esto ltimo es lo que precisamente puede traer muchos problemas.
Si yo le pregunto cul es el resultado de la operacin 5 dividido 2, usted seguramen
te contestar 2,5! Pero nuestra computadora, en cambio, nos devolver 2, ya que la
operacin fue entera y el resultado fue de enteros. Colocar una variable de tipo flo
tante al resultado no soluciona este inconveniente:
float a o 5 / 2>
Para solucionar este inconveniente deberemos convertir al menos uno de los operandos en flotante, para que, de este modo, la divisin no sea entre nmeros ente
ros, sino entre un entero y un nmero flotante:
float a = 5.Of / 2;
U U NMEROS MGICOS
Colocar una constante literal escrita sobre el cdigo sin explicacin alguna es una mala prctica
que suele denominarse "nmeros mgicos". Existe un muy buen libro llamado Code Complete,
de Steve McConnell, que cita muchas de las malas prcticas ms populares e indica cmo evi
tarlas. Lectura obligada si se desea ser un buen programador.
54
..c o d e
Sentencias condicionales
La primera sentencia que veremos ser la condicional if. Con esta sentencia podre
mos expresar, por ejemplo, que:
SIGNIFICADO
Igual a
tSBBBHBHRBBHflHBI
<
Menor a
>
M apa
<=
Menor o igual a
u s r .c o d e
55
PROGRAMACIN CK
Veamos un ejemplo:
int a * Consol. In.PeekO;
if (a
'x')
Consol.Write("Has adivinado el carcter secreto*)}
Otros lenguajes como Visual Basic utilizan otros criterios para exigir una sentencia
de fin de condicional, como End If o similares. C#, como C y C++, utiliza el con
cepto de bloques en todas sus sentencias. De hecho, las variables declaradas dentro
de bloques sern locales a stos.
Y qu ocurre cuando la expresin booleana especificada en el if se evala por falso?
Bueno, una sentencia condicional if debe poseer una sentencia que es el cdigo que
se ejecuta ante una evaluacin por verdadero de la expresin booleana, y puede o no
56
u s r.c o d e
poseer una sentencia por ejecutar si la expresin es evaluada por falso (esta sentencia
debe ser precedida por la palabra clave else). Entonces, los escenarios posibles son dos:
u s r .c o d e
57
PROGRAMACIN C#
3 y 4,
el flujo
if (a
; {
'x')
: }
; else
(
Consol.Write('Tal vez deberas intentarlo de nuevo*);
: }
Ntese que las llaves que colocamos en el cuerpo del else no son obligatorias en es
te caso, pues ste posee slo una lnea.
Y w A A J expresin
i V
r
1 booleana
,,/ A v
r
__
se
sentenda
expresin booleana
if(carss'a')
sentencia [
Consola.Nrite ('Verdadero*);
else
sentencia [
56
u s r .c o d e
Y qu ocurre si Jas opciones son mltiples? Si, por ejemplo, deseamos solicitar un
nmero del 1 al 3 y realizar diferentes acciones en funcin de la opcin elegida.
Bueno, nada nos impide escribir lo siguiente:
i (num == l)
{
. // opcin 1
}
else
{
if (num s= 2)
{
// opcin 2
}
else
{
if (num =e 3)
{
/./ opcin 3
}
else
{
// ninguna opcin
}
}
}
Q Q OPERADOR DE IGUALDAD
Ntese que el operador de comparacin de igualdad es "==" y no
nacin). Esto, en un principio, podra confundirnos, sobre todo si venimos de otros lenguajes.
Afortunadamente, si nos equivocamos y utilizamos V en lugar de V , el compilador nos lo in
formar, ya que la expresin condicional debe poder ser evaluada por verdadero o por falso.
u s r .c o d e
59
PROGRAMACION Cfl
2.
3.
Dentro del segundo else nos encontramos con otro if con una expresin que
evala num == 3 por verdadero, ya que 3 es igual a 3. Entonces, el flujo de eje
3.
Pero existe una manera de escribir lo mismo que mejora mucho la legibilidad.
if (a : '1')
1
opcin 1
else if (a
'2')
V
/'/ opcin 2
\
)
else if (a '3')
/
\
// opcin 3
elee
{
;// ninguna opcin
Operadores lgicos
Dentro de los parntesis del if debemos colocar una expresin booleana. Dicha ex
presin puede ser trivial, como, por ejemplo:
60
u s r .c o d e
b *= 2)
Hacer_algo
i
'
' ,
..-i.,: ;
El operador && es el operador lgico AND, por lo que nuestra expresin fue equiva
lente a decir: Si a es igual a 1 Y b es igual a 2, entonces....
Por lo tanto, slo ingresaramos en el cuerpo de la sentencia if cuando la expresin
1 o b fuera igual a 2.
if (a
1 || b = 2)
Hacer_algo
ir
&&
Y lgico (conjuncin)
0 lgico (disyuncin)
I_ _ _ _ _ _ _ _ _ _ _ _ Negacin lgica
Tabla 5. Operadores lgicos.
La sentencia switch
La sentencia
switch
evaluacin de una expresin. Es ideal para ciertos casos; por ejemplo, cuando una
u s r .c o d e
61
PROGRAMACIN C#
(expresin)
case
case
case
expresin constante
(sentencia)
(break;]
[break;]
[break;]
'
Suponiendo que num sea una variable de tipo entera, veamos el siguiente ejemplo:
switch (num)
{
case 1:
Consol.Write("Opcin 1*);
break;
case 2;
Consol.rite("Opcin 2*);
break;
case 3:
Consola.rite("Opcin 3');
break;
default:
Consol.rite("Ninguna opcin");
break;
Como podemos apreciar en el listado anterior, num se coloca como expresin para
evaluar por el switch. Luego, en cada case colocaremos los valores posibles de esta
variable que deseemos tratar. El break impide que el flujo de ejecucin salte de un
case al siguiente, aunque en realidad esta exigencia es heredada del uso en otros len
guajes como C, C++ o Java, ya que, de todos modos, en C# no se permite el salto
silencioso de un case a otro.
Si quisiramos ingresar en el
case 2),
62
case
deberamos escribir:
u s r .c o d e
switch (num)
{
case 1:
Consol.Jritfl'Opcin 1")
goto case 2;
case 2:
Consol.Write('Opcin 2');
break;
case 3:
Consol.Write('Opcin 3*);
breakj
default:
Consol.tirite ("Ninguna opcin*);
break;
En el caso de que el tratamiento de una opcin sea igual al de otra, podremos escribir:
: switch (num)
{
case 1:
case 2:
Consol.tirite ('Opcin 1 o 2*)
break;
case 3;
Console.WriteCOpcin 3');
breakj
default:
ConBole.Write'Ninguna opcin*);
break;
}
En el caso de que ningn valor de num coincida con los case que hemos especifi
cado, lo que podemos hacer es colocar un default que funcionara como una es
pecie de else final a toda la sentencia, y slo se ingresar aqu si no se ingresa en
ningn
u s r .c o d e
63
PROGRAMACIN C#
n i
wmam
La sentencia
switch suele utilizarse cuando una variable slo puede adoptar un nmero estable
cido de valores constantes y para cada valor se debe realizar un tratamiento diferente.
64
u s r .c o d e
expresin a evaluar
1 1
switch(num)
{
expresin__ r f j |
constante
LjCfig
casel:
Consol.Write( "uno")j
break;
expresin
constante
r
U .
2
cuerpo de
sentencia
switch
Consol.Write(*dosn);
break;
default:
Consol.Write( "tres');
breakj
}
switch (man)
case 1:
Consola.Write("cuatro o cinco");
case 2:
case 3:
Consol.Write("uno,
dos o tres');
break;
.
.
case 4:
case 5:
Consol.Write{"cuatro
u s r .c o d e
65
PROGRAMACIN C#
Ejemplo 2:
switch (nua)
if (num 1)
Consola.Writa("uno") ;
{
caae 1:
else if (nua 2)
Consol. Write("uno) ;
break;
ConBole.WriteCdos*);
else
caae 2:
Consol.Write ("otro1');
Coneole.Write^doB);
break;
default:
Consol.Write("otro");
break;
Sentencia de bucle
En algunas ocasiones requeriremos que determinada porcin del cdigo escrito sea
repetida una cierta cantidad de veces o hasta que se cumpla una determinada con
dicin. C# cuenta con varias sentencias para cumplir este fin.
La sentencia while
La sentencia while (que significa
mientras)
66
u s r .c o d e
while
expresin
booleana
y *
sentencia
expresin booleana
while(numlsO)
{
//...
//...
cuerpo de la
sentencia while
//...
}
{
Consol.WriteLine("Ingrese la palabra clave:*);
palabraClave = Consol.In.ReadLine0;
}
Consol.WriteLine("Correcto*);
u s r .c o d e
67
PROGRAMACIN C#
la palabra clave:" y
//
c < 10)
...
nor de 10....
La sentencia do
Con el while, el bloque de cdigo por repetir no ser ejecutado nunca si la expre
sin es falsa la primera vez. En ciertas ocasiones nos vendra bien ejecutar dicho c
digo al menos una vez, y luego evaluar la expresin.
Para esto existe otra sentencia llamada do:
slo
68
u s r .c o d e
ii
d.
sentencia
while
do
cuerpo de la
sentencia do...while
{
punto y coma
}while(num**l);
expresin booleana
u s r .c o d e
69
PROGRAMACIN Ctt
Veamos un ejemplo:
atring palabraClave;
do
{
Consol.Write("Ingrese la palabra clave\n*);
palabraClave = Consol.In.ReadLine();
} while (palabraClave 1= 'salir*);
Consol.Write("Correcto*);
La sentencia for
En ciertas ocasiones tendremos la necesidad de ejecutar un bloque de cdigo un n
mero determinado de veces. C# ofrece para estos casos una sentencia llamada for.
BUCLES INFINITOS
70
u s r .c o d e
Aqu declaramos e inicializamos una variable que slo ser vlida dentro del cuer
po del for (una vez terminado ste, dicha variable no existir ms, es local a la sen
tencia al bloque del for). Esta sentencia slo se ejecutar la primera vez que ingre
semos en el ciclo.
i<5
Mientras dicha expresin booleana sea vlida, se ejecutar el cdigo especificado en
el cuerpo del for.
i++
Sentencia que se ejecuta en cada ciclo, incrementa en uno el valor de la variable i.
Indefectiblemente dicha variable llegar a 5; por lo tanto, la expresin "i<5" se eva
luar a falsa y el for habr terminado. Por ese motivo, el cuerpo del for, en este ca
so, se ejecutar cinco veces del siguiente modo:
Se ejecuta la sentencia "int i=0" (esta sentencia slo se ejecuta una vez).
Se evala la expresin "i<5". En este caso "0<5" es verdadero, por lo tanto se in
gresa en el cuerpo del for.
bucle 0: se ejecuta Consol.WriteLine().
bucle 0: se ejecuta la sentencia "i++". En este caso i se incrementa en 1 y pasa a
valor 1.
Se evala la expresin "i<5". En este aso
gresa en el cuerpo del for.
bucle 1: se ejecuta Console.WriteLine ().
"1<5"
().
71
PROGRAMACIN C#
().
().
1 y pasa a valor 5.
Se evala la expresin "i<5". En este caso "5<5" es falso, por lo que se sale del bucle.
72
u s r .c o d e
int i=0;
Consol. Wr i te (\..\nB);
while (i<5)
{
Consol.Write("...\nH) ;
i++;
}
String palabraClave *
u s r .c o d e
73
PROGRAMACIN Ctf
{
Conaole.Writet*.*);
Coaflole.WriteC.1');
palabraClave Console.ReadLineO;
*h'*i
fcf!*
i -i"
'
C'*>
<
vv
La sentencia foreach
Existe una ltima sentencia de repeticin que es muy til para trabajar con colec
ciones de datos.
Si bien todava no hemos introducido el tema de colecciones ni el de arrays, nos
adelantaremos un poco simplemente para poder explicar esta poderosa sentencia
que se encuentra (desgraciadamente) ausente en lenguajes como C o C++.
Una coleccin es un conjunto de elementos, en general, del mismo tipo, aunque
no necesariamente. Utilizando algn tipo de coleccin se puede definir un conjun
Y al segundo elemento:
i
enteros 11] 500;
Y al tercero (y ltimo):
enteros [2] <* 900;
74
u s r .c o d e
Trabajar con arrays puede ser muy cmodo, pero no lo sera tanto si el lenguaje no
ofreciese sentencias adecuadas para manipularlos. La sentencia for es una de ellas.
Supongamos que deseamos inicializar los elementos de un array en un determina
do nmero; un modo de hacerlo sera escribiendo:
int {J enteros = new int (3];
for (int i=0; ixenteros.Length; i+t)
enteros(i] o 0;
Dentro del parntesis del foreach primero declaramos una variable que oficiar de
elemento activo de la coleccin; sta es seguida de la palabra clave in y, finalmente,
la coleccin por la cual deseamos iterar.
Entonces, en cada iteracin, en lugar de tener que acceder al elemento por subn
dice, directamente hacemos uso de la variable elemento declarada. Slo cabe la
salvedad de que el uso de la variable elemento es slo para lectura, no podremos
practicar una asignacin con ella.
QU ES LA PROPIEDAD LENGTH?
Length es una propiedad de los arrays que nos indica la cantidad de elementos que ste posee.
Ms adelante, cuando profundicemos sobre este tema, analizaremos los mtodos y propiedades
para trabajar con ellos.
u s r.c o d e
75
PROGRAMACIN CU
Variable elemento'
j Variable "coleccin
---1 i---1
-- 1
{
//solo lectura de la
j
Cuerpo de la
sentencia foreach
//variable elem
//...
}
76
u s r .c o d e
Tal vez en este momento no puedan apreciarse las ventajas del uso prctico del fo-
{
Consol.Wri teLine("punto a");
i++;
if (i . 3)
break;
Cuando "i == 3" se evala como verdadera, salimos del bucle while y seguimos con
la prxima lnea posterior a ! (de la misma manera en que habra ocurrido si la ex
presin "i < 10" hubiese sido falsa).
u s r .c o d e
77
PROGRAMACIN C#
{
Consol.WriteLine("punto a");
i (i > 3)
break;
La sentencia continu, en cambio, nos permite saltearnos lo que resta de una itera
cin dentro de un bucle para seguir con la prxima (sin salir del bucle). Veamos un
ejemplo con un while y con un for:
int i = 0;
while (i < 10)
{
Consol.WriteLine("punto a");
i++?
if (i > 3)
continu;
78
L .'.c o d e
Console.WriteLine("punto b");
{
Console.WriteLine("punto a");
if (i > 3}
continu;
Console.WriteLine("punto b")j
}
Llegado el momento de ejecutar el continu, las instrucciones que resten de la ite
racin en curso sern salteadas y se dar comienzo a la prxima iteracin.
1 RESUMEN
Por el momento la programacin con C# parece ser bastante similar a C++ o a Java; cuando
comencemos a analizar detenidamente las clases que ofrece la librera BCL junto con las
facilidades del lenguaje, veremos que estamos ante un lenguaje de programacin nico.
u s r .c o d e
79
ACTIVIDADES
TEST DE AUTOEVALUACIN
d)
guientes listados?
int num = 0;
al
if (num == 0)
Consol.Write ("Es valor");
int ni = 10;
double n2 = ni;
float n3 = n2;
Consol.Write("es cero!");
else
Consol.Write("El valor
es distinto de cero*);
bl
2 Para qu se utilizan los espacios de nom
int valor;
if (valor == 0)
Consol.Write("el valor
es cero!");
c)
for (int i=0, i<5, i++)
Consol.Write(".");
80
:.c o d e
PROGRAMACIN C#
Clases
y objetos
En este captulo estudiaremos
la anatom a de la estructura ce datos
m s im portante del lenguaje: la clase.
Veremos corno declarar constantes,
variables y m todos dentro de ella.
Tambin introducirem os otro tipo
de dato muy im portante, la estructura.
Y, finalm ente, explicaremos
qu es el recolector de basura.
Qu es una clase
Cmo declarar una clase
Modificadores de acceso
Instanciacin. Creando objeto?
Constantes de una clase
Variables estticas
Los mtodos
Estructuras
Resumen
Actividades
PROGRAMACIN C#
QU ES UNA CLASE
Una clase es una estructura de datos que utilizaremos para definir nuestros propios
tipos que extendern los primitivos que provee el lenguaje.
La mayora de las veces, las clases se utilizan por medio de sus instancias, las cuales
se denominan objetos. Los objetos del mismo tipo (diferentes instancias de la mis
ma clase) compartirn una estructura comn, pero podrn poseer valores distintos
en sus variables miembro.
Podramos trazar una analoga entre una clase y sus objetos con lo que es un mol
de y los elementos creados a partir de l. Una clase define una serie de variables y
comportamientos por medio de los cuales podremos crear objetos que poseern di
chas variables y comportamientos.
La cantidad de objetos que podremos crear a partir de una clase slo estar limita
da por la cantidad de memoria que posea el sistema.
[U
i;
En Java, el archivo de cdigo fuente suete terminar en ".java" y, a diferencia de C#, muchos corr'
piladores slo aceptan una clase pblica por archivo.
y : ::
LU A,a
82
'
-> r. A
V'-i|||
u s r .c o d e
MiClase,cpp
M i C la s e . e s
La clase MiClase
en lenguaje Java
La clase MiClase
en lenguaje C++
La clase MiClase
en lenguaje C#
O en cdigo:
class <dentificador>
// cuerpo de la clase
En primer trmino, debemos escribir la palabra reservada class, y luego, un identificador vlido que cumpla con las reglas que habamos mencionado en el captulo
anterior. Este identificador debe ser nico en un espacio de nombres. Algunos identificadores vlidos podran ser:
Clase1
Esta_es_una_clase
_mi_clase
_miClase_
u s r.c o d e
83
PROGRAMACIN CU
Y,i!o recordar que el hecho de que el nombre sea aceptado por el compilador no sig
nifica que ste sea un buen nombre. Mejor sera que el identificador de la clase
fuera seleccionado en funcin de un nombre que describiera mejor lo que represen
ta dentro del programa (por ejemplo,
Modificadores de acceso
Dentro de lo que llamamos cuerpo de la clase se colocarn la declaracin y la de
finicin de todos sus miembros, que sern datos y mtodos.
Las variables miembro de una clase se declaran como variables convencionales (co
mo vimos en el captulo anterior), pero pueden poseer algunos modificadores espe
ciales. Un modificador muy utilizado es el de acceso, que regula la visibilidad que
posee la variable o el mtodo desde otros objetos.
Siempre es posible acceder a las variables de una clase desde los mtodos declarados
en ella, ms all de su modificador de acceso. Para otros mtodos de otras clases, s
tos impondrn limitaciones, que son:
der a su contenido desde mtodos de clases que se encuentren dentro del mis
mo assembly.
84
u s r .c o d e
M
int a;
Ahora la clase Foo posee como uno de sus miembros a una variable del tipo nme
ro entero. Esta variable ser privada, pues no se ha especificado otra cosa.
Veamos cmo incluir los modificadores de acceso:
class Foo
{
public int a;
protected int b;
prvate int c;
t. , . \
- ,.;v
..
..
rT*f - . '
Veamos: ahora nuestra variable a fue declarada del tipo pblica, la variable b como
protegida, y la c como privada (aunque especificar prvate no es necesario, en mu
chas ocasiones se realiza para remarcar su condicin).
{
int a; // variable privada
public:
int b; // variable pblica
int c; // variable pblica
u s r .c o d e
85
PROGRAMACIN CU
Instanciacion
Una vez que hemos definido nuestra clase, para poder utilizarla debemos crear una
instancia de ella (aunque es posible acceder a variables y mtodos estticos sin la ne
cesidad de crear objetos de la clase; ms adelante profundizaremos en este aspecto).
La declaracin de un objeto es muy similar a la de cualquier otra variable. Recorde
mos que una clase es, al fin y al cabo, la definicin de un nuevo tipo. Pues bien,
un
Suponiendo que ya hemos definido la clase Foo, ahora podramos crear un objeto
de ella del siguiente modo:
Foo miObjeto;
Pero esto no es suficiente! Si bien ya declaramos que miObjeto ser una variable de
tipo Foo, los objetos requieren ser definidos de manera explcita por medio del ope
rador new.
miObjeto = new Foo();
Ahora s, podremos acceder a todos los elementos del objeto. Tambin podramos
haber declarado y definido el objeto en la misma lnea:
Foo miObjeto = new Food;
usr.code
(
Veamos, ahora, cmo instanciar un par de objetos y acceder a variables de stos. Su
pongamos que nuestra clase Foo posee una variable a y otra b, ambas enteras.
Foo objl = new FooO;
Foo obj2 = new Foo();
objl.a a 10;
obj2.a a 20;
Console.WriteLine("Valor de la variable a del objeto objl: {0}", objl.a);
Console.WriteLine{"Valor de la variable a del objeto obj2: {O}", obj2.a);
Tanto objl como obj2 son instancias de la dase Foo; sin embargo, ambos objetos son
independientes entre s. Poseen la misma estructura, pero el valor dentro de sus va
riables puede ser totalmente diferente.
A continuacin, analicemos de qu manera hemos realizado la asignacin de valo
res a las variables de los objetos.
No podramos haber colocado slo el nombre de la variable, pues el compilador no
podra haber determinado a qu objeto nos estbamos refiriendo. Entonces, la sin
taxis correcta es colocar el nombre del objeto, el operador de seleccin (el punto),
la variable, el operador de asignacin y, finalmente, la expresin.
operador de
seleccin
operador de
' asignacin
miObjeto . a o 4 ;
J
U U
objeto
expresin
J
fin de
'sentencia
propiedad
87
PROGRAMACIN Ctt
C'idoS Foo
{
public coDBt int a 10;
//
...
>
Ahora a ya no es variable, sino constante, para todos los objetos del tipo Foo.
Ntese que hemos inicializado la constante en la misma lnea en que la declaramos.
Esto es algo obligatorio en este tipo de dato.
Pero, adems, tiene una caracterstica adicional: puede ser accedida o consultada sin
requerir instanciacin alguna, es decir, sin la necesidad de crear un objeto de Foo.
Por qu? Porque no tiene sentido almacenar en objetos valores que sern iguales
para todos ellos sin excepcin. Veamos, entonces, cmo acceder a una constante:
int b = Foo.a;
Como podemos apreciar en la lnea de cdigo anterior, creamos una variable tem
poral b y le asignamos el valor de la constante de la clase Foo. Ntese que no crea
mos un objeto de Foo, sino que utilizamos directamente el identificador de la clase
seguido del operador seleccin y la constante.
Variables estticas
Las variables estticas, al igual que las constantes, pueden ser accedidas sin la nece
sidad de instanciar un objeto. Sin embargo, su valor puede ser modificado como
cualquier otra variable. Podramos pensar en ellas como variables de clase, siendo
las variables tradicionales variables de objeto.
P | INICIAUZADORES
Cuando una variable se iniciaiiza en la misma lnea que su declaracin dentro del cuerpo de la
clase, se dice que posee un nicializador. Como vimos anteriormente, las constantes de una cla
se deben poseer un nicializador.
88
u s r .c o d e
Este tipo de variables, al igual que las constantes o las variables convencionales, pue
den poseer los mismos modificadores de acceso (public,
Para declarar una variable como esttica, bastar con agregarle el modificador static
como prefijo al tipo de dato.
class Foo
{
int a = 1;
const int b = 1;
static int e l ;
// Creo un objeto
= 10;
// Muestro el valor de c
// Accedo a su variable a
objl.a
Los mtodos
Las clases slo con variables y constantes no resultan demasiado interesantes. Tam
bin es posible declarar funciones dentro de una clase. Estas funciones (ms cono
cidas como mtodos) contienen el cdigo que ser ejecutado por nuestro programa
cuando stas sean invocadas.
Una funcin miembro o mtodo posee:
u s r .c o d e
89
PROGRAMACION C#
Parmetros: es una lista de variables que recibe el mtodo. Esta lista puede estar
vaca o poseer tantos elementos como queramos.
En la Figura 4 se puede apreciar un diagrama de sintaxis de la funcin. Cabe des
tacar que la funcin debe ser declarada dentro del cuerpo de una clase y puede po
seer modificadores que veremos ms adelante.
90
u s r .c o d e
{
public int valor;
// Imprime la variable valor
void ImprimirValor()
{
Console.WriteLine(valor);
}
// Mtodo principal del programa
static void Main(string(] args)
{
Foo obj = new Foo()j
obj.ImprimirValor();
}
}
Veamos: declaramos la variable miembro valor. Luego, declaramos el mtodo ImprimirValor, que simplemente enva a la consola de salida el valor de la variable del objeto.
Para invocar un mtodo en un programa, siendo ste un mtodo convencional de
objeto, deberemos anteponer su nombre y el operador de seleccin de miembros (el
punto); luego se deber colocar entre parntesis todos los parmetros que requiera
la funcin (si la funcin no recibe parmetros, simplemente se abren y se cierran los
parntesis). Tal y como hicimos en el ejemplo anterior dentro de la funcin
Main.
Mtodos estticos
As como las variables estticas pueden ser consideradas como variables de clase,
existen mtodos estticos que pueden ser considerados como mtodos
de clase. Es-
u s r .c o d e
91
PROGRAMACIN C#
too
mtodos deben poseer como prefijo al tipo de dato de retorno la palabra reser
vada static. Claro que stos tendrn algunas limitaciones: no podrn acceder a va
riables de objeto (es decir, variables no estticas) o mtodos de objetos (mtodos
convencionales no estticos).
El modo de invocar un mtodo esttico es por medio del identificador de la clase
en lugar del identificador del objeto (as como sucede con las variables estticas).
Muchas clases de la librera BOL definen mtodos estticos. Hemos estado utilizan
do el mtodo esttico WriteLine de la clase Consol. Ahora veamos cmo definir
nuestros propios mtodos estticos.
claaa Foo
{
//
...
{
Consol.Write("La fecha actual es: {0}\nn , DateTime.Now
);
{
Foo. ImprnirFechaActual ();
}
}
III
LA ESTRUCTURA DATETIME
El manejo de fechas sola ser un problema en muchos lenguajes. Especialmente cuando deba
mos interactuar con otros programas o bases de datos, ya que el formato de almacenamiento de
stas era distinto. Pero la librera BCL ofrece una estructura llamada DateTime que simplifica el
manejo y unifica el almacenamiento de este tipo de datos para todas las plataformas.
92
u s r .c o d e
Luego, es conveniente notar el modo en que invocamos la funcin dentro de Main: uti
lizamos el nombre de la clase, no tuvimos la necesidad de instanciar ningn objeto.
Retornar valores
Hemos mencionado que los mtodos pueden retornar valores o no. Si no devuel
ven ningn valor, simplemente se especifica que el tipo de dato de retorno sea void.
Veremos cmo declarar y utilizar un mtodo cuando ste devuelve un valor entero:
class Foo
<
{
return valor * valor;
}
/ / ------------------// Mtodo principal del programa
atatic void MaintetringU args)
Foo obj = new Foo();
obj .valor o 9;
Consol.WriteLine(,'gl valor del objeto objl al cuadrado
es: {O}", obj.ValorAlCuadradoO);
Utilizar parmetros
La declaracin de parmetros en las funciones se realiza de modo muy sencillo.
Bsicamente, son declaraciones de variables (del modo en el que nos estamos
acostumbrando a realizarlas) separadas por el carcter coma (necesario si es que
hay ms de un parmetro).
u s r .c o d e
93
PROGRAMACIN Ctt
{
prvate int valor;
bool FijarValor(int
val)
{
if (_val >= 0 && _val < 10)
{
valor
val;
return trae;
}
elae
return falsa;
}
int DaaeValorO
{
return valor;
{
Foo ob j =new Foo ();
obj, FijarValor (55);
Consol.WriteLine("El valor es {0}", obj.DameValorf));
obj.FijarValor(5);
Consol.WriteLine("El valor es {0}", obj.DameValorO);
}
}
En el ejemplo anterior, lo que deseamos hacer es acceder a una variable privada por me
dio de dos mtodos: uno que fija el valor a la variable y otro que la retorna. Muchas ve
ces esta funcionalidad es deseada para realizar una verificacin del upo de dato fijado a
la variable. Normalmente todas las variables miembro son privadas y se accede a ellas
por medio de mtodos de este tipo o a travs de una funcionalidad especial que posee
el lenguaje C#, que se denomina propiedades y que luego trataremos en detalle.
94
u s r .c o d e
FijarValor
que nadie nos obliga a hacer uso del valor de retorno de una funcin. Lo negativo
de nuestro accionar es que no tendremos certeza si el valor es fijado satisfactoria
mente por el mtodo, pues no nos encontramos de alertas a la informacin que nos
brinda con respecto a esto.
Posteriormente, veamos que el valor de retorno de la funcin
mos directamente como parmetro de la funcin
WriteLine;
DameValor lo utiliza
{
public static void IntentarModificarValor (int iValor)
{
iValor = 10;
}
}
99;
Foo. IntentarModificarValor(num
);
Consol.Write(num) ;
num,
IntentarModificarValor
95
PROGRAMACIN C#
96
u s r .c o d e
{
public static void IntentarModificarValor (ref int iValor)
{
iValor = 10?
}
}
III
QU ES UNA REFERENCIA?
Una referencia es bsicamente una variable que contiene la direccin de memoria de otra varia
ble pero que oculta esta naturaleza. Por lo tanto su manipulacin es prcticamente idntica a la
de cualquier otra variable.
u s r .c o d e
97
PROGRAMACION CS
98
u s r .c o d e
Parmetros de salida
Qu sucede si necesitamos que nuestra funcin devuelva ms de un valor? Existen
varias alternativas. Es posible especificar que ciertos parmetros sean parmetros de
salida exclusivamente por medio del modificador out.
Supongamos que estamos creando una clase con funciones matemticas, algo as co
mo la clase Math. Deseamos crear un mtodo que devuelva el seno y el coseno de
un nmero pasado como parmetro.
Siendo sta la situacin, podramos retornar el seno como parmetro y el coseno co
mo valor de la funcin, o al revs, o incluso podramos devolver el resultado de am
bas operaciones en parmetros. Veamos:
class HiClaseDeMatemtica
{
public static void SinCos(double dValor, out doubla dSn, out
double dCo3)
{
dSin = Math.Sin(dValor);
dCos = Math.Cos(dValor);
}
}
u s r .c o d e
99
PROGRAMACIN C#
Sin-
2.
SinCos es esttico.
3. Anteponemos a las variables dCoseno y dSeno la palabra reservada out.
4. Finalmente, imprimimos los valores retornados en parmetros.
De lo expuesto, hay dos cosas importantes que es conveniente destacar:
La funcin deber otorgar valores a todos los parmetros de salida en cualquier
caso (dicho de otro modo: ningn camino de ejecucin puede terminar la fun
cin sin al menos inicializar los parmetros de salida en algn valor).
La funcin
El mtodo constructor
Qu ocurre si deseamos realizar cierta accin no bien el objeto es creado? Debe
ramos anunciarles a todos los programadores de nuestro equipo que recuerden in
vocar un mtodo arbitrario luego de crear el objeto en cuestin? Por suerte, no.
Existe un mtodo especial que es invocado cada vez que un objeto nuevo es creado
de forma automtica.
Dicho mtodo se denomina constructor, y su identificador debe ser exactamente el
mismo que el de la clase de la cual forma parte. Veamos un ejemplo:
using System;
class Foo
Foo (}
{
Consola.WriteLine("El mtodo constructor");
{
Poo = new Foo();
}
}
100
u s r .c o d e
po
see tipo de dato de retorno. Esto es lgico, pues los constructores no se invocan
como mtodos convencionales, sino que son invocados automticamente por el framework cuando se crean los objetos.
Aprovechando las caractersticas de polimorfismo que posee este lenguaje y en los que
profundizaremos ms adelante, es posible crear ms de un constructor, cada uno con
diferente cantidad de parmetros o con distintos tipos como parmetros. De este mo
do es posible crear un objeto al mismo tiempo que se le transfiere un parmetro.
clase Vector2
{
float x = O.Of;
float y a O.Of;
Vector2()
{
Consol.WriteLine("El mtodo constructor sin parmetros");
}
Vector2(float
x, float
y)
{
x =
x;
y * _y;
Consol.WriteLine("El mtodo constructor con dos
parmetros float");
}
void MostrarValor ()
{
Consol.WriteLine(*({0}, {l})", x, y);
}
/ / ------------------// Mtodo principal del programa
static void Main (string (] args)
{
Vector2 vecA = new Vector2();
vecA.MostrarValor();
Vector2 vecB = new Vector2(5.0f, 10.Of);
vecB.MostrarValor();
}
}
u s r .c o d e
101
PROGRAMACIN C#
las variables locales!) son inicializadas a cero cuando son creadas, no est de ms
recordar que esto es posible. Dentro del cuerpo de la funcin Main creamos dos ob
jetos de los dos modos posibles: invocando el constructor sin parmetros e invocan
do el constructor con dos parmetros.
Luego creamos un mtodo llamado
do del objeto. Este mtodo lo utilizamos para ver en qu valor estn las variables de
cada objeto inmediatamente despus de construir el objeto.
C-
KT
Vector2(Vector2 copiarDesde)
{
x copiarDesde.x;
y = copiarDesde.y;
Console.WriteLine("El mtodo constructor de copia*);
INVOCACIN DE CONSTRUCTORES
Es posible que un constructor invoque otro constructor. Esto suele realizarse cuando parte de a
tarea de inicializacin es comn a todos los constructores; no tendra ningn sentido duplicar c
digo. Simplemente se llama el constructor correspondiente -desde el otro constructor-, como si
fuese un mtodo convencional.
102
u s r .c o d e
vecA.Mo8trarValor ();
Vector2 vecC = new Vector2(vecA);
vecC = vecA; //' Nocoooccc!
.
.v" V .
'
TiV ^ * . ''-.A % ,
. '*
Para entender qu est mal con la ultima lnea, hay que ahondar en el aspecto te
rico de los objetos y cmo los maneja el lenguaje C#.
Al comienzo del Captulo 2 mencionbamos que existen dos tipos de datos distin
tos para el lenguaje: los manejados por valor y los manejados por referencia.
Los tipos de datos primitivos son manejados por valor, mientras que los objetos
(instancias de clases) son manejados por referencias.
Entonces vecA,
int num 1;
numl - 50;
float num2;
u s r .c o d e
! stack
numl
50
num2
no definido
103
PROGRAMACIN C#
num2 =98.5f;
! stack
numl
50
num2
98.5f
Vector2 vecA;
stack
numl
50
num2
98.5f
vecA
no definido
-------------- L
i
vecA =newVector2();
T-------------
| stack
numl
50
num2
98.5f
vecA
referencia vecA f
vecC
referencia vecC
1---
i heap
,J1
objeto vecA
r^fetO VdcC
j.
vecC =vecA;
' stack
numl
50
num2
98.5
vccA
referencia vecA
vecC
referencia vecA
104
u s r .c o d e
el funcionamiento es el esperado.
Luego, podemos apreciar que los objetos, al ser manejados como referencias, poseen
un comportamiento diferente. En primer lugar, el objeto en s es creado en otra zo
Finalmente, si asignamos el objeto vecA al objeto vecC, lo que haremos ser copiar
la referencia y no el contenido del objeto. Esto podra no ser lo que esperbamos.
Por lo tanto, el modo correcto de copiar un objeto sobre otro ser utilizando un
constructor de copia (los programadores avanzados de otros lenguajes podran pen
sar que tambin sera posible sobrecargar el operador de asignacin, pero en C# es
te operador en particular no es sobrecargable).
Destruccin de objetos
Un objeto se crea cuando solicitamos memoria para l por medio del operador new,
momento en el cual se invoca el mtodo constructor que corresponda.
El objeto poseer un
ciclo de vida.
III
El mtodo ms sencillo -aunque no tan preciso- de averiguarlo ser mirando el proceso que
corresponda a nuestra aplicacin desde el Administrador de tareas.
u s r .c o d e
105
PROGRAMACIN C#
objeto vecC queda aislada, es decir que se pierde toda referencia a ella. En un len
guaje como C++ esto generara un mcmory leak, y dicha zona de memoria quedara
reservada hasta que finalmente el programa terminara y el sistema operativo recu
perara toda la memoria que estaba usando.
En cambio, C#, gracias a su recolector de basura, advertir esta situacin y recupe
rar dicha memoria para dejarla nuevamente disponible a nuestro programa. Pero
cuando ocurrir estol
En el lenguaje de programacin C# no existe el operador contrario a new (como s
existe en C++, donde dicho operador se denomina delete). La destruccin de un ob
jeto no es un proceso determinstico, es decir que no podremos controlar exacta
...
106
u s r .c o d e
Los
<
moria, es muy comn olvidarse de destruir los objetos que ya no son utilizados,
lo que genera memory
Los
leaks.
objetos sean destruidos slo una vez. Un error muy comn en C++ es eli-
canzables) es una tarea que consume recursos, por lo tanto slo debe realizarse
cuando es imperioso.
i i ...
~Vector2()
{
//' Cdigo de desinicializacin
// ...
Consol.WriteLine("Destructor");
'
>
.//
...
107
'
PROGRAMACIN CU
{
//
...
{
// Desasigne recursos
...
Console.WriteLine("Dispose");
GC.SupressFinalize(this);
}
}
108
u s r .c o d e
E s tru c tu ra s
//
C o n s tr u im o s e l
o b je to
...
/ / D e s a s ig n a m o s r e c u r s o s
vecA.DispoeeO ;
Entonces, ahora invocando este mtodo arbitrario podremos estar seguros de cun
do
todos los recursos que eran necesarios, por favor, no invoques mi mtodo des
tructor. Cuando llegue el momento, el recolector de basura eliminar nuestro obje
to del hcap sin invocar nuestro destructor previamente, por expreso pedido nuestro.
ESTRUCTURAS
Una estructura es un tipo de dato muy similar a una clase. Es una alternativa livia
na a stas y puede contener prcticamente todos los elementos que puede poseer la
clase, como variables, mtodos, propiedades, constantes, etc.
La diferencia principal que posee la estructura respecro a la clase es que Ja estructu
ra es un tipo de dato manejado por valor, a diferencia de la clase, que es maneja
da por referencia. Esta simple distincin repercute en muchos aspectos de uso que
ya analizaremos; por ahora veamos cmo declarar una de ellas recreando la idea del
{
float x;
float y;
public Vector3(float _x, float _y)
u E T .co d e
109
PROGRAMACIN CU
{
x c
x;
y _y;
}
void MostrarValorO
{
Consol.WriteLine(*({0}, {l})",
x,
y);
}
}
Como podemos apreciar en el listado anterior, lo nico que parece haber cambiado
es la palabra clave class por struct. Sin embargo, existen otras diferencias ms pro
fundas, como:
No es vlido inicializar las variables en la misma lnea que su declaracin (ntese
que los inicializadores estn ahora ausentes).
No es posible especificar constructores sin parmetros (ntese que hemos elimi
nado dicho constructor).
No es posible especificar destructores para ellas.
No es posible practicar herencia con ellas. Todas las estructuras son derivadas de
la clase Object (como rodo tipo de dato de C#) de manera fija, no es posible espe
cificar que derive de ninguna orra clase, y ninguna clase puede derivar de una es
tructura (en el prximo captulo ya veremos con detenimiento qu es la herencia).
Y ahora veamos diferencias en su utilizacin:
Vector3 vecA;
vecA.x = 10.Of;
vecA.y = 20.Of;
vecA.MoBtrarValor();
heap.
..c o r ie
E s tru c tu ra s
Cabe destacar que, para poder utilizar una estructura, es necesario previamente asig
narles valor a todas sus propiedades; de otro modo, el compilador arrojar un error.
Tambin es posible hacer uso del operador new con la estructura, en especial si de
seamos invocar algn constructor en particular. Todos los constructores deben pro
veer de valor a todas las variables de la estructura. Si no especificamos constructor,
existe un constructor implcito predeterminado que inicializa todas las variables
(pero es invocado slo si utilizamos el operador new). Por lo tanto, tambin podra
haber sido vlido especificar:
Vector3 vecA = new Vector3{10.0f, 20.Of);
vecA.HostrarValorO;
Utilizar el operador new no significa que la variable vecA sea un objeto ni que la me
moria sea tomada del
en el stack, siempre.
Por lo tanto, cuando hacemos uso de un tipo de dato de una librera, es importan
te saber si dicho tipo es una clase o una estructura, porque, en caso contrario, po
dremos cometer errores.
RESUMEN
u s r .c o d e
111
ACTIVIDADES
TEST DE AUTOEVALUACIN
1 Dnde
guientes listados?
m_iValor = iValor;
r e tum true;
a)
}
}
class Foo
{
const int a;
int b;
int c;
2 Es
acceder:
una variable de tipo entero no esttica?
class Foo
{
public int miValor;
// Imprime la variable m_ iValor
static void ImprimirValor()
{
Consol.Write(m_iValor);
}
6 Es posible destruir un objeto de manera
explcita?
c)
class Foc
i
prvate int miValor;
bool FijarValor(int iValcr!
112
.c o d e
Captulo
PROGRAMACION C#
Encapsulamiento.
herencia
y polimorfismo
Aqu veremos los conceptos
fundam entales de la programacin
orientada a objetos y de qu modo
C -tt
qu es el polim orfism o y qu
caractersticas de ste ofrece C#,
como los metoo s virtuales, las interfaces
V IriS t I d S t r : dt.'S tr
actas.
le c t o r e s @ m p e c lic io n e s .c o ii]
114
Uso de los modificadores
de acceso
122
Las propiedades
123
Invocar constructores
128
Invocar destructores
132
Composicin
133
Composicin Irente a herencia 135
13/
Polimorfismo
37
Sobrecarga de mtodos
Sobrecarga de operadores
Ki
Mtodos virtuales
145
Interfaces
153
154
Clases abstractas
Resumen
155
Actividades
156
PROGRAMACIN CU
HERENCIA
La herencia es un concepto fundamental de la programacin orientada a objetos.
Por medio de esta caracterstica podremos definir nuestras clases a partir de otras,
ms generales, y slo agregar las propiedades y mtodos de la especializacin.
Debido a que nuestro sistema ser una coleccin de clases relacionadas entre s, es
muy importante el modo en que estar conformada su estructura. Un diseo po
bre, por lo general, genera ms problemas que soluciones, ya que los errores se pro
pagan rpidamente, y su expansin y mantenimiento se dificultan.
C#, como un buen lenguaje del paradigma de programacin orientada a objetos,
soporta herencia. Veamos cmo podramos definir dos clases, una derivada de la
otra, con un ejemplo minimalista:
class A
{
}
class B : A
; } -
Hemos declarado la clase A como una clase convencional (as como lo venamos ha
ciendo). La clase B posee, seguido de su identificador, el carcter dos puntos (:) y,
luego, el identificador de la clase de la cual deriva. Qu significa esto? La clase B
heredar los mtodos y las variables pblicas, protegidas e internas de A.
Y de qu modo podra beneficiarnos esta caracterstica? Bueno, si el diseo de
nuestro programa es correcto, entonces escribiremos una cantidad de cdigo me
nor, adems de mejorar la reusabilidad de nuestros componentes y facilitar el man
tenimiento de todo el sistema.
H H TERMINOLOGA DE LA HERENCIA
Si la clase B hereda de la clase A, entonces B es una clase hija o derivada de A, mientras que A
es la clase padre de B. Tambin se suelen emplear los trminos subclase (B es una subclase de
A) y superclase (A es una superclase de B).
114
u s r.c o d e
Herencia
{
// --------------// Variables
protected int caballoaDeFuerza;
protected int cantidadPuertas;
// -------------------------// Mtodos
public void Arrancar()
{
System.Consol.WriteLine('Clase Automvil, Mtodo Arrancar");
public void Detener()
System.Consol.WriteLine("Clase Automvil, Mtodo Detener*);
public void AbrirFuerta(int puertaHum)
System.Consol.WriteLine("Clase Automvil, Mtodo AbrirPuerta");
public void CerrarPuerta(int puertaNum)
System.Consol.WriteLine("Clase Automvil, Mtodo CerrarPuerta");
I -------------------------// Variables
uii.c o d e
11
PROGRAMACIN C#
// -------------// Mtodos
public void Arrancar(]
{
System.Consol,WriteLine{
Clase PalaMecanica, Mtodo Arrancar");
}
public void Detener!)
{
System.Consol.WriteLine("Clase PalaMecanica, Mtodo Detener*);
}
public void LevantarPalaO
{
System.Consol.WriteLine("Clase PalaMecanica,
Mtodo LevantarPala*) ;
}
public void BajarPalaO
{
System.Consol.WriteLine("Clase PalaMecanica, Mtodo BajarPala");
}
}
Como puede verse en los listados anteriores, algunos mtodos y variables son co
munes a ambas clases; pero como no utilizamos herencia, tuvimos que rescribirlos.
En la Figura 1 se puede observar un esquema de las clases descritas, que no poseen
relacin alguna entre s. El diagrama de clases es uno de los diagramas UM L, del
cual se puede apreciar una introduccin en el Apndice D.
Automvil
PalaMecanica
#cabaliosDeFuerza: int
tfcantidadPuertas: ini
#caballosDeFuerza: int
#pesoMaximoDeLevante: int
+Arrancar{): void
+0etener(): void
+AbrirPuerta(): void
+CerrarPuerta(): void
+Arrancar(): void
+Detener(): void
+LevantarPala(): void
+BajarPala ( ) : void
116
u s r .c o d e
Herencia
Si, en cambio, creramos una clase llamada Vehculo que ruvicsc las variables y los
mtodos comunes a ambas clases, luego Automvil y PalaMecanica slo deberan
agregar los mtodos especficos del tipo de vehculo que representan. Entonces, la
cantidad de cdigo escrito sera sensiblemente menor. Tambin, en el caso de exis
tir un error en el mtodo Arrancar, slo deberamos modificar el cdigo de una cla
se y no de dos. En definitiva, estaramos ante un diseo mis elegante. Veamos:
/ / -------------------------// Variables
// c
:-----------------
// Mtodos
{
System.Consola.WriteLine{"Clase Vehculo, Mtodo Arrancar");
>
'
{
System.Consol.WriteLine1"Clase Vehculo, Mtodo Detener");
}
}
// -------------------------// Variables
// --------------// Mtodos
{
System.Consol.WriteLine!"Clase Automvil, Mtodo AbrirPuerta");
u s r .c o d e
117
PROGRAMACIN CE
{
System.Consol.WriteLine("Clase Automvil, Mtodo CerrarPuerta*);
}
}
{
.// --------------// Variables
// -------------------------// Mtodos
{
System.Consol.WriteLine("Clase PalaMecanica,
Mtodo LevantarPala") ;
"
.} '
-jjV '
' Vv-'l
>'
{
System.Consol.WriteLine("Clase PalaMecanica, Mtodo BajarPala");
}
}
Como se puede apreciar en los listados anteriores, ahora las clases Automvil y Pala
por lo tanto todas las variables, mtodos y pro
piedades que no sean privadas sern heredadas, y entonces podrn ser accedidas des
de objetos de Automvil o PalaMecanica como si hubiesen sido declaradas all mismo.
IJ H LA CLASE OBJECT
D e c ir que n u e s tra s c la s e s no h ac en uso de h e re n c ia no es d el todo p re ciso . Todo c la s e s e r una
I1 t
is r .c o d e
Herencia
Ntese que existe una flecha grande desde las clases Automvil y PalaMecanica hacia
esta relacin expresa generalizacin y es uno de los smbolos caractersti
Vehculo;
DE NUEVO NEW?
-
iXV
,.. *;...
Ya usamos el operador new para solicitar memoria al sistema. Adems posee otro uso. Al defi
nir un mtodo (no virtual) en una subclase de una clase que contiene el mismo mtodo, debere
mos indicar que deseamos crear una versin nueva de l. No hacerlo no producir un error, si
no una advertencia. Esta regla evita que se sobrescriba un mtodo de una clase padre por error.
(
u s r .c o d e
119
PROGRAMACIN C
ti
lido invocarlo desde cualquier objeto del tipo Automvil como si hubiese estado de
clarado en l. Lo mismo ocurre con objetos del tipo PalaMecanica:
PalaMecanica unaPala = na* PalaMecanlcaO}
unaPala.Arrancar();
Ciertamente, un automvil y una pala mecnica poseen un motor que debe ser en
cendido. La representacin de estas entidades en nuestro sistema podra llevar a que
las implementaciones de los mtodos Arrancar y Detener fueran las mismas, pero tal
vez podra existir el caso en que algunas de ellas o todas deberan ejecutar distintos
trozos de cdigo. En estos casos es perfectamente vlido rescribir los mtodos en las
clases derivadas. Veamos.
La clase Vehculo posee un mtodo llamado Arrancar, que probablemente conten
ga el cdigo necesario para el encendido de cualquier vehculo genrico. La invo
cacin de dicho mtodo (por medio de objetos de subclases) provocara su ejecu
cin. Sin embargo, si definiramos un mtodo Arrancar en la clase Automvil (de
jando intacta la clase Vehculo), entonces existiran dos mtodos Arrancar. Cul
de ellos sera el mtodo invocado? Desde un objeto del tipo Automvil se invoca
ra el mtodo de la clase Automvil, y desde un objeto del tipo Vehculo se invo
cara el mtodo de la clase Vehculo.
clase Vehculo
{
public
void
Arrancar {)
{
SyBtem.Console.WriteLine("Clase Vehculo, Mtodo Arrancar17);
}
}
clasa Automvil : Vehculo
{
public new void Arrancar()
{
System.Console.WriteLine ("Clase Automvil, Mtodo Arrancar'7);
}
}
120
usr.code
Herencia
car de la clase Vehculo, ya que las tareas realizadas en dicha clase de otro modo que
daran ocultas y no seran ejecutadas (adems de que es lgico que parte del proce
so de encendido de un automvil sea comn al de cualquier vehculo). Para esto de
beramos agregar la siguiente lnea de cdigo:
claas Automvil : Vehculo
{
public new void Arrancar{)
{
base.Arrancar!)
Base
Arrancar,
(idealmente,
de la pila
u s r .c o d e
121
PROGRAMACIN C#
{
public void Arramcarf)
{
// ;Se invocar el mismo mtodo una y otra vez hasta
producir un error!
Arrancar () ;
System.Consol.WriteLinef
Clase Automvil, Mtodo Arrancar");
}
}
As como la lnea:
Automvil unAuto = new Automvil();
unAuto,caballosDeFuerza
420;
[ I QU ES UN ASSEMBLY?
Un sistema siempre debe estar compuesto por uno o ms assemblies. Un assembly puede ser
un archivo ejecutable o una librera de enlace dinmico, que puede poseer cdigo ejecutable y/o
recursos (como bitmaps, iconos o cualquier tipo de dato). Cada assembly posee un manifest que
describe su contenido e informa de otras propiedades como su nombre, versin, etc.
122
u s r .c o d e
Herencia
Automvil y PalaMecanica
bra sido as si hubiese sido declarada como privada). El cuadro que se encuentra a
continuacin aclara un poco esta situacin:
prvate
no
no
no
no
protected
no
no
public_ _ _ _ _ _ _ _ _ _ _ _ _ s_ _ _ _ _ _ _ _ _ _ _ _ s_ _ _ _ _ _ _ _ _ _ _ _ s_ _ _ _ _ _ _ _ _ _ _ s_ _ _ _ _ _ _ _ _ _ _ _ si
Tabla 1. Modificadores de acceso.
Las propiedades
En lenguajes como el C++, si deseamos permitir que se modifique una propiedad
de modo externo a la clase, poseemos dos alternativas:
Declarar la variable como pblica. Entonces, desde cualquier parte del progra
ma se podr leer y escribir dicha variable sin inconvenientes. El problema de esta
solucin es que no podremos especificar una variable como de slo lectura o slo
escritura; si sta es pblica, siempre podr ser leda y escrita sin excepcin. Por
otro lado, no podremos reaccionar ante la lectura o escritura de alguna variable
en particular, ya sea para modificar otros valores en cascada, comprobar rangos o
validez de la informacin especificada, etc.
u s r .c o d e
123
PROGRAMACIN C#
Get).
LeerCantidad (claro que esto de anteponer Fijar y Leer es simplemente una conven
cin arbitraria). Veamos:
clase Foo
{
protected int cantidad;
public void FijarCantidad(int valor)
{
cantidad = valor;
}
public int LeerCantidad()
{
return cantidad;
}
}
que
objeto.mtodo(valor);
Sobre todo, cuando debemos acceder a variables de objetos que se encuentran den
tro de otros objetos, con lo que en el primer caso quedar:
124
u s r .c o d e
Herencia
objeto.objeto.objeto.variable = valor;
y en el segundo caso:
objeto.mtodoO.mtodoO.mtodo(valer);
{
protected int cantidad;
public int Cantidad
1
get
r e t u m cantidad;
}
set
{
cantidad = valu;
1
}
}
125
PROGRAMACIN C
tipo de dato
modificador
de acceso
public
identificador
int
Cantidad
{
get
<
Mtodo de
acceso get
!
I
v-V-
.- |
;
set
Mtodo de
acceso set
{
}
>
set
FijarCantidad
Cabe destacar que podremos especificar el get y el set o slo uno de ellos (si es que deseamos
que nuestra variable sea de slo lectura o de slo escritura), pero al menos uno debe estar de
clarado, o se producir un error de compilacin.
126
u s r .c o d e
Herencia
u s r .c o d e
127
PROGRAMACIN Ctt
INVOCAR CONSTRUCTORES
Sabemos que cuando construimos un nuevo objeto se ejecuta el cdigo del mtodo
constructor. Dicho constructor puede existir de manera explcita (cuando lo defini
mos) o de manera implcita (cuando no lo definimos).
Pero qu es lo que sucede cuando nuestra clase est definida a partir de otra? Qu
constructor se invoca? Para responder estas preguntas, pasemos a analizar con
detenimiento el siguiente ejemplo:
Poseemos tres clases:
128
A()
u s r.c o d e
Invocar constructores
{
Consol.WriteLine("Constructor A");
}
}
class B : A
{
B()
{
Consola.WriteLine("Constructor B*);
}
}
class C : B
{
C()
{
Consol.WriteLine("Constructor C");
}
static void Main(string[} args)
}
}
Esto que observamos es lgico, debido a que el objeto C, en el momento de ser cons
truido, debera tener la posibilidad de contar con todas las variables y propiedades
de sus superclases debidamente inicializadas (esto, en un gran nmero de ocasiones,
podra significar abrir archivos o canales hacia otros dispositivos de hardware), y as
realizar su propia inicializacin.
Y que ocurrira si deseramos invocar un constructor con parmetro en alguna cla
se padre? Veamos el siguiente ejemplo:
u s r .c o d e
129
PROGRAMACIN CS
Clasa B : A
{
B()
{
Consola.Writeiinot
Coiistruetor B"!;
}
B(int num)
{
Console.WriteLine("Constructor B con parmetro
entero; 0}*, num);
}
}
Ahora nuestra clase B cuenca con dos constructores; lino de ellos recibe un parme
tro que es una variable del tipo entero.
"Pero en el caso de que volvamos a ejecutar nuestro programa, el constructor de la
clase C seguir ejecutando el constructor sin parmetros de B. Cmo hacemos pa
ra cambiar este comportamiento?
claas C : B
{
CO
: baseII)
{
Consol.SritaLinePConatructor C!;
}
// ...
}
130
u s r .c o d e
invocar constructores
Tambin cambiamos el modo de construir un objeto del tipo C, para que se invo
que el constructor con parmetro entero y no el constructor sin parmetros.
u s r .c o d e
131
PROGRAMACIN C#
INVOCAR DESTRUCTORES
En el momento en que un objeto es destruido, los destructores tambin son invoca
dos en un orden preestablecido, que, como es de esperar, es inverso al ordenamien
to que siguen los constructores.
class A
{
A ()
{
Con8ole.KriteLi.ne('Constructor A*);
}
-A()
{
Consol.KriteLine("Destructor A");
}
; }
class B : A
{
BO
{
Consol.WriteLine("Constructor B");
}
-BO
{
Consol.WriteLine("Destructor B*);
}
}
class C : B
1 3
DESTRUCCION DE OBJETOS
132
u s r .c o d e
Com posicin
C()
{
Consol.WriteLine('Constructor C*)j
-C{)
{
Consola.WriteLine("Destructor C");
}
static void Main (string [} args)
{
C obj a new C();
}
COMPOSICIN
Una clase puede tener como miembro cualquier tipo de variable, sin importar que
sea de algn tipo fundamental o definido por el usuario; esto tambin incluye otros
objetos definidos previamente.
Por tal motivo, en un sistema ser bastante frecuente que los objetos se encuentren
compuestos por otros objetos. Veamos un ejemplo trivial.
u s r .c o d e
133
PROGRAMACIN C#
class A
| {
public void ml{)
{
Consol.WriteLina("Clase A, mtodo Foo);
}
// . . .
}
class B
{
public A objA a new A();
//
'
...
'*
De este modo, si el objeto del tipo A contuviera, a su vez, otros objetos, podramos
acceder a ellos simplemente anteponiendo el operador de seleccin de miembros,
siempre y cuando stos fueran pblicos.
1 34
u s r .c o d e
{
public int vari;
public int var2;
public int var3;
vari
var2
var3
{
public int var;
public int var5;
Cuando instanciemos un objeto del tipo B, el mapa de memoria para ste ser:
objB
vari
var2
var3
var4
var5
(en este caso, slo una, sin contar la clase Object, que, de todos modos, no posee va
riables) ms las definidas por l.
u s r .c o d e
135
PROGRAMACIN C*
Por lo tanto, un objeto del tipo B podr acceder a elementos de B y a elementos (he
redados) de A. Podramos haber obtenido un resultado similar utilizando composi
cin. Veamos:
La clase A permanecera sin cambio alguno. Sin embargo, la clase B ya no sera una
subclase de A, sino que poseer otra variable ms, que sera un objeto del tipo A:
class B
{
public A objA = new A();
public int var4;
public int var5;
}
objB
objA
vari
var2
var3
var4
var5
El mapa de memoria es muy similar; el objeto, en definitiva, ocupar el mismo es
pacio en memoria. Cul es la diferencia, entonces?
Usualmente elegimos utilizar herencia cuando deseamos incorporar a nuestra clase las
variables, propiedades y mtodos del objeto seleccionado, o cuando deseamos especia
lizar una clase determinada agregando caractersticas de una entidad especfica que es
tamos modelando, tomando como base una clase del mismo tipo, pero ms general.
En cambio, decidimos utilizar la composicin cuando deseamos ocultar, encapsular, el objeto seleccionado bajo la nueva interfaz.
Por lo tanto, ms all de algunas similitudes tcnicas, conceptualmente la herencia
y la composicin se encuentran bien diferenciadas.
136
u s r .c o d e
Polim orfismo
POLIMORFISMO
El polimorfismo es la habilidad que poseen los objetos para reaccionar de modo di
ferente ante los mismos mensajes. Un objeto del tipo Puerta, al igual que un obje
to del tipo Ventana, podr recibir el mensaje Abrir; sin embargo, cada uno de ellos
reaccionar de modo diferente.
En C#, el polimorfismo se encuentra ntimamente relacionado con el mecanismo
de sobrecarga y con los mtodos virtuales. Veamos.
Sobrecarga de mtodos
En lenguajes como el C, es comn encontrar libreras que poseen grupos de funcio
nes que realizan la misma tarca, pero con distintos tipos de datos en los parmetros.
De esta manera, si la tarea consiste en mostrar en pantalla el dato pasado como pa
rmetro, nos podremos encontrar con casos como el siguiente:
void Imprimirlnt(int num);
void ImprmirChar(char car);
void ImprimirFloat(float num);
137
PROGRAMACIN C#
{
// Error: Los mtodos slo difieren en el tipo
// de datos retomado.static Lool Fooiint num);
static bool Foo (Int num);
static cbar Foo(int num);
{
public float X o O.Of;
public float Y = O.Of;
Vector2()
{
}
Vector2(float
_x,
float _y)
{
X = _x;
Y = _y;
}
}
138
u s r .c o d e
Polimorfismo
Debido a que todo el rango de florantes es aceptado por nuestro vector para sus
componentes y a que no debemos disparar ninguna accin relacionada con la lec
tura o escritura de stos, entonces las variables miembro las especificaremos con
modificador de acceso public.
Agregaremos ahora algunos mtodos tiles para la manipulacin de vectores:
public double ProductoPunto(Vector2 vec2)
{
return X*vec2.X + Y*vec2.Y;
}
public double ProductoPunto(float _x, float
y)
{
return X*_x + Y*_y;
{
X = X + vec2.X;
Y = Y + vec2.Y;
}
public void Sumar(float
x, float _y)
Q Q PARMETROS OPCIONALES
C# no soporta la declaracin de parmetros opcionales, asi como lo hacen C++ o Visual Basic
Para conseguir el mismo objetivo, habr que crear dos mtodos distintos sobrecargados con di
ferencia en cantidad de parmetros.
u s r .c o d e
139
PROGRAMACIN C#
X * X + Jt;
Y => Y y;
}
static public Vector2 Sumar(Vector2 vacl, Vector2 vec2)
{
return new Vector2(vecl.X + vec2.X, vecl.Y + vec2.Y)j
:>
La primera versin dei mtodo suma un vector pasado como parmetro al vector
del objeto y almacena el resultado sobre s mismo. La segunda versin hace lo mis
mo, pero recibe los parmetros como elementos.
En ltimo lugar, la tercera versin del mtodo es esttica y no requiere la existencia
de un objeto, simplemente suma dos vectores y devuelve el resultado de la opera
cin como valor de la funcin.
' '
// ...
'
}
otatic public void Foo (int num)
{
//
...
140
u s r .c o d e
Polim orfismo
Sobrecarga de operadores
Sera mucho ms prctico poder hacer la suma de dos vectores utilizando el opera
dor de suma (+), en particular la ltima versin del mtodo Sumar. De otro modo,
as como estamos ahora, deberamos escribir:
vec3 = Vector2.Sumar(vecl, vec2);
Pero cmo podra saber el lenguaje cmo debe manipular dos vectores de dos di
mensiones en una suma? O, eventualmente, cmo podra saber cmo sumar dos
objetos definidos arbitrariamente por nosotros? C# permite sobrecargar operado
res, es decir, redefinir el significado de un conjunto de operadores cuando se uti
lizan con ciertos objetos.
Esta sobrecarga devendr en uu mtodo convencional pero declarado de un modo
especial, por lo que termina siendo, al fin y al cabo, una modificacin a la esttica
de nuestro cdigo.
Veamos cmo sobrecargar el operador +:
static public Vector2 operator+ (Vector2 vecl, Vector2 vec2)
{
return new Vector2(vecl.X + vec2.X, vecl.Y + vec2.Y);
( 3 OPERADORES SOBRECARGABLES
No todos los operadores pueden ser sobrecargados! En este mismo captulo podremos encon
trar una lista de los operadores que podremos sobrecargar en el lenguaje C#.
u s r .c o d e
141
PROGRAMACIN C#
Sin embargo, de rodos los operadores con los que cuenta C#, no todos son sobre
cargares. En la siguiente tabla podemos apreciar qu operadores pueden ser sobre
cargados y el tipo al cual pertenecen:
1 42
u s r .c o d e
Polimorfismo
OPERADORES
DESCRIPCIN
I TIPODEOPERADOR
Unarios
Negacin aritmtica
Binarios
Negacin lgica
Negacin bitwise
&
Y bitwise
I
++
0 bitwise
Incremento
Decremento
true
Verdadero
false
Falso
Suma
Resta
ii*.
,y;.-
-*
* TV le '':* > r
Mtfltipbcatin
Divisin
telo
&
Y bitwise
0 bitwise
0 exciusarobitvrise
Desplazamiento 3izquierda
Igualdad
Desplazamientoa derecha
g ->
Relacinales
1-
Desigualdad
<
Menor
>
Mayor
Menor o igual
>
Mayor o Igual
<
'
}
}
u s r .c o d e
1 43
PROGRAMACIN C#
n ...
tatic public bool operator true(Vector2 vec)
return {vec.X 1= 0 && vec.Y 1= 0);
static public bool operator false(Vector2 vac)
return I(vec.X l 0 && vec.Y 1= 0);
{
// ...
static public bool operator == (Vector2 vecl, Vector2 vec2)
return (vecl.X == vec2.X && vecl.Y == vec2.Y);
static public bool operator I* (Vector2 vecl, Vector2 vec2)
return (vecl.X != vec2.X || vecl.Y != vec2.Y);
144
u s r .c o d e
Polim orfismo
TIPO DE OPERADOR
OPERADORES
Primario
Cast
Seleccin
new
Asignacin de memoria
typeof
Tipo
sizeof
Tamao
checked
Verificado
unchecked
No verificado
ComparacnY
Condicional
Asignacin
II
Comparacin0
?;
Condicml
Asignacin
+*
Suma y asignacin
Resta y asignacin
Divisin y asignacin
*-
Y bitwise y asignacin
A.
0 exclusivo y asignacin
I ,*V *
>
u
is
Seleccin
; Indexamientode array
Resto y asignacin
ir
Raooal
Multiplicacin y asignacin
Seleccin de miembro
Indexadon
Mtodos virtuales
Una de las caractersticas ms importantes que ofrece el lenguaje en cuanto a poli
morfismo tiene que ver con los mtodos virtuales.
D U INDEXADORES
El operador [] (indexacin de array) no puede ser sobrecargado directamente. Sin embargo, C#
dispone de un recurso denominado indexadores, que nos permite realizar una tarea equivalente
que ya veremos en el Captulo 5.
usr.code
145
PROGRAMACIN C#
{
public void RealizarMovida{)
{
Consol.WriteLine("Clase: Jugador, Mtodo: RealizarMovida);
{
Jugador jugadorl;
Jugador jugador2;
public void EmpezarPartida(Jugador jugl, Jugador jug2)
146
u s r .c o d e
Polimorfismo
{
jugadorl = jugl;
-
jugador2 = jug2;
jugadorl.RealizarMovida();
jugador2.RealizarMovida();
}
}
Nuestro modelo de clases terminar all, debido a que simplemente queremos mos
trar una funcionalidad especfica.
No existir tablero ni fichas, sino que, por el contrario, slo mostraremos en pan
talla algunos mensajes para analizar de qu manera se comporta el compilador al ser
sometido ante distintos modelos.
Nuestro sencillo diagrama esttico de clases podra ser:
Juego
Jugador
+RegistrarJugador()
+EmpezarPartida()
+RealirarMovida()
Ahora bien, cmo haremos uso de nuestras clases? En un primer ejemplo, lo hare
mos instanciando la clase Jugador en dos ocasiones:
class Foo
-voftr
{
static void Main (string U gs)
.
*.
-vi -<
}
}
u s r .c o d e
147
PROGRAMACIN C#
duego
jugadorl:Jugador
jugador2Jugador
EmpezarPartida
RealizarMovida
RealizarMovida
1
----
f r
El diagrama de secuencias anterior nos permite ver en forma grfica cmo se deben
realizar las llamadas. Un diagrama de secuencias se encuentra compuesto por dis
tintos elementos:
Objetos: son representados por los rectngulos no llenos en el borde superior del
diagrama. Dentro de ellos se debe colocar su nombre seguido de unos dos puntos y
el nombre de la clase. En caso de querer indicar que lo especificado es para cualquier
objeto del tipo, se colocan simplemente unos dos puntos y el nombre de la clase.
Mensajes: son las lneas horizontales que cruzan el diagrama. Representan invo
caciones a funciones o mtodos, y las hay de distintos tipos (simple, sincrnica y
asincrnica).
146
u s r.c o d e
Polim orfismo
* Tiempo: las lneas verticales representan el tiempo. Es decir que lo que se coloque
ms arriba se producir antes que lo que se coloque ms abajo. Los rectngulos co
locados sobre estas lneas de tiempo representan un flujo de ejecucin determinado.
En el Apndice D se puede encontrar ms informacin respecto a este diagrama y
los otros diagramas del lenguaje de modelado unificado.
Sin embargo, nosotros queramos hacer distintas inteligencias; cul sera entonces
la estrategia por seguir? Podramos colocar una propiedad tipo en la clase y luego,
en funcin de su valor, dividir el flujo de ejecucin representando distintas lgicas:
if (tipo
1)
{
// lgica del jugador tipo
}
lee if (tipo
2)
{
// lgica del jugador tipo B
}
alee if (tipo <= 3)
{
// lgica del jugador tipo C
I 1
Pero esto sera demasiado tedioso! Adems, la cantidad de cdigo en la clase crece
ra mucho, y si no tenemos el cuidado suficiente podremos, intentando modificar
el comportamiento de un tipo de jugador, modificar el equivocado alterando lo que
ya funcionaba correctamente.
Entonces, usted se podr preguntar: por qu no utilizamos el mecanismo herencia?
Excelente idea! Veamos: podramos crear distintas subclases de Jugador que implementaran el comportamiento de cada tipo; podran ser Botl y Bot2.
Entonces, agregaremos a nuestro programa:
class Botl : Jugador
,
{
public void RealizarMovidaO
{
Console.WriteLine("Clase: Botl, Mtodo: RealizarMovida");
u s r .c o d e
149
PROGRAMACIN C#
}
}
class Bot2 : Jugador
{
public void RealizarMovidaO
{
Consol.WriteLine{"Clase: Bot2, Mtodo: RealizarMovida");
}
}
Juego
Jugador
+RegistrarJugador()
+RealizarMovida()
+EmpezarPartida()
JugadorBotl
JugadorBot2
+ReallzarMovida()
+RealizarMovida()
Nos estamos acercando a nuestra solucin, ahora deseamos que en la partida inter
vengan los jugadores Botl y Bot2, para lo cual modificaremos el mtodo Main:
claas Foo
{
static vid Main(atring(] args)
{
Botl jugl = new BotlOj
Bot2 jug2 = new Bot2();
Juego j = new Juego ();
j,EmpezarPartida(jugl, jug2);
}
}
150
u s r .c o d e
Polim orfismo
La idea sera que ahora la instancia de la clase Juego invocase los mtodos de los ob
jetos del tipo
Botl y Bot2.
Botl
mente vlido, ya que al ser subclases de Jugador tambin pueden ser considerados
de dicho tipo (podramos establecer una analoga definiendo que si un gato es una
particularizacin de un animal, entonces un gato ES un animal). Lo que aqu hici
EmpezarPartida
invoc el mtodo
RealizarMovida
de un objeto,
que si bien es del tipo Botl, fue asignado a un parmetro del tipo Jugador; por lo
tanto, cuando se realiza la invocacin, se ejecuta la versin del Jugador.
Para modificar este comportamiento, deberamos declarar al mtodo
RealizarMovi
da como virtual; para realizar esto nos alcanzar con anteponer dicha palabra como
un modificador ms:
class Jugador
{
public virtual void RealizarMovidaO
{
Console.WriteLine("Clase: Jugador, Mtodo: RealizarMovida*);
}
}
[JJ
Es importante realizar pruebas de distintos ejemplos para entender bien cmo funcionan los mto
dos virtuales y poder anticipar con total seguridad cul ser el comportamiento de nuestro progra
ma en cada caso. Por suerte, el excelente depurador que incluye el entorno Visual Studio .NET nos
facilitar mucho la tarea, y3 que podremos seguir paso a paso la ejecucin de nuestro programa.
u s r .c o d e
151
PROGRAMACIN C#
override:
{
public override void RealizarMovidaO
}
}
class Bot2 : Jugador
{
public override void RealizarMovidaO
{
Consol.WriteLine("Clase: Bot2, Mtodo: RealizarMovida*);
}
}
(Botl, Bot2)
I f f l EL MODIFICADOR OVERRIDE
Otros lenguajes orientados a objetos, como el C++, no especifican que deba declarase un modi
ficador override cuando se est sobrecargando un mtodo virtual. Por suerte, C# ha incorpora
do esta caracterstica, que evita posibles errores y malas interpretaciones.
152
u s r .c o d e
Polim orfismo
aa podremos crear nuevas subclases de Jugador y hacer que Juego las invoque sin
modificar una sola lnea de esta ltima clase.
Vayamos ahora un paso ms adelante. Podramos establecer que todas las implementaciones de algn jugador debieran ser subclases de Jugador, y de esta subclase
dejar nicamente el esqueleto, ya que, al fin val cabo, imponiendo esta regla no ca
be la posibilidad de que exista una instancia Jugador, sino que existirn instancias
de sus subclases.
Dejar el esqueleto implicara colocar slo las declaraciones de ios mtodos; ningn
sentido tendra colocar sus definiciones, ya que nunca sern ejecutadas. Obrando de
esta manera estaramos creando lo que se conoce como interfaz (en ingls, interfac).
Interfaces
Como mencionamos en el prrafo anterior, una interfaz es una estructura de daros
que nicamente posee declaraciones, pero que no realiza implementacin de ningn
mtodo. Un contrato que es expresado para que posteriormente lo implemente quien
se subscriba a l.
Para convertir nuestra clase Jugador en una interfaz deberemos escribir:
interface Jugador
{
void RealizarMovidaO;
Ntese que:
Cambiamos la palabra reservada class por interface.
Eliminamos el modificador public (ya que todos los mtodos declarados dentro de
una interfaz siempre son pblicos).
Una interfaz puede declarar propiedades Ideclarando el get y/o el set pero sin imptementarlos). Una interfaz NO puede poseer variables ni constantes, ni heredar de ninguna clase, pero
S de otras interfaces. Finalmente, una clase que herede de una interfaz debe implementar TO
DOS los mtodos declarados por ella.
u s r .c o d e
153
PROGRAMACION C#
RealizarMovida
Botl,
Clases abstractas
Es muy posible, en el caso anterior, especificar Jugador como una clase especial, de
nominada clase abstracta. Las clases abstractas poseen la caracterstica particular de
no poder ser instanciadas. Estas son creadas con el propsito de ser utilizadas
posteriormente por medio de la herencia.
Y cul es la diferencia respecto a las interfaces? Las clases abstractas pueden definir
mtodos o declararlos como abstractos, para luego ser implementados por subcla
154
u s r.c o d e
Polim orfismo
ses. Ademas, pueden poseer variables y constantes; es decir que se asemejan mucho
ms a una clase convencional que las interfaces.
Veamos cmo podramos haber declarado Jugador como una clase abstracta;
abatract class Jugador
{
abatract public void RealizarMovida();
RESUMEN
En este captulo hemos analizado conceptos en apariencia simples pero muy profundos.
U tilizar correctam ente el polimorfismo y la herencia ser determ inante en la creacin de
sistemas complejos. Las propiedades nos brindan la posibilidad de reforzar el encapsulamiento; la herencia nos permite crear programas con mucho menos cantidad de cdigo y ms
fciles de m antener; tos mtodos virtuales, interfaces y las clases abstractas nos ayudan a ex
plotar el polimorfismo hasta el lm ite. Todo esto, sumado a la gran arquitectura con la cual fue
creada la librera BCL. Nunca antes otro lenguaje de programacin orientado a objetos haba
contado con un nmero similar de recursos. Programar en C# es realmente un placer.
u s r .c o d e
155
R 3 ACTIVIDAD
TEST DE AUTOEVALUACIN
156
u s r .c o d e
PROGRAMACIN CS
Captulo
Colecciones
El array es uno de los recursos ms
poderosos que ofrece C#. Analizaremos
aqu diferentes tipos de arrays, de una
dimensin y multidimensionales, cmo
usarlos y los beneficios que ofrecen.
Veremos qu son los indexadores, que es
una coleccin y cules son las interfaces
ms importantes de colecciones que
Arrays
Mtodos de la clase Array
Arrays como parmetros
de mtodos
Valores predeterminados
en un array
Inicializando elementos
de arrays
158
163
166
169
171
E modificador params
Arrays multidimensionales
Inicializacin de un array
de dos dimensiones
Arrays de arrays
Indexadores
Indexadores para acceder
a arrays de dos dimensiones
Colecciones
lEnurnerable y lEnumerator
ICollection
IComparable
IList...
Diccionarios
El diccionario Hashtable
Resumen
s e r v ic io de atencin ai . lec t o r :
Actividades
172
173
176
176
179
184
185
185
188
189
189
190
191
193
194
PROGRAMACIN C#
ARRAYS
Hasta este momento hemos aprendido la manera de crear variables que contengan
en su interior un valor determinado relacionado con el tipo de dato de las mismas.
En el caso de que quisiramos almacenar, por citar un ejemplo, el nombre de un
alumno, podramos especificar:
string nombre;
Esto no es para nada prctico, debido a que todo clculo relacionado con el con
junto de datos (como, por ejemplo, el promedio de las notas) nos obligar a escri
bir el nombre de cada una de las variables.
| float promedio = (notal + nota2 + nota3 + nota4
+ nota5) / 5;
+ nota5 + notafi +
158
u s r.c o d e
Arrays
Con lo escrito, hemos declarado el array, pero an no podremos utilizarlo. Para ello
deberemos solicitar memoria para la cantidad de elementos que poseer, y esto lo
hacemos utilizando el operador new:
Ntese que luego del operador new especificamos el tipo de dato, y esta vez entre
los corchetes indicamos cul ser la cantidad de elementos de nuestro array.
Tambin podramos haber especificado todo en una sola lnea:
float [] notas = new float [5];
...
.,
.jjgaaMgaBBBHfiHBSBHMaaBMMB
........
...
. -
.............
.. . . .
r*
::
/ > *
En C#, los lmites de un array son verificados (algo que no se hace en C o en C++). Si intentamos
acceder a un elemento no vlido (por ejemplo, mayor al nmero total de elementos), el frame-
' ......
work arrojar una excepcin en tiempo de ejecucin
u s r .c o d e
i;
ir -V
' '
''
'
159
PROGRAMACIN CU
160
u s r .c o d e
Con los diagramas de flujo podremos expresar, sin obligacin de ligarnos al lengua
je de programacin, cmo ser el flujo de ejecucin de nuestro programa.
:x'* "
* ;
Los diagramas de flujo se utilizan para disear algoritmos esquemticamente, antes de llevar
los al cdigo. De este modo, nos concentramos slo en el problema, y no en una sintaxis parti
cular del lenguaje de turno, porque un diagrama de flujo no est relacionado especficamente
con ningn lenguaje de programacin.
u s r .c o d e
161
PROGRAMACIN C#
Salida a pantalla
c m
Entrada por teclado
Sentencia condiciona
condicin
no
si
0
nombrejuncin
Cabecera de funcin
parmetros
Length?
C ad a objeto d e c la ra d o e s d e sce n d ie n te de la c la s e
L o s a r r a y s d e riv an im p lc ita m e n te de la c la s e
Anay (qu e
d e s c ie n d e de la c la s e
Object.
Object], lo cu a l
Length, q ue tie n e
co m o
fu n ci n d e vo lv er e l to ta l de e le m e n to s q u e p o se e el arre g lo .
162
u s r.c o d e
Arrays
u s r .c o d e
163
PROGRAMACIN CU
BinarySearcb
Clear. IH 1
sv -
Copy
'
, "
fo
Cooy
GetBtumerator
No
fio
. vetit-r.gcr.
GetVaue
,,
NcNo
fever
SetValue
i Sor! ,
No
S
I
Tabla 2. Mtodos utilizados en la clase Array.
UN ARRAY EN MEMORIA
gjjj
E l espacio en m em oria que ocu p a un a rra y corresp ond e a l espacio que ocupa un elem ento d el ti
po de dato a i cu a l pertene.ee, m ultiplicado por e l tam ao d el array. S i cada elem ento ocu p a 4 bytes, un at a y ce 10 ele m e n to s o cu p ar 40. byts. Los elem entos.d e un a rra y son colocados,adya
centem ente en la m em oria, para a cc e d e r a ellos fcil .y rp id am en te por m eda de un subndice.
164
u s r .c o d e
Arrays
'
.
->
>
-
.
nuns i3] = 5;
nuas!4) =
9;
nums [5] = 2
nums [6] = 0;
nums[7] * 6;
nuKSti) - 1;
u s r .c o d e
165
PROGRAMACIN C#
nums [2] s 8;
Duna [3] = 5;
nums[4] 9;
int [3 nums2 new int (53;
gados, por lo que no existe un solo modo de utilizarlos. En este caso hicimos uso
de la versin de los mtodos que mejor se adaptaba a nuestras necesidades.
{
n u m s [0 3
= 50;
166
u s r .c o d e
A rra y s
Ntese que el parmetro es del tipo int[] y que no especifica el tamao del arreglo,
es decir que el mtodo podr recibir arrays de enteros de cualquier tamao. En to
do caso sera conveniente verificar, antes de a leer o escribir un elemento, si el ndi
ce se encuentra dentro del rango vlido (por medio del uso de la propiedad Length).
Veamos el programa completo:
clasa Foo
'
{
public static void ModificarArray{int[3 arr)
'
{
arr[0] * 50;
}
static void Main (string [] args)
(IIP
^
nums[03 * 3;
nums[13 = 1;
nums[2f a 8;
'
: V :'
nums[33 s 5;
nums[4] = 9;
Console.WriteLine("Array notas");
for (int i=0; icnums. Length; i++)
Console.WriteLine("elemento {O}; {l}*, i numsij);
Foo.ModificarArray(nums);
Console.WriteLine("Array notas modificado");
for (int i=0; icnums.Length; i++)
Console.WriteLine("elemento {0}: {l}",
i, nums[i]) ;int[] nums2 = new int[53;
}
}
u s r .c o d e
un elem ento
167
PROGRAMACIN CU
Poo.ModificarElemento(ref nums[0]);
'
num = 33;
En realidad, el mtodo
ModificarElemento
{
Consol.WriteLine(*valor variable: {0}", num);
168
u s r .c o d e
_________________________________________________________________________________________________ A rr a y n
class Foo
public static void ModificarElemento(re int num)
{
num = 33;
}
public static void MostrarValorfint num)
{
Consola. WriteLine ('
valor variable; {o}", num);
}
static void Main(8tring[3 args)
{
int [] nums new int [5];
4
nums[0)
3;
numsll] = 1;
nums[2] 8;
num8[3] = 5;
nums [4] =-9;
Foo.Modificarlemento(ref nums [0]);
Foo.MostrarValor (nuais [0]) ;
Consol.WriteLine("Array notas*);
for (int i0; icnums.Length; i++)
Consol.WriteLine(*elemento {0}: {l}", i, numstij)
int variableConvencional * 10;
Foo.ModificarElemento(re variableConvencional);
Foo.MostrarValor(variableConvencional);
un elemento de un
mismo que enviar
usr.code
169
PROGRAMACIN C#
Poo()
{
Console.WriteLine("Constructor") ;
}
}
Foo. El array tendr cinco elementos con valor nuil, que son referencias a objetos del
tipo Foo que an no han sido inicializadas.
Para poder utilizar los elementos deberemos inicializarlos en forma individual. Po
dramos realizar esta tarea inmediatamente despus de la declaracin del array o a
medida que lo requiramos (hay que tener en cuenta que inicializar un objeto impli
ca ejecutar cdigo de constructores; realizar esto una gran cantidad de veces podra
influir en la performance de nuestra aplicacin).
for (int i=0; i<arrayDeFoo.Length; i++)
arrayDeFoo(i) new Foo();
Ahora s, se ha ejecutado el constructor de cada uno de los elementos del array, tras
lo cual podremos acceder a sus variables, mtodos y propiedades. En la Figura 6 se
puede apreciar otro ejemplo de lo mencionado:
170
u s r .c o d e
Foo[]arrayDeFoo =new
Foo[5];
[0]
nuil
[0]
[1]
nuil
(11
nuil
[2]
nuil
[2]
referencia a objeto
tipo Foo
[3]
nuil
[3]
nuil
14]
nuil
[4)
nuil
'
nums[0] t 3
numatl] a 1;
nums[2] * 8;
nums[3]
9;
= 5;
numaf] =
usr.code
171
PROGRAMACIN C#
O mejor an:
int[]
nm$
= (3, 1, 8, 5, 9};
Recorriendo arrays
Hasta el momento, hemos recorrido arrays por medio de la sentencia for. Tambin
podramos haberlo hecho utilizando la sentencia while para recorrer un array, tal co
mo se detalla a continuacin:
int [] nuxos new int 15];
int i=0;
while (i<nums.Length)
{
Consol.WriteLinefmims [i]);
i++I
}
Sin embargo, la sentencia que mejor se adeca a los arrays tal vez sea el foreach (au
sente en los lenguajes C y C++). En el Captulo 2 ya habamos introducido esta sen
tencia; aqu veremos nuevamente cmo recorrer un array haciendo uso de ella:
intfi nuraa = {10, 20, 30, 40, 50}
foreach {int i in nwns)
{
Consol,WriteLine(i);
Como podemos apreciar, en la sentencia foreach declaramos una variable que oficiar
de elemento en cada iteracin. Luego utilizamos dicha variable para mostrar en panta
lla el contenido del array (tengamos en cuenta que con dicha variable podremos leer el
contenido del array, pero no podremos modificar el contenido de los elementos).
El modificador params
Es posible especificar un modificador al parmetro de una funcin llamado params,
que nos permitir pasar arrays o un conjunto de elementos que el compilador tra
ducir a arrays de manera dinmica. Para ello deberemos escribir:
172
u s r .c o d e
Arrays multidimensionales
Veamos ahora cmo invocar el mtodo Listar, por medio de un array convencional:
int ] nums
{3, 1, 8, 5, 9};
foo.Listar(nums
);
ARRAYS MULTIDIMENSIONALES
C# soporta la definicin de arrays de mltiples dimensiones. Hasta el momento, to
dos nuestros arrays eran de una dimensin, pero es posible definir arrays de dos di
mensiones (ideales para representar tablas, cuadros de dos entradas, matrices, etc.)
o de las dimensiones que nos parezcan.
Veamos cmo declarar un array de dos dimensiones:
int[,] tabla a nev int (3, 3];
Como podemos apreciar en el listado anterior, luego del tipo de dato del array en
tre los corchetes, existe una coma. Tambin, en lugar de haber un solo nmero en
la indicacin del tamao del array, figuran dos, correspondientes a la cantidad de
elementos por cada dimensin.
Es muy prctico imaginar un array de dos dimensiones como una tabla, siendo la
primera dimensin la cantidad de filas, y la segunda dimensin, la cantidad de co
lumnas (o al revs, segn la convencin que se desee emplear).
u s r .c o d e
173
PROGRAMACIN Ctt
Para poder acceder a los elementos de un array de dos dimensiones, se deber hacer
uso de la siguiente sintaxis:
tabla[0, 0] = 10;
174
u s r .c o d e
Arrays multidimensionales
Veamos ahora esta equivalencia en cdigo. Si tuviramos que representar una tabla
con un array de dos dimensiones, procederamos del siguiente modo:
int cantidadFilas = 3;
int cantidadColusmas = 3;
intt,] tabla = new int[cantidadFilae, cantidadColusmas];
for (int i=0; i<cantidadPilas * cantidadColusmas; i++)
tabla [i / cantidadColusmas, i % cantidadColusmas] = i;
for (int fila=0; filaccantidadFilas; fila++)
for (int col=0; col<cantidadColusmas; col++)
Consol.WriteLine(tabla(fila, col]);
u s r .c o d e
175
PROGRAMACIN CS
int cantidadPilas 3;
int cantidadColumnas = 3;
int I) tabla = new int [cantidadPlas * cantidadColumnaa];.
for (int i=0; iccantidadFilaa * cantidadCol-uanaa; i++)
tabla [i] s i;
for (int fila=0; filaccantidadFilas; fila++)
for (int col=0 colccantidadColumnas; col++)
Consol.WriteLine(tabla[fila*cantidadColumnas+col]);
ARRAYS DE ARRAYS
Adems de los arrays multidimensionales que analizamos en los prrafos anteriores
y que son conocidos con el nombre de arrays
posibilidad de declarar arrays
in t[][]
arrayDeArrays;
Notemos que, ahora, dentro del corchete no hay nada, pero existe otro juego de
ellos tras el primero. Esto quiere decir que poseeremos un array en el cual cada uno
de sus elementos ser, a la vez, otro array.
1 76
u s r .c o d e
Arrays de arrays
Ahora definamos el array de nivel ms alto, el que contendr al resto de los arrays:
arrayDeArrays = new int [S] [];
Aqu obtendremos un array de cinco arrays. Los arrays que se encuentran dentro
del primero an no fueron definidos, por lo que lo que tendramos en memoria se
corresponde con el siguiente diagrama:
Array de arrays
[0]
<no def>
[1]
<no def>
[21
<no def>
[3]
<no def>
[4]
<no def>
Definamos, entonces, los arrays que se encuentran dentro del primer array. Estos no
tendrn por qu poseer el mismo tamao:
arrayDeArrays[0] new int [3];
arrayDeArrays[11 = new int[21;
arrayDeArrays[21 = new int[5J;
arrayDeArrays[31 = new int[4];
arrayDeArrays [43 = new int [2];
u s r .c o d e
177
PROGRAMACIN C#
nnr
ELEMENTOS NULOS
,
-" ;
178
u s r.c o d e
Indexadores
arrayDeArraya10][0] 1;
arrayDeArraya[0][1] =
2>
| arrayDeArraya[0] [2] 3?
arrayDeArraya[1][0] 1;
arrayDeArraya(I](1] a 2;
arrayDeArrays 12][0] 1;
arrayDeArrays12][1] * 2 ;
arrayDeArraya[2] f2] * 3;
arrayDeArraya[2][1] = 4;
arrayDeArraya[2][2] = 5;
arrayDeArraya[3] [0] = 1;
arrayDeArraya13][1] = 2;
arrayDeArraya(3][2] = 3;
arrayDeArrays13)[1] 4;
arrayDeArraya4][0] = 1 ;
arrayDeArraya14][1] - 2;
INDEXADORES
En ocasiones puede ser beneficioso permitir acceder a una coleccin dentro de un
objeto que hayamos creado como si ste fuese un array, es decir, utilizando el ope
rador de indexacin [].
C# permite realizar esto no por medio de la sobrecarga del operador [], como ocu
rre en C++, sino a travs de una caracterstica denominada indexador.
{]
USO DE INDEXADORES
u sr.code
179
PROGRAMACIN C#
Supongamos que hemos implementado una clase llamada Cadena, que facilita el uso
y la manipulacin de strings (en C#, esto sera realmente innecesario, porque cuen
ta con un excelente soporte de strings). Nuestra clase Cadena poseer como variable
privada un array de caracteres donde se almacenar el texto correspondiente:
class Cadena
1 {
gat
{
string str
foreach(int c in texto)
str += (char) c;
r e t u m str;
}
set
{
texto a new char[valu.Length];
for (int i0; ievalu.Length; i++)
texto [i] = valu [i];
}
}
180
Creamos un array del tamao adecuado para contener el string fijado (en la pa
labra reservada valu). Ntese que la segunda vez que se fije un valor al texto, se
u s r .c o d e
Indexadores
crear orro array; el primero ser destruido por el recolector de basura cuando al
framework le parezca adecuado (podramos haber verificado si realmente era ne
cesario crear otro array; o crear uno un poco ms grande de lo necesario para no
solicitar memoria una y otra vez, pero deseamos mantener el ejemplo sencillo).
2.
Siguiendo con nuestro ejemplo, ahora deseamos permitir que el usuario de nuestro
objeto de tipo Cadena pueda acceder a cada letra del string (elemento de nuestro array)
como si nuestro objeto entero fuese un array. Para esto crearemos un indexador:
public char this int ndex]
l
{
get
{
i (index < texto.Lngth)
return textolindex];
else
return '\0';
}
set
{
if (index < texto.Length)
texto[index] valu;
h
A primera vista, nuestro indexador es muy similar a una propiedad, pero si obser
vamos bien, notaremos que el identificador es diferente. La palabra reservada this
hace referencia al propio objeto en el cual estamos. Luego, entre corchetes, declara
mos una variable que ser la que podremos usar dentro de los mtodos de acceso
get y set, y la que contendr el nmero que entre corchetes especifique el ndice.
u s r .c o d e
181
PROGRAMACIN C#
182
u s r .c o d e
Indexadores
En el mtodo get:
1. Verificamos si el ndice especificado se encuentra ubicado dentro del rango vli
2.
do de nuestro array.
En el mtodo set:
1. Verificamos si el ndice especificado se encuentra ubicado dentro del rango vli
do de nuestro array.
2. En caso de comprobar que sea as, modificamos su contenido con el carcter re
cibido en la palabra reservada valu.
Finalmente, sobrecargamos el mtodo ToString para especificar qu string debe de
volverse como representacin del objeto cuando se lo requiera.
Ahora, veamos un programa sencillo que hace uso de nuestra clase Cadena:
Cadena cad * new Cadena ();
iS i S f i
L';
u s r .c o d e
183
PROGRAMACIN Cff
En el listado anterior, hacemos uso del indexador definido en la clase con la finali
dad de leer los caracteres del array que se encuentra encapsulado en su interior, as
como para modificar su contenido.
{
get
set
{
Consola.WriteLine("mtodo set. Indice 1: {0}, Indica 2: {l}
Valor: {2}, idxl, idx2, valu);
}
}
El hecho de que el indexador permila recibir ms de un tipo de dato no significa que debamos
utilizarlo solamente para el acceso a arrays multidimensionales. lanpoco es necesario que to
dos los elementos que reciba el indexador sean del mismo tipo. Come hemos mencionado antes,
es un recurso muy flexible.
1 84
u s r .c o d e
Colecciones
Como se puede apreciar, ahora enere los corchetes de la primera lnea de la declara
cin del indexador existen dos variables declaradas, y no slo una. Estas variables
representan los dos ndices que se le pasarn al objeto.
Tambin conviene destacar que nuestro indexador recibe y entrega nmeros ente
ros, y no caracteres. En realidad, podra recibir y entregar cualquier tipo de dato.
COLECCIONES
Una coleccin es un objeto que contiene un grupo de objetos afines. Mediante una
coleccin es posible actuar sobre la totalidad de un subconjunto de objetos.
C# posee diversas interfaces de colecciones que nuestras clases podrn implementar
y, de este modo, otorgar mayor facilidad de uso.
lEnumerable y lEnumerator
Por ejemplo, vimos que es posible recorrer un array mediante la sentencia de bucle
Cmo hacer para que un objeto definido por nosotros tambin pueda ser
foreach.
IEnumarator es otra interfaz que bien podr implementar la misma clase que implementa Enumerable, o alguna otra clase afn.
Esta propiedad ser utilizada cuando se desee acceder al elemento actual apuntado
por el enumerador. Y tambin declara los siguientes mtodos:
bool MoveNextO;
u s r .c o d e
185
PROGRAMACIN C#
La
interfaz
Enumerable
" 1
ClaseEnumerable
interfaz
lEnumerator
1
------ -
+GetEnumerator()
1
O
t
ClaseEnumerador
+Current
+MoveNext()
+Reset()
Una vez que hemos implementado nuestro pequeo programa, ser posible instanciar la clase ClaseEnumerable y recorrerla por medio de una sentencia foreach, tal co
mo se muestra a continuacin:
ClaseEnumerablfi objEnum a new ClaseBnumerableO;
foreach (int i in objUnun)
Consol.WriteLine(i);
nnr
QU ES UN ENUMERADOR?
186
u s r .c o d e
Colecciones
La ciase ClaseEnumerable:
KkdVT-
|{
A1
aSfiy*4
'"fUSfi?
rw'M
{
r e t u m new ClaseEnumerador(this);
}
// Indexator para facilitar el acceso
// a elementos del array encapsulado
public int thietint idx]
{
get
{
r e t u m lista [idx];
}
}
// Propiedad Length que a su vez invoque la propiedad
// Length del array encapsulado
public int Length
{
get
{
return lista.Length;
La clase ClaseEnumerador:
clasa ClaseEnumerador : lEnumerator
u s r .c o d e
187
PROGRAMACIN C#
ii
{
objEnum = obj;
}
// Propiedad Current que retorna elemento actual
public object Current
{
get
{
return objEnumlelementoActual];
}
}
// Mtodo MoveNext
public bool MoveNexti)
{
if (elementoActual < objEnuo.Length-1)
{
elsmentoActual+t;
return true;
}
else
return false;
}
// Mtodo Reset
public void Reset)
{
eleaentoActual -1>
}
}
ICollection
Existe otra interfaz de colecciones que se denomina ICollection. Esta interfaz decla
ra las propiedades que enumeramos a continuacin:
188
u s r .c o d e
Colecciones
int Count {get;}: devuelve la cantidad total de elementos que posee la coleccin.
bool IsSynchronized {get;}: indica si el acceso al objeto es seguro por medio de di
ferentes threads concurrentes.
object SyncRoot {get;}: esta propiedad devuelve un objeto que permita sincronizar
el acceso a la coleccin.
La interfaz declara, adems, el siguiente mtodo:
void CopyTo(Array array, int ndex);
IComparable
Si nuestra clase implementa la interfaz IComparable, entonces podr ser ordenada
por medio del mtodo Sort, ya que es posible determinar si un elemento es menor,
igual o mayor a otro.
La interfaz slo declara el siguiente mtodo:
El mtodo
CompareTo
IList
Si nuestra clase implementa la interfaz IList, entonces sus elementos podrn ser ac
cedidos individualmente por medio de un ndice.
u s r .c o d e
189
PROGRAMACIN C*
DICCIONARIOS
Un diccionario es una coleccin que asocia un valor a una clave. Podra ser consi
derado como un array que utiliza ndices no numricos para acceder a los elemen
tos. Esto es muy til en innumerables ocasiones; un ejemplo podra ser querer ob
tener la referencia a un objeto a partir de su nombre:
Sprite nave SpriteManager[,'nave enemiga jefe");
MS INFORMACIN!
Este libro no pretende reemplazar la completsima ayuda que ofrece el sitio MSDN (http://m sdn.
microsoft.com) o la que viene incluida con el entorno de desarrollo integrado Microsoft Visual
Studio .NET. Dicho recurso es ideal para obtener informacin de referencia respecto a clases,
estructuras e interfaces.
1 90
u s r .c o d e
D ic c io n a r io s
O, por ejemplo, acceder a la cantidad de das que posee un mes a partir de su nombre:
int diaaMarto Mes['Harto" ) ;
es
tipo
tipo el valor retornado. Es
El diccionario Hashtable
La librera BCL provee una clase llamada Hashtable, que ofrece un diccionario opti
mizado para encontrar rpidamente un valor a partir de una clave.
La idea general en una tabla de tipo hash es la de acceder directamente aun elemen
to en una tabla sin tener que buscarlo recorriendo sta. Y cmo se logra esto? Por
medio de una funcin hash, que toma la clave como entrada y provee un ndice nu
mrico como salida, que es donde se almacena el valor en la lista.
Una funcin hash trivial podra ser sumar los cdigos ASC II del string por almace
nar en mdulo
(siendo
dos strings distintos podran producir el mismo ndice, lo cual implicara una coli
sin. De todos modos, si la funcin hash se encuentra bien pensada, la cantidad de
colisiones debera mantenerse en un nmero bajo.
u s r .c o d e
191
PROGRAMACIN C#
Cuando se produce una colisin, es decir, cuando dos entradas distintas a la fun
cin de hash producen la misma salida, no se debe devolver ningn error; la cla
se que implemente el algoritmo deber tomar las acciones necesarias para poder
almacenar el valor en la tabla.
Muchas veces, de cada elemento de la tabla se relaciona otra lista que contiene los
elementos en colisin; claro que la bsqueda para estos elementos incurrir en
ms pasos, pero nunca debera ser tan costoso como buscar por la tabla entera.
Cuando la cantidad de colisiones es elevada, podemos estar ante dos escenarios:
1. La funcin de hash es mala para el conjunto de datos entrantes.
2. El tamao de la tabla es muy pequeo.
Respecto a esto ltimo, cabe destacar que el tamao de la tabla de hash no debera ser
un nmero suficientemente bajo para albergar a todos los elementos, sino que se sue
le recomendar que sea el nmero primo mayor al doble de la cantidad de elemento?,
mximos que podra poseer la tabla (s, se desperdiciar espacio en virtud de velocidad
de acceso a los elementos). De todos modos, esta recomendacin se encuentra ntima
mente relacionada con la funcin hash que utilice la implementacin del algoritmo.
192
u s r .c o d e
D ic c io n a r io s
J J
resumI
No existe programa fuera de lo trivial que no haga uso de colecciones de algn tipo. Desde los
clsicos arrays potenciados por la librera BCL hasta la gran variedad de tipos de colecciones
que nos ofrece sta. El problema ahora no es cmo implementar determinado tipo de colec
cin por nosotros mismos, sino qu clase ya implementada elegir ante tantas opciones que
nos ofrece esta plataforma. Un problema muy lindo, por cierto.
u s r .c o d e
193
ACTIVIDADES
TEST DE AUTOEVALUACIN
1 Cul es el ndice del primer elemento de
un array?
EJERCICIOS PRCTICOS
Crear un programa que permita:
a] Ingresar el nombre y el telfono de una
o ms personas (almacenar estos da
194
u s r .c o d e
PROGRAMACION C#
Captulo
Delegados
y eventos
Los delegados y los eventos son muy
utilizados en la program acin Windows.
El usuario puede interactuar con ellos
generando ocurrencias sobre los
Delegados
198
Qu es un delegado?
El delegado es una clase
Eventos
Invocar mltiples mtodos
1S9
201
201
204
La clase System.Timers.Timer
Caso de estudio
Resolucin
207
208
209
Resumen
213
Actividades
214
(
(
PROGRAMACIN Cfl
DELEGADOS
En ocasiones es necesario algn mecanismo que le permita al programador especi
ficar una funcin o un mtodo que ser invocado si ocurre un determinado suceso.
Un ejemplo clsico es la implementacin de un tim er. Un timer es una especie de
reloj despertador, slo que, en lugar de especificarle una hora absoluta, le indicamos
una cantidad de tiempo que debe transcurrir para que nos alerte.
Luego, para saber desde una clase que utilice el timer cundo ha transcurrido el tiem
po especificado, qu podramos hacer? Podramos estar consultando constante
mente el objeto timer, preguntando si el contador ya ha llegado al nmero propues
to? Sera muy poco eficiente!, adems de poco preciso. Lo ideal sera que el objeto
timer nos llamara a nosotros. Es decir que invertiramos los papeles por un momen
to: en lugar de ser nosotros quienes invocramos los mtodos de los objetos instanciados, dicho objeto sera quien llamara a algn mtodo de una de nuestras clases.
Pero entonces cmo podra el objeto timer informarnos de la ocurrencia del suce
so: ya-transcurri-el-tiempo-especificado!?
De nada servir coloar el cdigo que necesitemos utilizar dentro de nuestra clase
que implementa el timer, porque de este modo ser muy poco reutilizable. Lo que
aqu necesitamos es una solucin general y elegante.
Histriamente los lenguajes ofrecieron diversas maneras de lidiar con esta situa
cin. En lenguaje C, por ejemplo, es posible especifiar una funcin callback que
ser invoada cuando sea preciso.
callback es, en realidad, una funcin convencional que posee un prototipo especifi
cado (coincide en tipo de dato retornado y en antidad y tipo de parmetros). Lue
go, un puntero a esta funcin es pasado como parmetro a la librera que lo requie
ra. Cuando suceda el evento en cuestin, la funcin
U J l QU ES UN PUNTERO?
Un puntero es una variable que posee como valor una direccin de memoria. Un puntero a una
funcin es una variable que contiene la direccin de memoria donde esta funcin se encuentra
definida. Los punteros son populares en lenguajes como C y C+*. C # permite emplearlos en con
textos no seguros, pero casi no se utilizan. Ya veremos un poco ms en el Capitulo 10.
196
u s r .c o d e
Delegados
puntero a foo()
1
Y
void fooO
librera
{
}
t
gpjy
{
// Evitamos lidiar con el conteo del tiempo,
// simplemente invocamos el mtodo Tick
TickO;
}
protected virtual void TickO
W
i
)
)
u s r .c o d e
197
PROGRAMACIN C#
{
protectad overrida void Tick O
{
Consola.WriteLinel
Bjecucifa de Tick de Clase 1*) j
static void MainstringU args)
{
Claael obj new C laselO;
obj.Start();
}
}
Podramos suponer que la clase Timer forma parte de alguna librera, y que ni si
quiera podramos acceder a su cdigo fuente ni modificarla en ningn aspecto.
Sin embargo, declara un mtodo virtual que es invocado cada vez que se cumple
el intervalo de tiempo especificado (aunque en nuestro ejemplo no se realice un
conteo, para mantener el cdigo breve y sencillo). Entonces, para poder colgar
cdigo de este mtodo, debemos sobrecargarlo en una subclase de Timer, como ya
hemos hecho en captulos anteriores.
El sistema funciona a la perfeccin; en el momento en que invocamos el mtodo
Start,
lU
El lenguaje C++, como sucesor del lenguaje C -que de algn modo lo es-, permite utilizar el me
canismo de funciones callback. En C#, en cambio, esto es imposible, pues aqu toda funcin de
be estar definida dentro de una clase, algo que no exige C++ (lenguaje que muchas veces es cri
ticado por esta caracterstica y es tildado de hbrido).
198
u s r .c o d e
Delegados
modo, queremos hacer algo parecido al ejemplo que acabamos de analizar, pero sin
que Clasel deba ser subclase de Timer. Y aqu entran en accin los delegados.
Qu es un delegado?
Los delegados son clases especiales, y sus objetos son bsicamente contenedores de
referencias a mtodos de otros objetos.
De esta manera, pueden ser utilizados para almacenar una referencia al mtodo que
deseamos invocar, como si fuese una funcin callback convencional pero con una
flexibilidad mucho mayor, ya que el mtodo puede encontrarse en cualquier clase;
y podramos indicar que cuando ocurra el suceso no se invoque un solo mtodo, si
no todos los que deseemos (multicast).
____________________
usr.code
199
PROGRAMACIN C#
claes Claael
{
public Claael ()
{
TickHandler obj = (TickHandler)
Delegate.CreateDelegate(typeo(TickHandler),
thia, "EsteEsElMetodoTick*);
objO; // Aqu se invcca el mtodo EateEsBlLaetodoTickO
}
public void EateEeElMetodoTickO
}
static void Main(stringU arga)
{
Clasel obj new ClaselO;
I .
tres parmetros:
DELEGADOS POPULARES
El mecanismo de delegados y eventos es realmente til. Es muy utilizado por la librera BUL pa
ra diversos fines. Uno de ellos, tal vez el ms popular, es el de los eventos de los controles de tos
formularios, que comenzaremos a analizar en los siguientes captulos.
200
u s r.c o d e
Eventos
;
// Declaracin de algunas variables especficas
//
...
// ...
public <identiicador>(object o, int punteroAMtodo) {}
public virtual <tipo de dato> Invoke(dista de parmetroa>) {}
[ }
Pero nosotros no debemos complicarnos la vida con esta sintaxis. De hecho, la clase
declara algunas variables y mtodos mis que ni siquiera es menester mencionar aqu.
Simplemente es bueno tener en cuenta qu es lo que el lenguaje entiende realmen
te y cul es la naturaleza de este tipo de objeto nuevo que estamos utilizando.
EVENTOS
Un evento es un tipo especial de propiedad y est muy relacionado con los delegados,
ya que se utiliza para controlar el modo en que nuestro sistema hace uso de ellos.
u s r .c o d e
201
PROGRAMACION C#
{
public void StartO
{
// Invoco el evento Tiek
if (Tick I* nuil)
rieleo t
}
public event Tickllandler Ticfc - nuil;
}
clase Clasel
{
Timer a_timer;
public Clasel()
{
// Creo el objeto timer
m timer a new Timer ();
202
u s r .c o d e
E v e n to s
// Establezco el delegado
'ntiaer.Tick +' new TickHandlertthis.EsteEsElMtodoTick)
// Inicio el timar
m_tiaer.Start()
}
public void EsteEsElMetodoTicM)
{
Consol.Kritebine(*Ejecucin de EeteKsElMetodoTick da Clasel");
}
static void Main(string[] args)
{
Clasel obj = new Clasel 0;
}
}
u s r .c o d e
203
PROGRAMACIN Cft
QU ES UNA EXCEPCIN?
Una excepcin es un recurso del lenguaje que permite alterar el flujo de ejecucin normal de un
programa. Usualmente son utilizadas para tratar los errores que se pueden producir en tiempo
de ejecucin en nuestras aplicaciones. Ms adelante veremos cmo hacer uso de ellas. Apren
deremos ms acerca de excepciones en el Captulo 9.
204
u s r .c o d e
E v e n to s
Mtodo 1
Mtodo 2
unDelegado
void Hetodo2
{
throw new Bxception
(*...*),
u s r .c o d e
205
PROGRAMACIN CU
{
Timer m_timer;
public ClaselO
{
// Creo el objeto timer
m_timer = new Timar 0;
// Establezco el delegado
m_tiraer.Tick += new TickHandler(this.EsteEsElMetodoTickl);
m_timer.Tick += new TickHandler(this.EsteEsElMetodoTick2);
m_timer.Tick += new TickHandler(this.EsteEsElMetodoTickl);
// Inicio el timer
mtimer.Start();
}
public void EsteEsElMetodoTicklO
Consol.WriteLinel"Ejecucin de EsteEsElMetodoTickl
de Clasel");
public void KsteEsElMetodoTick2()
{
Console.WriteLine("Ejecucin de EsteEsElMetodoTick2
de Clasel");
public void EsteEsElHetodoTick3()
Console.WriteLine("Ejecucin de EsteEsElMetodoTickl
de Clasel");
}
static void Main{string[] args)
{
Clasel obj = new ClaselO;
Es totalmente obvio que esto resultara muchsimo ms prctico si los mtodos por
invocar fuesen de distintas clases.
206
u s r .c o d e
La clase System.Timers.Timer
LA CLASE SYSTEM.TIMERS.TIMER
La librera B C L nos ofrece una clase Timer que es ideal para utilizar en nuestras apli
caciones cuando stas deben realizar una determinada tarea cada cierto perodo de
tiempo. Esta clase hace uso de delegados y eventos (como no poda ser de otro mo
do). Veremos aqu cmo podemos utilizarla:
using System;
using System.Tiera;
namespace acDeTimar
{
clase Clasel
{
Timer
Clasel()
{
// Indico que el intervalo sea de 1000 ms
_timer.Interval 1000;
timer. S t a r t O ;
public void Tick(object sender, ElapsedBventArge e)
{
// Envo a pantalla un mensajecada vez que se
// invoca el mtodo Tick
Console.WriteLine(*Tick') ;
}
static void Main(string(] args)
{
// Creo un objeto del tipo Clasel
Clasel c = new Clasel();
el
// programa no termine
string str = Consol.ReadLineO;
u s r .c o d e
207
PROGRAMACIN C#
CASO DE ESTUDIO
Construir un pequeo programa que conste de tres clases (Clasel,
Clase2 y Clase3).
Figura
Clasel
Clase2
Start
Clasel
r DELEGADOS EN JAVA
Java no soporta delegados. Para realizar mplementaciones similares a las vistas, suelen utili
zarse interfaces de
208
u s r .c o d e
Caso de estudio
Resolucin
u s r .c o d e
209
PROGRAMACIN C#
Prestar especial atencin a que ahora nuestro delegado posee un parmetro entero
que nos solicita el enunciado.
Definir las tres clases con sus propios mtodos y eventos es muy sencillo:
public class Clasel
{
public void Startdnt num)
{
}
public event MiDelegado Evento n nuil;
}
class Clase2
{
Clasel objClasel;
public event MiDelegado Evento = nuil;
public Clase2()
{
public void MI(int num)
{
public void Startdnt num)
{
}
}
class Clase3
210
u s r.c o d e
Caso de estudio
Clase2 objCla8e2;
public Clase3()
}
public void M2{int num)
}
public void Start(int num)
{
public delegate void MiDelegado(int num);
public class Clasel
{
public void Start(int num)
{
// Invoco el evento
i (Evento != nuil)
Evento(num);
}
public event MiDelegado Evento = nuil;
}
class Clase2
{
Clasel objClasel;
public event MiDelegado Evento = nuil;
public Clase2{)
{
// Creo el objeto
u s r .c o d e
211
PROGRAMACIN C#
// Establezco el delegado
objClasei.Bvento += new MiDelegado(thiB.Hl);
}
public void MI (int num)
{
Console.WriteLine('Ejecucin de MI de Clase2.
Nmero = {o}", num);
}
public void Start(int num)
{
objClasei.Start(nua);
}
}
class Clase3
{
Clase2 objClase2;
public ClaselO
{
// Cree el objeto
objClaae2 * new Clase2();
// Establezco el delegado
objClase2.Evento +o new MiDelegado(this.Ml);
objClase2.Evento += new MiDelegado(this.M2);
}
public void MI(int num)
{
Console.WriteLine('Ejecucin de MI de Clase3.
Nmero
{0}", num);
}
public void M2(int num)
{
Console.WriteLine("Ejecucin de M2 de Clase3.
Nmero = {O}*, num);
}
public void Start(int num)
212
u s r .c o d e
Caso de estudio
{
objClaae2.Start(nua);
}
static void MainfstringU args)
{
Clase3 obj = new Clase3();
}
}
RESUMEN
Finalmente hemos visto los conceptos ms importantes del lenguaje que nos permitirn su
mergirnos de lleno en la programacin de aplicaciones de ventana.
En el prximo capitulo veremos cmo, por medio de la librera BCL, podremos crear aplicacio
nes con botones, cuadros de texto, listas y muchsimos controles ms. Aprenderemos, entonces,
que los delegados y los eventos forman parte de los recursos ms populares que utilizaremos
para colgar cdigo de los sucesos que pueden producirse en los controles y en el formulario.
u s r .c o d e
213
ACTIVIDADES
TEST DE AUTOEVALUACIN
1 Qu es realmente un delegado?
214
u i.c o d e
PROGRAMACION CS
Aplicaciones
con Windows.Forms
Ha [legado el m om ento de introducirnos
en la creacin de aplicaciones con
ventanas y controles. Por eso, en este
captulo darem os los pasos bsicos para
crear una aplicacin con interfaz de
usuario. Presentarem os los controles
bsicos de la librera y verem os cules
son sus m todos y propiedades bsicas.
Caso de estudio 2
Caso de estudio 3
Caso de estudio 4
Caso de estudio 5
Resumen
Actividades
227
229
232
234
234
239
241
246
250
253
254
PROGRAMACIN C#
PASO A PASO
(New Project).
New Project
Project Types:
^
ffl
O
i j c l l
Iem plates:
Visual C # Projects
Visual C + + Frojects
Setup and Deploym ent Projects
Ciass Librar;/
Windows
Control Library _ J
G U lA ppl
Locat.cn:
I E:\users\diego\libro CS(code-cap7
y"|
g row se...
T M o rj.
OK
Help
216
Cancel
que elegiremos
Windows Applica
u s r .c o d e
f>
B O
tyM F^nnot I k
f ;
>w
W nk*
- [# .'ui
%%.
?. X
Fwlxt Itta^n] ]
2B 3
oJutntflwr(t *-i
f. 0 UJIAppl
' CWJC
?X
Z{
D Si todo ha ido bien, deberamos ver en nuestra pantalla algo similar a lo que ex
presa la figura anterior.
Ahora bien, en la pestaa Solution Explorer encontraremos tocios los archivos que
pertenecen al proyecto o estn relacionados con l; algunos nos resultan conocidos
y otros no. Veamos:
Carpeta References: dentro de esta carpeta se listarn los distintos assemblies que
utiliza nuestro proyecto. Recordemos que un assembly es un componente de soft
ware que en su interior posee cdigo ejecutable v/o recursos (los assemblies, que
estarn relacionados con nuestros proyectos, se encontrarn generalmente en archi
vos de tipo dll). Por el momento, entre ellos podremos encontrar:
System
System.Data
System.Drawing
System.Windows.Forms
System.XML
App.ico: el icono que representa nuestra aplicacin. Puede ser modificado median
te el editor integrado que posee Visual Studio (aunque es recomendable trabajar
con editores externos si es que se desea construir iconos con ms de 16 colores).
u s r .c o d e
217
PROGRAMACIN Ctt
* AssemblyInfo.es:
nuestra aplicacin.
Forml.cs: archivo con cdigo fuente C#. Posee una clase que desciende de System.
Windows.Forms.Fonn y cdigo generado por el asistente de Visual Studio.
La clase Forml representa un formulario en nuestra aplicacin. Los formularios son
contenedores de controles (botones, cuadros de texto, etc.). Estos sern tiles para
construir una interfaz que le permita al usuario interactuar con nuestra aplicacin!
Existen muchos tipos de controles, el framework 1.1 incluye ms de 50 y existe en
la Red una oferta de muchsimos otros para todos los gustos (algunos gratuitos y
otros comerciales), que podremos incorporar a nuestras aplicaciones.
Entre los mtodos que el asistente escribe en nuestra clase Formulario se encuentra
uno llamado InitializeComponent. A primera vista, este mtodo no estar visible an
te nuestros ojos, pues se encuentra dentro de un bloque regin llamado Windows
Form Designer generated code . Si expandimos este bloque, encontraremos el
mtodo buscado dentro de l.
#region NOMBRE
bloque ocultable
#endregon
Figura 1. Bloque expandido.
n o m bre
QU ES UN ATRIBUTO?
Un atributo brinda informacin acerca de los datos que describen nuestra aplicacin. En el Ca
pitulo 10 hablaremos ms acerca de ellos: veremos cules son los atributos predefinidos y cmo
declarar los nuestros propios.
218
u s r .c o d e
Es importante notar que, a diferencia de las aplicaciones de tipo consola que antes
creamos, ahora la aplicacin no termina inmediatamente. Es decir que no existen
-visiblemente- ciertas lneas de cdigo que deben ser ejecutadas secuencialmente,
tas lo cual el programa se da por finalizado.
Ahora, el programa se ejecuta hasta que cerremos la ventana principal o lo exprese
mos explcitamente mediante cdigo.
De hecho, es interesante analizar el cdigo de nuestro mtodo esttico Main:
Application.Run(new FormlO);
QU ES UN BLOQUE REGION?
Los bloques regin nos permiten mejorar la legibilidad del codigo de nuestro programa. Estn
compuestos por un par de directivas dentro de las cuales todo el cdigo escrito podr ser expan
dido o eolapsade. De este modo, si el listado total de una hoja de coigo fuente es muy extenso,
con este tipo de bloques podremos reducir su longitud visible, agrupando mtodos afines.
u s r .c o d e
219
PROGRAMACIN C#
220
u s r .c o d e
A r q u ite c tu r a d e u n a a p lic a c i n W in d o w s
Por ejemplo, si el usuario presiona un botn del mouse, entonces Windows genera
r un mensaje del tipo WM_LBUTT0ND0WN) que usualmente ingresar en la cola de
mensajes de la aplicacin que posea el foco en ese momento (la aplicacin activa).
Cada aplicacin se encuentra en un bucle, esperando a que ingrese algn mensaje. Ca
da vez que un mensaje ingresa, la aplicacin lo despacha con el manejador que corres
ponda. Volviendo al ejemplo del botn del mouse, nuestro programa podra poseer
una funcin que realice una determinada tarea cuando el botn izquierdo del mouse
es presionado; si no es as, el mensaje ser tratado por un manejador predeterminado.
En C#, todo este mecanismo de bucle de mensajes queda un tanto oculto (no sera
as si programramos en lenguaje C). El sistema de despacho de mensajes ser implementado por el framework, y nosotros nos limitaremos a especificar mtodos
que respondan a eventos de un modo similar al que vimos en el captulo anterior,
cuando no sea el mismo Visual Studio quien escriba dicho cdigo por nosotros.
La clase Application
Application es una clase que representa a nuestra aplicacin. Posee una serie de m
todos y propiedades estticos que nos brindar una gran cantidad de informacin
respecto a ella. Las propiedades ms importantes son:
DoEvents: a los programadores de Visual Basic les resultar conocido este mto
do. Aunque en aquel lenguaje se encontrase como una funcin global, aqu su
propsito es el mismo: atender otros mensajes mientras nuestra aplicacin se en
cuentra trabajando en algn proceso que demande cierto tiempo. Por ejemplo, si
nuestra aplicacin se encuentra dentro de un bucle extenso, es normal que un
programador coloque dentro de l un DoEvents. De este modo, nuestra aplicacin
seguir atendiendo los mensajes en cola y evitaremos que, por ejemplo, el formu
lario quede sin repintarse.
221
PROGRAMACIN CU
CONTROLES
Para modificar las propiedades de cualquier elemento bastar con seleccionarlo, pre
sionar el botn derecho del mouse sobre l y acceder a la opcin del men contextual llamada Properties. Hecho esto, aparecer la pgina de propiedades del control
en la cual podremos observar y modificar sus propiedades, y tambin podremos
agregar mtodos que manejen sus eventos.
Adems, toda modificacin de propiedades se puede realizar mediante cdigo. Lo
que sucede es que, aqu, Visual Studio genera dicho cdigo por nosotros, pero que
no estemos utilizando este entorno no significa que estemos imposibilitados de tra
bajar con controles ni mucho menos.
Properties
P Form i
jd
im n ?
AccessibleNam e
AccessibleP.ole
A
D efau lt
El .
BackColor
| C ontrol
B aclg ro u n d lm ag e
1 (n o n e )
Cursor
D efault
Fo n t
M icrosoft Sans S e r f, ,2 5 p t
r o re C o b r
IB
Sizable
R ig h tT o le ft
No
Te*
0
C uritrulT ext
im ilicauJikuuj^
Allow Drop
False
C o n te x tM e n u
(n o n e )
Enabled
True
IrneM ode
NoC ontrol
0
0
0
0
(D ataB indings)
Tac
0
(Namc-l
F o rm !
Oraw Crid
True
0 GridStee_
................
S.
Figura 5. La p g in a de prop ie d a d e s .
Es imprtame notar que ios controles son ciases, y cuando seleccionamos un con
trol dei toolbox y iu insertamos en nuestro formulario, estamos creando una instan
cia de dicha ciase (un objeto) que Visual Studio automticamente agrega a nuestro
formulario con ei nombre que indique la 'propiedad' (ame).
222
t u r .c o d e
Controles
Existen controles que poseen representacin grfica (la mayora) y otros que no (co
mo Timer,
ImageList,
etc.):
Label
Representa una etiqueta sencilla, un trozo de texto no seleccionable ni editable por el usuario.
linkLabe
Representa una etiqueta con un enlace dentro de eHa. Cuando posamos el puntero del meuse sobre sta
y hacemos un clic, automticamente se abre el navegador predeterminado del sistema apuntando al sitio
que especifica ei control.
Button
; TextBox
Representa el clsico botn. Puede contener un texto y/o una imagen relacionada con l.
Representa un cuadro de texto editable y selecdonate (si sus propiedades as lo determinan).
Es el modo tradicional de ingresar datos por un formulario.
MainMenu
Representa el men de una ventana que es relacionado con la propiedad Men de un formulario. En tiempo
de diseo se permite modificar las opciones y propiedades de los elementos que lo componen.
CheckBox
Representa un cuadro de verificacin, fe utilizado para campos que pueden tomar dos valores (verdadero/
falso, si/no. encendido/apagado, etc.), aunque tambin se permite un tercer estado que es indeterminado.
RadioButoon
Representa un botn de opcin que puede tomar el valor de marcado o no marcado. Usualmente se combinan
varios botones de este tipo, donde su valor de verdad es mutuamente excluyente con el resto del conjunto.
GroupBox
Representa una agrupacin de controles, enmarcados y con una etiqueta. & ideal para agrupar opciones afines
dentro de un ormulano complejo.
PictureBox
Panel
Representa un contenedor de controles. Es prctico en muchos cases, como cuando se desea controlar la
propiedad de visibilidad de muchos controles afines de modo simple
DataGrid
Representa una grilla relacionada con un conjunto de datos. Facilita muchsimo la interaccin con bases
de datos.
ListBox
CheckedstBox Representa un cuadro de lista sencillo donde los elementos poseen asociados cuadros de verificacin.
Combo8oj
u s r .c o d e
223
PROGRAMACIN Ctf
1 CONTROL
ListView
DESCRIPCIN '
Representa una lista de visualizacin. Este control es muy flexible y permite diversas vistas. Es utilizado por
muchas aplicaciones, como el explorador de archivos (cuadro derecho donde se muestran los contenidos
de las carpetas).
TreeView
Representa un rbol de vistas. Este control se complementa muy bien con el lisVie. Muchas aplicaciones
hacen uso de l. como el mismo Visual Studio y el explorador de archivos.
TabControl
Representa un control de pestaas que es muy til para organizar grandes cantidades de opciones dentro
de una ventana pequea.
DateTimePicker
Representa un control en el cual se ofrece un calendario para seleccionar una fecha en l cuanto
es desplegado.
MonthCalendar
Representa un control en el cual se ofrece un calendario para seleccionar una fecha en l. Es similar
a DatePicker, excepto que aqu el calendario siempre se encuentra desplegado.
HScroliSar
VScrollBar
Timer
Representa un timer.
Splitter
Representa un divisor. Es muy til para otorgar al usuario la posibilidad de ajustar el tamao de ciertos
controles de modo automtico (como lo que ocupa un TreeView asociado a ListView).
OomainUpOown
Representa una lista de strings que puede ser modificada secuenciamente mediante botones
NumericUpDown
Representa una lista de nmeros que puede ser modificada secuenciamente mediante botones.
TiackBar
ProgressBar
RichTextBox
Representa un cuadro de texto con formato de texto enriquecido. De este modo es posible cambiar el color
y la fuente de una parte del texto que se encuentra en su interior (a diferencia de) cuadro de texto normal,
donde las propiedades de tipografa y cok eran generales para lodo el control).
ImageUs
Representa una lista de imgenes. Este control se utiliza asociado a otros que requieren imgenes
(por ejemplo,TreeView, ListView, etc.). Es posible compartido entre varios controles.
ToolTip
ContextMenu
Representa una pequea etiqueta flotante que brinda una ayuda sobre algn control del formulario.
Representa un men contexta! que puede ser abierto cuando el usuario realiza determinada accin
con nuestra aplicacin (por ejemplo, presiona el botn derecho sobre algn elemento).
Toolbar
Representa una barra de herramientas (generalmente colocada debajo del men de la aplicacin).
StatusBar
Notifylcon
Representa un icono que aparece en el tray (iconos que se encuentran a la derecha del reloj en la barra
de tareas de Windows). Es posible asociarle un ContextMenu.
OpenFileDialog
SaveFiieOialog
FolderBrowser
FontOialo
ColorDiaiog
PrintDialog
224
u s r.c o d e
Controles
En la Gua Visual 1 vemos los principales elementos que componen una ventana de
Windows
O Men.
O ListView.
O Toolbar.
StatusBar.
O ComboBox
TreeView.
6U(A VISUAL 1
DOCUMENTACIN OFICIAL
Recordemos que la documentacin electrnica que provee Visual Studio .NET es ideal para uti
lizar como referencia cuando deseamos conocer las propiedades, mtodos o eventos que posee
un control. Tambin podemos acceder a esta ayuda en linea mediante un navegador en el sitio:
u s r .c o d e
225
PROGRAMACIN CU
Veamos, ahora, cules son las propiedades comunes y ms populares de los contro
les que poseen representacin grfica:
PROPIEDAD
DESCRIPCIN
BackCotor
Enabled
Habilita o deshabilita el control (cuando un control se encuentra deshabilitado no es posible interactuar con l).
SE
f $ f y
ForeColor
<fente, tsmaitorcok,ate.).
a
Left
Height
Alto en pixeles.
Jert
Textoasociadoal control.
TextAlign
Top
Visible
Wldth
Anchoen pixeles.
Tabla 2. Propiedades de controles con representacin grfica.
Aqu estamos citando las propiedades, mtodos y eventos que consideramos ms importantes
(los que van a utilizarse con mayor frecuencia). Existen muchos otros que pueden consultarse en
la documentacin de referencia oficial que acompaa al framework SDK o a Visual Studio .NET,
o inctuso en el sitio MSDN.
226
u s r .c o d e
Formularios
Focus
Transfiere el foco al control (la entrada por teclado es dirigida al control que posea el foco).
Hide
Show_ _ _ _ _ _ _ Muestra el control (mismo efecto que fijar la propiedad Visible en true)._ _ _ _ _ _ _ _ _ _ _ _ _
Tabla 3. Mtodos de controles con representacin grfica.
Click
Doubleclick
GetFocus
KeyDown
KeyPress
KeyUp
LostFocus
MouseOown
MouseMove
Mouselp
MnuseWheel
FORMULARIOS
Si hacemos doble clic en
Forml.cs
en la pestaa
Solution Explorer,
veremos el for
lario). Aqu: podremos agregar otros controles del Toolbox, y modificar las propie
dades del formulario y de los controles. Las propiedades ms importantes son:
u s r .c o d e
en
a la h e rra m ie n ta d e M icrosoft.
227
PROGRAMACIN CU
1 PROPIEDAD
'
DESCRIPCIN
AcceptButton
BackCotor
CancelButton
: Pont
ForeColor
: lext
Location
'. 1
! MaximurtSize
Tamao mximo del formulario (en pixetes de alto y ancho). Si estas propiedades se encuentran en (0,0),
MinimumSize
Tamao mnimo del formulario (en pixeles de alto y ancho). Si estas propiedades se encuentran en (0,0),
WirtdowState
Puede set;
-Normal: ventana en modo normal
Minimized: ventana en moo minimizado.
Maximized: ventana en modo maximuado.
ControIBox
Indica si la ventana poseer los botones de minimizar, maximizar, cerrar y el men contexta! que se desprende
de ella cuando hacemos clic sobre su extremo superior izquierdo,
; Icn
MaximizeBox
Men
MinimizeBox
TopMost
Cise
, Hide
Show
Cierra el formulario.
Ocuita el formulario.
Muestra el formulario.
Tabla 6. M todos del form ulario.
I
228
u s r .c o d e
DESCRIPCIN
Activated
'
|i
Ciosed
Closing
Deactrvated
Load
Cada vez que modificamos el valor predeterminado de alguna propiedad del formu
lario o de algn control del formulario, Visual Studio agrega cdigo al mtodo InitializeComponent que mencionamos antes. Podemos verificar esto modificando, por
ejemplo, la propiedad Text del formulario. Inmediatamente despus observaremos,
en el mtodo mencionado, el siguiente cdigo:
prvate void InitializeComponentO
{
//
...
// Form l
II
...
Para esto deberemos acceder a la vista de diseo del formulario y luego hacer visi
ble la barra de herramientas llamada
Toolbox
u s r .c o d e
229
PROGRAMACIN CA
Toolbox
M y U ser Controls
D a ta
Cofiiponents
W indow s Forms
^
Pointer
A Label
A LinkLabd
j b j Button
[ab TextB ox
M ainM eru
|7 CheckBox
(
RadioButton
L j GroupBox
m
PictureBox
Pant!
n p DataGric
D 3 LfstBox
1 3 C h ecke d istB o x
!
CornboBox
ListView
TreeVIew
J J TabControl
DateTmePicker
D I M o n th C en d ar
j j ) HScroIlBar
, :
G eneral
230
u s r .c o d e
C r e a r u n a a p lic a c i n s e n c illa
buttonl
t iia S
SBHPmmamimmtBm
buttonl Click
0 .
,i> .
Paint
0 ! I '.
C hang eU IC ues
H d p R eq u ested
Q ueryAccessiblityHelp
StyleC hanged
System ColorsChanged
0 (D ataB indings)
0 l s< l.vx
D ragD rop
D ra g E n ter
Drag L e ave
D ra g O ver
GiveFeecfoack
Q u ery C o n tn u e D ra g
8 f OOH
E nter
L e av e
Validated
Valdating
U H LA "PROPIEDAD" (AME)
Cuando modifiquemos la propiedad (ame) desde el Toolbox del editor de formularios, Visual
Studio modificar el nombre de nuestro objeto instanciado a partir de la clase del control del for
mulario. Cualquier referencia a l dentro del cdigo deber ser modificada manualmente.
u s r .c o d e
2 31
PROGRAMACIN CU
Ntese que ahora la pgina muestra los eventos del control activo (en este caso, el
botn). Si hacemos doble clic sobre el evento llamado Click, entonces automtica
mente generar el cdigo requerido para que un mtodo de nuestro formulario ma
neje dicha ocurrencia. El cdigo agregado por el diseador de formularios ser:
El mtodo que trate el evento con identificador conformado por el nombre del
control, seguido por el signo underscore y del nombre del evento por tratar (como
por ejemplo: buttonl_Click).
Agregado del mtodo al evento por tratar dentro del mtodo InitializeComponent.
this.buttonl.Click += new System.EventHandler(this.buttonl_Click);
Text-
Ntese que nuestro Button se llama buttonl y nuestro TextBox se llama textboxl. Es
tos son los nombres de las instancias (objetos) que ha fijado el entorno automtica
mente. Nosotros podremos hacer los cambios que consideremos adecuados.
232
u s r .c o d e
u s r .c o d e
CtieckedUstBox
chkl
ColofOiaiog
ctallg
ComboBox
cbo
ConlextMenu
anns
Control
ctr
: ataGrid
dgr
DataList
dlst
DateFimePictef
dtp
DropDownList
cbo
FontDIafeg
fntrflg
Form
frm
Group8ox
ffl
HelpProvider
hpv
HscrollBar
hsb
Image
img
Imagest
its
Label
Ibl
linktabel
Ubi
ListBox
Ist
UstView
Iw
Men
mnu
MonthCalendar
mclr
Notifylcon
nicn
NumericUpDown
nudn
OpenFlleDialog
ofdlg
i PageSetupDialog
psdlg
Pane!
pnl
PictureBox
pie
PrintDialog
prtdlg
PrintOocuntent
prtdoc
ProgressBar
prg
RadkrButton
rdb
RadioButtonList
rdbl
RichTextBoi
rt
233
PROGRAMACIN C#
TIPO DE CONTROL
PREFIJO
TextBox,
Caso de estudio 1
Controles empleados: TextBox,
ListBox, Button.
Crearemos una aplicacin con un cuadro de texto, un cuadro de lista y tres botones.
La idea ser que, presionando un botn, se agregue el texto del cuadro a la lista, con
el segundo botn se elimine la informacin seleccionada en la lista y con el tercer bo
tn se limpie la lista por completo. La aplicacin tendr el siguiente aspecto:
*
Fo rm u la rio p rin c ip a l
A flre ja r
234
u s r .c o d e
TextBox
Sus propiedades ms importantes son:
1 PROPIEDAD
MaxLength
DESCRIPCION
Muttiline
ReadOnly
Si es verdadero, impide que el usuario pueda modificar el contenido del texto dentro del cuadro.
'
Text
TextAlign
PasswordChar
. . .
1 MTODO DESCRIPCIN ..
Clear
Limpia el control.
Tabla 1 0 . Mtodo del TextBox.
TextChanged
Button
El botn lo utilizaremos para disparar las acciones. Simplemente nos colgamos del
evento Click como lo hemos hecho anteriormente.
Sus propiedades son:
1 PROPIEDAD
DESCRIPCIN
Image
Imagelndex
Text
TextAlign
DESCRIPCIN
Click
u s r .c o d e
235
PROGRAMACIN Ctt
ListBox
una propiedad del tipo ListBox.ObjectCollection que implemento las interfaces IList,
ICollection e Enumerable;
in te rfa z
IList
ListBox
in te rfa z
Collection
in te rfa z
Enumerable
ListBox.ObjectCollection
El mtodo Add
El mtodo Add recibe un objeto de tipo Object como parmetro. Luego, como he
mos visto, todo Object debe implementar un mtodo ToString() que devuelva una
OTROS CONTROLES
En la Red encontraremos muchos sitios que ofrecen libreras de controles para bajar e integrar
muy fcilmente a nuestras aplicaciones. ComponentOne es uno de los ms conocidos en este as
pecto (www.componentone.com).
236
u s r.c o d e
representacin del contenido del objeto en formato texto. Dicho texto ser el que
exhibir el ListBox.
Adems, el hecho de que toda clase sea descendiente de Object resulta en que el ListBox
puede almacenar en su interior cualquier tipo de objeto definido por nosotros.
El cdigo que especificaremos para agregar texto a nuestra lista ser:
IstOsuarios.Items.Add(txtsuario.Text);
El mtodo Clear
Utilizar el mtodo Clear es muy sencillo, no posee parmetros.
Simplemente escribiremos:
IstOsuarios.Items.Clear();
El mtodo Remove
El mtodo Remove recibe un objeto de tipo Object como parmetro. Este objeto se
r el que la lista misma nos informe que est seleccionado.
Escribiremos, entonces:
lstsuarios.Items.Remove(IstUsuarios.Selectedltem);
Ahora, agregaremos una verificacin extra. No deseamos que el usuario pueda agre
gar a nuestra lista dos nombres iguales. Si esto ocurre, se deber informar esta situa
cin mediante un cuadro de mensaje. Tampoco deseamos introducir valores nulos.
Por lo tanto, el cdigo que invoca el evento Click de nuestro primer botn ser:
if (txtsuario.Text == "")
return;
if (lstsuarios.Items.Contains(txtsuario.Text) == false)
lstsuarios.Items.Add(txtsuario.Text);
else
MessageBcx.Show(''El valor ya se encuentra en la lista");
u s r .c o d e
237
PROGRAMACIN CU
Items
Selectedlndex
Selectedlndices
Seiectedltem
Selectedltems
} SelectedValue
Sorted
FindString: busca el primer tem de la lista que comienza con el texto especificado.
Otros eventos importantes:
Agregar.
Existe una propiedad de casi todos los controles llamada Enabled, que permite ha
bilitar o deshabilitar un control. Luego, los cuadros de texto poseen un evento lla
mado TextChanged, que es invocado cuando existe una modificacin sobre el con
tenido del cuadro.
Utilizaremos la propiedad y el evento citados para cumplir nuestro cometido.
236
usr.code
! Formulario Principal
Uno
g ro u p B o x l
!<
FaoBttorii
C ra d io 8 u tto n 2
C
radioB uttonS
(7 checkB ox 1
Figura 12. El manejo de botones de opcin y cuadros
17 checkB ox2
Las propiedades que marcan o desmarcan los botones de opcin, as como los cua
dros de verificacin, es Checked. Esta opcin es booleana, por lo que acepta dos va
lores: verdadero
u s r .c o d e
(true)
o falso
(false).
239
PROGRAMACIN CU
{
lblRBSeleccionado.Text = "Uno";
}
prvate void rdb2_CheckedChanged(object sender, System.EventArgs e)
{
lblRBSeleccionado.Text = "Dos";
}
private void rdb3_CheckedChanged(object sender, System.EventArgs e)
{
lblRBSeleccionado.Text = "Tres*;
}
private void chkl_CheckedChanged(object sender, System.EventArgs e)
{
if (chkl.Checked)
lblEstadoCBl.Text = "Chequeado";
else
lblEstadoCBl.Text = "No chequeado";
}
private void chk2_CheckedChanged(object sender, System.EventArgs e)
{
if (chk2.Checked)
lblEstadoCB2.Text = "Chequeado";
else
lblEstadoCB2.Text = "No chequeado";
}
Podemos encontrar el cdigo completo de esta aplicacin en el proyecto GUIApp2,
que se puede descargar desde el sitio oficial del libro
240
(onweb.tectimes.com).
u s r .c o d e
Caso de estudio 3
Controles empleados:
ListView, ImageList.
3; . y ggf f i
Columns
Coleccin de columnas.
FullRowSelect
GridLines
Items
LabelEdit
Selectedlndices
Selectedltems
Clear
Elimina todos los elementos y columnas del control (no confundir con el Clear de la propiedad Items).
Sort
ColumnClick
ItemCheck
SelectedlndexChanged
t i ! ! PROPIEDADES COMUNES
Gracias al buen diseo de la librera BCL, muchas de las propiedades que encontraremos en con
troles que nunca antes hemos utilizado nos sern familiares. Si al control se le puede fijar un tex
to, seguramente se realizar por medio de la propiedad Text. Esto no ocurra en versiones ante
riores de Visual Basic ni en la librera VCL de Borland.
u s r .c o d e
241
PROGRAMACIN C#
III
242
u s r .c o d e
Adems, antes de utilizar el control deberemos especificar las columnas que posee
r. Esto se puede realizar en tiempo de diseo (propiedad Colunins):
Hembeis:
columnHeadet 1 Properties.:
HHH
1 IcolumnHeadet!
'B
E (DyrvamicPropcttli
4i a .
21 colutcnHeadirv
r
(N-ar.ne)
columnHeadcrl
Modfier;
Prvate
Tea
Nombre
Te:<tAIn
Lef:
Wldth
146
1
Add
gemove
O):
Cancel
Help
PROGRAMACIN C#
columnas, el mtodo Add acepta objetos del tipo ColumnHeader, por lo que debemos
crear dicho objeto con anterioridad.
Notemos que en el listado anterior no reutilizamos el objeto
lumnas, sino que creamos objetos nuevos. El asunto es que aqu el control almace
na referencias a las columnas, y si utilizamos los mismos objetos, el control no se
comportar como esperamos que lo haga.
Respecto a las filas, el modo de manejarnos ser similar:
ListViewItem lvi;
lvi = new ListViewItem("primera fila, primera columna");
lvi.Subltems.Add{"priinera fila, segunda columna");
1vi.Subtems.Add("primera fila, tercera columna");
lvwProcesos.Items.Add(lvi);
lvi = new ListViewItem("segunda fila, primera columna");
lvi.Subltems.Add("segunda fila, segunda columna");
lvi.Subltems.Add("segunda fila, tercera columna");
lvwProcesos.Items.Add(lvi);
// ...
u rr.c o d e
M a n i p u l a c i n d e lo s c o n t r o l e s b s i c o s
nombres de los ImageList que posee nuestro formulario. Una vez que selecciona
mos el nico que hemos agregado, la relacin ha sido consumada.
Las imgenes dentro del ImageList poseen un ndice, deberemos referirnos a alguna
de ellas por medio de este nmero. En nuestro ejemplo, hemos agregado un peque
o bitmap de 16x16 al ImageList que referenciaremos por su ndice: el nmero cero.
ListViewItem lvi;
lvi = new ListViewItem("primer fila, primer columna'
);
lvi.Subtema.Add("primer fila, segunda columna*);
lvi.Subtems.Add("primer fila, tercer columna");
ivi.Imagelndex = 0;
lvwProcesos.Items.Add(lvi);
Como se puede apreciar en el listado anterior, antes de agregar el objeto del tipo
En el ejemplo usamos un control de tipo ComboBox para elegir la vista del ListView.
Tambin colocamos un
View.
Con
r CONTROLES CONOCIDOS
Los controles que ofrece la librera BCL son les que podremos encontrar en cualquier otra apli
cacin convencional de Windows, y son lo suficientemente vastos como para adapta-se a much
simas necesidades.
u s r .c o d e
245
PROGRAMACIN CU
6 S formuario Principal
fD etafc
Nombre
| ( 7 Grilla Visible
I Tamao
Q i o s . p ic
6730
tA
|S 108.pic
6JOO
tA
| 3 .p c
6710
b b b b m w
i''-'"
,m
tA
m
E fb o o tiri
211
tA
SfiBootfont.bin
4952
ca
ffjCONFIG.SYb
cA
[jdatdbase.bdb
180633o
tA
23) debug.txt
1689
(A
p l ii b e r f s y s
536399372
tA
IO .S Y 5
cA
)fn fc 7 l.d *
1060364
cA
3] m fc7tu.dll
1047552
tA,
S M 5DQ 5.SY5
tA
t) msvcp71.dll
499712
tA
||m svcr7l.dl
348160
tA
|N TD E TEC T,C O M
47564
tA
B r it U r
250640
cA
lp a g e fite .s y s
805306368
cA
459646
tA
SjThum bs.db
7680
tA
@ )vefdurd,fcm p
196664
tA
iS fZ inioInstal.tx t
6316
tA
3 ;
tA
GUIAppS,
Caso de estudio 4
Controles
ListView,
246
iCollection e iEnumerable.
u s r.c o d e
TreeView.
Antes de crear la nterfa2 de usuario de nuestra aplicacin, ser conveniente conocer un poco la
ciencia que subyace tras su diseo. Existen libros que tratan este tema, y varios artculos que po
dremos encontrar en la Red, como en www.medlcalcomputingtoday.com/flagui.html.
u s r .c o d e
247
PROGRAMACIN Cff
TreeView:
Tngase en cuenta la pequea y sutil diferencia que posee este listado en compara
TreeView), sino tn l,
Esta operacin tambin podra repetirse con tn2, es decir que cada
n od o
puede po
seer uno o ms nodos hijos sin que el control especifique lmite alguno.
Para limpiar los elementos de la coleccin no hay novedades; deberemos escribir:
tvwElementos.Nodes.Clearf);
Luego existen algunas otras propiedades de inters de la clase TreeView, que son:
1 PROPIEDAD
CheckBoxes
Imagelndex
Indent
labelEdit
Selectedlmagelndex ndice de imagen de nodo seleccionado por predefinicin que se utilizar en los nodos.
Showtmes
ShowPlusMinus
ShowRootlines
TopNode
VisibleCount
248
usr.code
M a n i p u l a c i n d e lo s c o n t r o l e s b s i c o s
A H I
AfterCheck
AfterCollapse
AfterExpand
AfterSeiecl
BeforeCheck
BeforeCollapse
BeforeExpand
BeforeSetect
USFormulario Principal
Elemento seleccionado
Uno
|Cos
Tres
Algunas propiedades del TreeView
|
jr
17 M o strar Sheas
[7 Mostrar cuadrlos
UJ_I
17 Habilitado
249
PROGRAMACIN CE
Caso de estudio 5
Controles empleados: mltiples formularios, Men,
TrackBar, ProgressBar.
Hasta ahora, nuestras aplicaciones tenan slo un formulario. Pero usualmente las
aplicaciones poseen ms de uno. Para agregar un nuevo formulario a nuestra apli
cacin, slo deberemos seleccionar nuestro proyecto desde el Solution
sionar el botn derecho del mouse e ingresar en la opcin Add/Add
Explorer, pre
Windows Form....
MJWfbPefaence.. NwWn
. --..ir |LI M | e t ! l
5* te>
.3MdWnom&nOctwj
JJ AJJ(r/*edFarr. j
i Conti..
;C WfSUIA*'.
/ MUrrrteCrrtrul. j.V-inrri* .VI.J >-<Uxl
)
....*-.
^ 'jX Bemc-f
MJCcfConnt.
i .km- :
ftspwtJH Rtrjc
t MQku.
II < -tW, l. j)
CUtApcSjg
y ij
i i;
)
Bh"oikiffc
LJ. : )
i:.:|
>
3
:J -f ir........
Merf
.......... ..."...... ....~
i Outxxi
IX
joefcuq
i t*W
.f.UlV
o
o
fc
ti
n
:
l
o
*
!
'
.
c
:
\w
|
n
d
>
v,\u
i
e
ro
i
v
(l
.M
i
W
l
uiu;ik\vl
1
.
IJ.'
.
ltici,
lll
d
i
)
H
e
lyitrli
nl-: Ut4.J-1.
Cvccifi.y
*:k^7
UXinAtvvj
|f .feraiU.O
jtC.USIC
Ac*of.C_>
t*7?',.icJJJ Jo
*,)C
.w
i CCIAffS..,.': lLoe.J..
ed.
Nvri^v
<
.....V
Ecunilsa..
te:,
Main,
Forml
pero
ShowDialog,
do modal; esto significa que el usuario no podr seguir interactuando con otros for
mularios abiertos de nuestra aplicacin hasta que se cierre el recin abierto.
250
usr.code
Control Men
GUAVISUAL 2
mtubrto Principal
E25E3 \21:
Ablir Form ulario 2
&
Sal
^ mainMenut
Entonces, escribiremos cdigo para el evento Click de la opcin de men que espe
cifiquemos para abrir el segundo formulario; este cdigo ser:
Form2 frm2 = new Form2();
fna2.Show ();
u s r .c o d e
251
PROGRAMACION CS
Pero si el usuario no abre nunca el formulario 2, de todos modos lo habremos instanciado al inicio de la aplicacin. Tal vez sta no sea una buena idea: depender de
la importancia del formulario 2 para la aplicacin: si siempre ser abierto o no.
Una tercera opcin podra ser inicializar la variable
desee abrir el formulario, escribir:
if (fnn2 == nuil)
rm2 = new Fono2();
frm2.Show();
Cuando la aplicacin se inicie, no se solicitar memoria para frm2. Esto slo se har
la primera vez que el usuario desee abrir dicho formulario. Lo malo de esta solucin
ser que siempre, antes de utilizar alguna propiedad o mtodo de frm2, deberemos
verificar que no sea nuil, o generaramos una excepcin en tiempo de ejecucin.
En nuestro ejemplo, el formulario 2 es muy sencillo. Slo posee un botn que lo oculta:
HideO;
Pero frm2 nunca ms podra ser abierto; por eso deberemos hacer otro new
Form2().
u s r .c o d e
En nuestro ejemplo, nos colgamos del evento Scroll del TrackBar que se invoca ca
da vez que alguien quiere modificar el valor de la barra (por cdigo o por interac
cin con el mouse), y dentro de este evento escribimos:
prgMedidor.Valu = tbrBarra.Valu;
El valor de un TrackBar se lee y se escribe del mismo modo que el control ProgressBar: a travs de su propiedad Valu.
Existen otras propiedades generalmente modificadas cuando se utiliza este tipo de
controles, que son:
Mnimum
M I RESUMEN
En este captulo hemos dado el puntapi inicial en la construccin de aplicaciones con con
troles. .NET hace esto m u y sencillo gracias al excelente diseo que posee la librera BCL. En
los prximos captulos, todos los ejemplos que estudiemos estarn basados en aplicaciones
de este tipo, y cuando veamos alguna propiedad o mtodo nuevo relacionado con los contro
les, lo indicaremos convenientemente.
usr.code
253
J 3 ACTIVIDADES
TEST DE AUTOEVALUACIN
EJERCICIOS PRCTICOS
jugador acierte.
RadioButton?
254
usr.code
Captulo
PROGRAMACIN C#
Acceso a datos
externos
Un programa que no interacte con
elementos externos no resulta de mucho
inters. En este captulo veremos cmo
acceder a archivos de texto y binarios,
como tambin a bases de datos
relacinales por medio de AD0.NET.
Archivos
256
File
.1 1 1 J
Tipos de streams
Manipulando archivos de texto
Manipulando archivos binarios
56
256
257
260
Bases de datos
SQL
Elementos de una base
de datos relacional
Un ejemplo sencillo
266
269
263
. 2 6 5
279
281
......
282
Actividades
PROGRAMACIN C#
ARCHIVOS
Todos sabemos que un archivo es una coleccin de datos situada en algn disposi
tivo de almacenamiento, y que posee un nombre por medio del cual podemos refe
rendario para interactuar con l.
La librera BCL ofrece muchas clases para facilitarnos su manipulacin. De stas,
tal vez la ms popular sea la clase File.
File
La clase File se compone slo por mtodos estticos que nos permiten crear, copiar,
eliminar, mover y abrir archivos. Veamos algunos de sus mrodos ms importantes:
Copy
Copia un archivo.
Create
Crea un archivo.
Delete
Existe
Move
Mueve un archivo.
GetAltributes
Open
Abre un archivo.
DpenText
SetAttributes
Lo que no posee la clase File son mtodos para leer o escribir el contenido del archivo.
Para esto deberemos utilizar los objetos que nos devuelven los mtodos Create y Open.
Estos mtodos nos devolvern diversos tipos de streams (flujos) con los cuales s po
dremos manipular el contenido de los archivos.
Tipos de streams
Existen diversos tipos de streams:
Streams de memoria (clase MemoryStream): la fuente de datos se encuentra sita
da en la memoria de la computadora.
256
u s r .c o d e
Archivos
Todos estos tipos de streams descienden de la misma clase Stream, como se puede
apreciar en el siguiente diagrama de clases:
Q Q QU ES UN STREAM?
Un stream es un objeto que encapsula una secuencia de datos. Los streams de lectura producen
informacin, mientras que los streams de escritura la reciben. Los streams abstraen al progra
mador del modo concreto en el cual se opera con la fuente de datos.
u s r .c o d e
257
PROGRAMACIN C #
H B B
' * Anotador
Archivo
Requerimiento:; mrrmos do la splicacin
En la primera lnea hacemos uso del mtodo esttico OpenText de la clase File. Estemtodo nos retornar una referencia a un objeto
StreamReader,
Cise
Peek
Cierra el stream.
Devuelveel simiente carcter del stream, peronoloconsume (esto signiiea queen la prximaoperacin de Peek
oReadvolveremosa leer el mismocarcter).
Read
Readne
u s r.c o d e
Archivos
En este caso empleamos el mtodo CreateText de la clase File, que nos devolver un
objeto del tipo StreamWriter.
El objeto StreamWriter posee, principalmente, los siguientes mtodos:
Cise
Cierra el stream.
flosti
Respecto a los controles de dilogo, su utilizacin es muy sencilla. Pero cabe desta
car que no tenemos por qu utilizarlos; aqu los introducimos simplemente porque
es habitual ofrecer este tipo de dilogos al usuario cuando se solicita que se seleccio
ne un archivo para abrir o guardar.
dlgAbrirArchivo.Title
Abrir archivo de texto*;
dlgAbrirArchivo.Filter = "Archivos de texto (*.txt)|*.txt|Todos
los archivoB (*.*)|*.** ;
if (dlgAbrirArchivo.ShovDialogO == DialogResult.OK)
{
// Almaceno el nombre
nombreArchivo = dlgAbrirArchivo.FileName;
// . . .
}
de nuestro formulario.
259
PROGRAMACIN CS
dlgGrabarArchivo.Ti
tle = "Grabar archivo de texto";
dlgGrabarArchivo.Pilter "Archivos de texto (*.txt)j*.txt|Todos
los archivos (*.*}}*.*" ;
if (dlgGrabarArchivo.ShowDialogO == DialogRestilt.OK)
.
nombreArchivo a dlgGrabarArchivo.FileName;
// ...
Como se puede apreciar, ambos listados de cdigo son muy parecidos, y es que am
bos tipos de dilogo poseen casi las mismas propiedades, ya que son descendientes
de la clase FileDialog.
Veamos sus propiedades ms utilizadas:
PROPIEDADES
DESCRIPCIN
FileName
1 FBtet
Especifica las opciones <te filtro que se leofrecern al usuario para que elija un tipo de archivo vlido.
InilialDirectoiy
Y sus mtodos:
b
ShowDiaiog
u s r .c o d e
Archivos
{
BinaryReader br = new BinaryReader(fs);
varBntera br.ReadInt32();
varString * br.ReadStringO;
varPloat = br.ReadSingleO;
br. Cise ();
}
f8.Cise 0 ;
Read
ReedBoolean
ReadByte
ReadDcuble
Readlntl6
Read)nt32
Readlnt64
ReadSByte
ReadSingle
ReadUln!l6
ReadUlnt32
u s r .c o d e
261
PROGRAMACIN C8
PileStream fs = Pile.OpenWrite(nombreArchivo);
i (fs 1= nuil)
{
BinaryWriter bw a new BinaryWriter(s);
bw.Write(varRntera);
bw.Write(varString);
bw.Write(varFloat
);
}
fa.CloseO
Para la escritura del archivo binario procedimos de un modo similar. En este caso
slo utilizamos el mtodo Write de BinaryWriter, no existe la necesidad de especifi
car diversos mtodos con identificadores diferentes, pues el mismo Write est sobre
cargado para todos los tipos de datos que soporta.
Chars
Int32
Byte
Bytes
Decimal
Double
Int64
SByte
Char
Intl 6
Single
Soporta:
U lntl
UInt32
UInt64
D Q UTILIZANDO EL NAMESPACE 10
Debido a que todas las clases de manipulacin de streams se encuentran bajo el espacio de
nombres 10, ser conveniente que agreguemos la siguiente lnea al comienzo de nuestro archi
vo de cdigo fuente: using System.IO;.
262
u s r .c o d e
Bases de datos
BASES DE DATOS
Una base de datos (DB, por su nombre en ingls) es una coleccin de informacin
relacionada. Fsicamente podra estar compuesta por uno o ms archivos estructu
rados internamente para optimizar la manipulacin de los datos que contienen.
Hoy en da, muchsimas aplicaciones poseen la necesidad de almacenar sus datos en
un medio eficiente, como una base de datos, para su posterior consulta o manipu
lacin. Para esto se podra seleccionar entre muchos productos gestores de bases de
datos que existen en el mercado. Los ms populares actualmente son:
framework .NET ofrece una serie de clases que facilitan en gran medida la in
III
Desde .NET podremos conectarnos a casi cualquier base de datos que exista. Si sta no ofrece
clases especificas de ADO.NET, siempre podremos seguir conectndonos a ella mediante ODBC
(Open DataBase Connectvity\.
u s r .c o d e
263
PROGRAMACIN C#
Aplicacin ADO.NET
DataSet
DataReader
Adaptcr
Connection
Data
Base de
datos
DataSet
DataAdapter
DataRowCollection
Comando SELECT
DataColumnCollection
Connection
Comando INSER
Command
Comando UPDATE
DataReader
Comando DELETE
ConstraintCollection
Base de
datos
DataRelatlonCollection
XML
264
u s r .c o d e
Bases de datos
SQL
Podemos encontrar una gran variedad de productos gestores de bases de datos.
Afortunadamente para todos nosotros, existe un lenguaje declarativo estndar de
consulta llamado SQ L (Structured Query Language).
Con SQL no slo estaremos posibilitados para consultar la informacin almacena
da en la base de datos, sino que tambin nos permitir agregar, modificar y elimi
nar informacin, as como modificar las estructuras lgicas donde los datos se en
cuentran contenidos (por ejemplo, tablas).
No liaremos aqu una gran introduccin en el lenguaje SQL, slo nos limitaremos
a nombrar los principales comandos y dejaremos ai lector la tarea de profundizar en
l, en caso de que lo considere conveniente.
Existen tres tipos de comandos SQL:
DML
[U
Conocer SQL para trabajar con bases de datos es muy recomendable. Sin embargo, si no nos ma
nejamos muy bien con este lenguaje, podremos utilizar los asistentes que ofrecen los controles
de AD0.NET para que sean ellos los que construyan los comandos SQL por nosotros.
u s r .c o d e
265
PROGRAMACIN CU
Tabla: es el elemento fundamental. Una tabla representa una entidad y sus rela
ciones; contiene unidades de informacin denominadas registros, que especifican
valores para cada campo que la tabla puede almacenar (determinados en colum
nas). Posee un nombre mediante el cual se referencia.
CDIGO
NOMBRE
APELLIDO
EDAD
juan
ritz
20
pedio
pa
23
carlos
toms
25
ivan
werty
26
-Columnas
-Registros
ndices: los ndices son estructuras de datos que se relacionan con una o ms co
lumnas de una tabla, con el fin de acelerar el proceso de bsqueda de registros
cuando se utilizan los campos de dichas columnas como criterio.
son tablas virtuales creadas dinmicamente a partir de consultas preesta
Vistas:
Disparadores (triggers):
DDL).
emplear aplicaciones ms amistosas que nos faciliten la tarea mediante una interfaz
de usuario (estas aplicaciones se encargan de generar los comandos SQ L que corres
pondan a partir de nuestra interaccin).
AD O .N ET ofrece un poderoso conjunto de clases para manipular la informacin
de la base de datos. Ejecutar comandos SQL es slo una parte nfima de sus funcio
nalidades. Veamos cules son las clases ms importantes.
266
u s r .c o d e
Bases de datos
DataSet
Un
DataSet
DataTable).
DataSet
DataRelationCollection
DataTable Collection
DataTable
DataColumnCollection
DataRowCollection
ConstralnCollection
Las tablas no tienen por qu estar colocadas dentro del DataSet de modo indepen
diente, sino que tambin pueden poseer relaciones que se expresan a travs de ob
jetos que se encuentren dentro de l.
PROGRAMACIN C#
Connection
Mediante un objeto del tipo Connection se realizar la conexin a la base de datos.
DataAdapter
Hemos mencionado anteriormente que un DataSet se alimenta de una fuente de da
tos, que en este momento para nosotros sera una base de datos.
El modo en el cual el DataSet se conecte a dicha base ser por medio de un objeto
del tipo DataAdapter, que se encarga de hacer de puente para la informacin, ya sea
desde la base hacia el DataSet o por el camino inverso.
DataSet
Connection
Comando INSERT
Com m and
Comando UPDATE
DataReader
Comando DELETE
Internamente, un DataAdapter estar compuesto por comandos SQL, que sern uti
lizados para las operaciones que el DataSet requiera realizar con la base.
Command
Representa un comando SQL, el cual se ejecuta a una fuente de datos utilizando
para tal propsito un objeto del tipo DataAdapter.
268
u s r .c o d e
Un ejemplo sencillo
DataReader
Permite navegar hacia adelante por registros de una base de datos mientras se est
conectado a ella. Una aplicacin suele optar por utilizar DataReaders, en lugar de
DataSets, cuando la cantidad de datos por traer es muy grande (con DataSets se uti
liza mucha memoria) y se requiere un acceso de consulta muy rpido.
UN EJEMPLO SENCILLO
Ahora que hemos introducido los principales conceptos deADO.NET, podremos
ver un sencillo ejemplo. En nuestro caso utilizaremos una base de datos de tipo
Microsoft Access. Esta contendr slo una tabla que manipularemos utilizando
C# y las clases ADO.NET.
Nuestro primer paso ser crear una pequea base de datos con una tabla sencilla,
que luego consultaremos desde una aplicacin C#.
ID
NOMBRE
EDAD
CALLE
PISO
DEPTO
usuarol
25
CalleX
4555-0001
usuano2
26
CalleY
4555-0009
usuario3
23
CalleZ
4555-0201
usuario4
22
CalleW
4555-0441
TELFONO
Con la tabla creada veremos ahora cmo operar desde Visual Studio. Para esto
construiremos una aplicacin con interfaz de usuario del modo tradicional y arro
jaremos un control
DataGrid al formulario.
El control DataGrid es bastante prctico para interactuar con DataSets. Una vez que
ste se encuentre colocado en la porcin del formulario que ms nos agrade, agre
garemos otros controles ms. En este caso, dentro del
II
Toolbox,
cambiaremos de
Utilizar una base de datos -en vez de archivos binarios- trae muchsimas ventajas debido a que
son sistemas creados para organizar y gestionar informacin. Entre otras caractersticas, podre
mos contar con integridad referencial de datos, seguridad de acceso, optimizacin de consultas,
etc. El uso de archivos binarios se justifica slo en aplicaciones muy sencillas.
u s r .c o d e
269
PROGRAMACIN C#
Connection
DataAdapter
Command
Connection
[ U I ALTERNATIVAS DE CONEXIN
Es posible que, en ciertas bases de datos, tengamos varias alternativas para conectarnos a ellas.
En el caso de Oracle, por ejemplo, podremos utilizar OracleConnection y OdbcConnection. Siem
pre ser mejor usar el objeto especfico creado para dicha base, debido a que posee optimizacio
nes propias del fabricante.
270
u s r .c o d e
U n e je m p l o s e n c i ll o
De la misma manera que en el caso anterior, los objetos del tipo Command implementan la interfaz IDbCommand.
OleDb,
en principio no habr
OleDbConnection
y se lo agregamos a
nuestro formulario. De este control ser importante especificar la propiedad ConnectionString, que ser la que se ocupe de indicar al objeto la ubicacin y el modo
de conectarse a la base de datos.
Esta propiedad puede ser estipulada por cdigo o bien por medio de un asistente
que se dispone con esta finalidad.
usr.code
271
PROGRAMACIN Ct>
PASO A PASO
<
>
r&ifl^ente'>j
Aceplai I
Cancela! i
Ajajda
tioba ccnen
Acopla |
272
Cancelar
Apjria
u s r .c o d e
U n e je m p l o s e n c i ll o
Cmtd
d >
Aqu deberemos seleccionar el objeto de tipo Connection por el cual nos conec
taremos a la base de datos (en nuestro caso ser el que hemos creado en las l
neas anteriores).
01 Dala Adapter Configuration Wizard
K
'/
Choose froro the k t of data conrecttons currenty In Server Explorer a add a new
connection If the me you wentisnotfeted.
vert9a\VTtejiAcqCS,'hn\Ciet!(Jl
u s r .c o d e
New Connection...
273
PROGRAMACIN C#
J f
Spec#y a Select statemant to load data, andthe wwaid w# genesHe the Insert, Update,
and Mete statements lo save data cherges
Specfy a Select statarent, and the wizard vi# generate new stered procederes te
select, insert, updete, and dtete recode.
Ahora deberemos especificar el comando SELECT, por medio del cual se traer la
informacin desde la base de datos a travs del DataAdapter. Si no sabemos SQL,
podremos utilizar un creador de consultas presionando del botn Query
Builder.
Type in your SQL Sded statemer* or use the Query BufcJer to gr'dpbcelly desjgn the query.
Wfvat data shouW the data adapter load loto the dataset?
i
Advanced Optlorc...
Query Builder...
Cancel
274
<6A
u sr.code
U n e je m p lo s e n c illo
1 m tk w i* *
; * (A l Colemos)
.'C e
QS3MMI
:id
v i
|SortOrdw
lOtoia
U/Oircs
Usuarios
Ff
III
D Una vez que hemos cerrado el Query Builder, ste nos deja el comando SELECT
escrito en nuestro cdigo.
u s r .c o d e
275
PROGRAMACIN C#
En el ltimo paso, el asistente nos informa los comandos que fueron creados por
nosotros para manipular la informacin seleccionada.
$ Data Adapter Configuraron Wizard
V ie w W iz a r d R e s u lts
Review the fot of la (he wizord has performed. Ckk Fruih (o
complete or Back (o make charges.
Details:
^ Generated SELECT siatemeot.
* Generated table mappings.
F Generated IN3ERT statement.
* Generated UPDATE tatemar*,
r1 Generated CELETE statenvent,
Cancel
OleDbConnection,
<feack j
| sh
nuestro OleDbDataAdapter, que se encargar de hacer de puente para traer los datos
276
u s r .c o d e
Un ejemplo sencillo
de la base. Pero dnde los alojar? Podramos especificar para ello un DataSet pro
gramticamente o en tiempo de diseo.
Para especificarlo en tiempo de diseo deberemos seleccionar el DataAdapter, acce
der a su men contexta! y luego seleccionar la opcin Generate Dataset....
Cut
[fe Copi;
fe <*<
X
(dete
IS1 Properties
dbComertion
oleDbOai WWPW7---
_ J
? fjew.
hoose Vitilch teb!e(s) to add to the dataset:
y UsuarlosdeDbOataAdapterl)
OK
Cantei
Help
u s r .c o d e
277
PROGRAMACIN Ctt
Completada esta operacin, notaremos que nuestro proyecto posee una nueva
clase. Esta clase es un DataSet tipado, creado especficamente para nuestras tablas.
Esto quiere decir que ahora podremos manipular las columnas, los registros, las
restricciones y las relaciones de nuestro objeto por medio de propiedades y mto
dos, como si fuese un objeto ms.
Veamos ahora cmo, casi sin escribir cdigo, podremos utilizar el control
DataGrid
DataSet
hagan efectivos en la fuente (en este caso, nuestra base de datos). Para hacer los cam
bios efectivos deberemos utilizar el DataAdapter en sentido inverso (conceptualmen
te, claro). Podremos efectuar esta tarea escribiendo:
adpsuarioa.pdate(dssuarios, 'Usuarios");
278
u s r .c o d e
U n e je m p lo s e n c illo
DataSet
guiente modo:
// Creo un nuevo registro
DataSetsuarioe.BuariosRow newrow * dsOsuarios.Usuarios.NewsuarioaRowO;
);
:y
.vSSR
u s r .c o d e
279
PROGRAMACIN C
);
dsArchivos.Tables.Add(tbArchivos
Del paso 2:
Directorylnfo di = new DirectoryInfo("c:\\");
{
// 2.a. Creo un registro
DataRow dw s dsArchivos.Tables ["Archivos"] .NewRowO ;
Prstese especial atencin a que los registros se encuentran compuestos por infor
macin de consulta de archivos a un directorio arbitrario (esta tarea es simplemen
te para tomar datos de algn lugar).
280
u s r .c o d e
Un ejemplo sencillo
Y, finalmente, el paso 3:
dgDirs.D&taSource = dsArchivos.Tablea("Archivos*];
En este ltimo caso, el control tambin nos permite especificar, no una tabla, sino
un DataSet completo. En dicho caso ofrece un enlace con los nombres de las tablas
que componen el DataSet para ingresar en ella.
-*DataSets creado...
Archivos d e \
; nombre
f^~|fB]fx)
tamao
jdebug.txt
1689
ihkerfil.syj
536399872
iIO.SYS
mfc7l.dll
1060864
mfc71u.cl
1047552
HS005.SYS
jmsvcp71.dB
499712
:msvcr71.t0
348160
NTDETECT.C
47564
jntldr
2S0640
pagefile.sys
805306368
;5
tkb.txt
'Thumb.db
459646
7680
RESUMEN
En el mundo real, las aplicaciones interactan con datos externos a la aplicacin misma: a r
chivos, bases de datos, objetos remotos, etc. En este capitulo hemos introducido varios con
ceptos importantes y, en particular, AD0.NET, un tema del cual podramos escribir un libro
entero. En el siguiente captulo estudiaremos cmo manejar los errores que podran produ
cirse en nuestros programas por medio de la manipulacin de excepciones.
u s r .c o d e
281
J T
a ct y id a d s
TEST DE AUTOEVALUACIN
EJERCICIOS PRCTICOS
que corresponda?
Arifoo
282
u s r .c o d e
PROGRAMACIN C
Captulo
Manejo
de excepciones
Qu sucede cuando en la ejecucin
de nuestros programas las cosas no salen
de la manera prevista? 6Qu ocurre
cuando no es posible encontrar aquel
archivo que necesitamos abrir o cuando
el usuario ingresa un dato invlido?
C# ofrece un sistema de manejo de
excepciones muy completo que nos
permitir lidiar con estas situaciones
de un modo muy sencillo y efectivo.
Tratamiento de errores
Encerrar las excepciones
284
28B
Clases de excepciones
Generar excepciones
287
234
Resumen
Actividades
296
297
298
PROGRAMACIN C#
TRATAMIENTO DE ERRORES
Sabemos que los programas que escribimos pueden poseer errores, algunos de los
cuales son detectados en tiempo de compilacin (errores de sintaxis, semnticos,
etc.), pero otros podran permanecer inadvertidos por ser errores de lgica o raquerir ciertas condiciones para manifestarse.
Si debemos efectuar una divisin y el denominador es provisto por una variable in
gresada por el usuario, el proceso de compilacin finalizar de manera satisfactoria.
Pero en nuestro programa podra producirse un error en el supuesto caso de que el
usuario especificara cero como denominador.
Por otro lado, siempre existe la posibilidad de que se presenten situaciones impre
vistas, a pesar de no que no existan errores de programacin en nuestra aplicacin
(siempre y cuando no tomar todas las precauciones en cada caso no sea considera
do por nosotros como un tipo de error).
C# ofrece un sistema para manejar este tipo de situaciones, heredado del lenguaje
C++, que se denomina manejo de excepciones ( exception handli?ig).
Una excepcin es una alteracin en el flujo de ejecucin normal de la aplicacin. El
sistema de manejo de excepciones tiene como principal finalidad permitir el trata
miento de errores en nuestros programas.
Hasta el momento, el cdigo desarrollado por nosotros no ha hecho tratamiento de
excepciones. Por ejemplo, la lnea de cdigo que observamos a continuacin pare
cera no poseer inconveniente alguno:
int num = Convert.ToInt32 (txtNum.Text);
In g re s e un nm ero
20
Convertir
284
u s r .c o d e
Tratamiento de errores
Bieak ~~lj
|[
Continu
!ov-
Help
raSs
Continu
S.uit
Lo que ocurri fue que el mtodo esttico ToInt32 de la clase Convert arroj una ex
cepcin. Este es un modo de avisarnos que algo sali mal, por lo tanto deberamos
hacer algo al respecto o la aplicacin no podr seguir su curso normal.
u s r .c o d e
try..catch.
285
PROGRAMACIN Cfl
{
num = Convert.ToInt32(txtNum.Text);
: }
catch
'{
Me8sageBox.Sbow(,,Se ha producido una excepcin");
alguna dentro del cdigo del bloque try, el flujo de ejecucin saltar automtica
mente a la primera lnea del bloque catch. Luego, la ejecucin del programa conti
nuar normalmente, si es que no establecemos lo contrario.
Es cierto que tambin podramos realizar las verificaciones del caso para evitar que
pueda producirse una excepcin. Es decir que en el caso anterior podramos haber
286
u s r .c o d e
Clases de excepciones
verificado que el texto por convertir contuviera slo nmeros. Sin embargo, estas
verificaciones terminan agregando cdigo que siempre ser ejecutado y no nos ase
gura que, de todos modos, se produzca la excepcin por alguna verificacin que he
mos olvidado o que ni siquiera pueda realizarse.
Adems, de este modo se mezclara el cdigo relacionado con la lgica del progra
ma con el cdigo asociado al manejo de errores. En cambio, utilizando un bloque
CLASES DE EXCEPCIONES
Hemos logrado capturar una excepcin arrojada por un mtodo, encerrando su in
vocacin dentro de un bloque try..catch.
Pero qu fue lo que ocurri? Qu produjo el error? Qu le informamos al usua
rio? Existe ms informacin que podremos obtener al respecto; el bloque catch pue
de recibir un objeto de algn tipo de excepcin.
Rehagamos nuestro ejemplo y veamos que podremos ofrecerle al usuario no slo la
indicacin de que algo ha fallado.
try
{
num = Convert.ToInt32(txtNum.Text);
u s r .c o d e
287
PROGRAMACIN C#
U{
:
MesaageBox.Show(fe.Ma3sage);
Figura
Exception.
En el siguiente diagrama se
288
u s r .c o d e
Clases de excepciones
En caso de que se produzca una excepcin del tipo FormatExeption, podremos cap
turarla especificando como parmetro un objeto del tipo FormatExeption o un ob
jeto de tipo superior (como, por ejemplo, el objeto SystemException).
Por lo tanto, el siguiente cdigo tambin ser vlido:
try
{
num = Convert.ToInt32(txtNum.Text);
}
catch (SystemSxception se)
''
{
KessageBox.Showfse.Meesage);
o incluso:
try
{
num o Convert.ToInt32(txtNum.Text);
}
catch (Bxception ex)
{
MessageBox,3how(ex.Message);
La idea de este sistema cobra sentido cuando comprendemos que pueden existir
mltiples bloques catch por cada bloque try, y el flujo de ejecucin se desviar al
que corresponda segn la excepcin generada.
u s r .c o d e
289
PROGRAMACIN C#
'
'
nua Convert.ToInt32(txtNum.Text)}
res. * 5 / num;
}
catch (PormatException fe)
: {
// Tratamiento de la excepcin de formato
lili
290
u s r .c o d e
Clases de excepciones
ception.
ms especfico a m s general.
}
catch (Exception ex)
{
// Tratamiento de la excepcin
}
catch (FormatException fe)
// ;Error!
PROGRAMACIN Ctt
catch (FormatException e)
// Tratamiento de la excepcin
292
u s r .c o d e
Clases de excepciones
{
Abrir archivo
}
catch (AlgunaExcepcin el)
{
Tratamiento de excepcin el
}
catch (OtraExcepcin e2)
{
Tratamiento de excepcin e2
}
finally
{
Cerrar archivo
De este modo, si se suscita una excepcin o no, igual se ejecutar el cdigo corres
pondiente al finally.
Claro que usted podr pensar: pero... podra cerrar el archivo luego de todo el blo
que try..catch? Para comprender la respuesta a este interrogante deberemos estudiar
un tema ms: el arrojo de excepciones por medio de la sentencia throw.
u s r .c o d e
293
PROGRAMACION C#
GENERAR EXCEPCIONES
Nuestros objetos tambin podrn generar excepciones. Si verificamos en el cdigo
alguna de nuestras funciones, podremos informar al mtodo invocante que, por
ejemplo, un parmetro no es vlido. Para esto, se utiliza la sentencia throw.
Veamos un ejemplo. Supongamos que creamos un mtodo que opera con un par
metro entero que debe ser impar. Si el mtodo verifica que el nmero recibido no
es impar, podra arrojar una excepcin al mtodo invocante que informe esto.
prvate void Calcula(int num)
{
// Verifico que el nmero sea impar
if (num % 2 as 0)
throw new FormatException(HEl nmero debe ser impar*);
// Si sigo aqu es porque el nmero ES impar
//
...
En este caso, la sentencia throw ir acompaada por el objeto del tipo excepcin que
mejor se adapte al tipo de error que ha ocurrido. Tambin podramos crear nuestra
propia subclase de alguna excepcin existente si lo considerramos conveniente
(SystemException, FormatException, etc.).
Cuando se ejecuta el throw, se abandona el mtodo y se produce la excepcin.
Tambin es habitual que cuando se produce una excepcin, sta sea tratada y luego
transferida al mtodo superior;
int num, res;
try
{
num = Convert.ToInt32(txtNum.Text);
res = 5 / num;
}
catch (FormatException fe)
{
// T ra ta m ie n to de l a e x ce p ci n de fo rm ato
...
throw f e ;
294
u s r .c o d e
Generar excepciones
finally.
finally
cerrar archivo
inmediatemente despus
En ambos bloques, la cantidad de lneas de cdigo que pueden contener no se encuentra limita
da. Sin embargo, es una buena prctica mantenerlos breves,
u s r .c o d e
295
PROGRAMACIN C#
{
public NumlmparException{) : base(*El nmero no es impar.")
}
public NumlmparException(string atrErr) : base(strErr)
{
}
}
En este caso se permite construir el objeto haciendo uso del mensaje predetermina
do o personalizando el mensaje que ser enviado.
Para arrojar la excepcin ahora podramos escribir:
private void Calcular(int num)
{
if (num % 2 a* 0)
ii
...
{
int num = Convert.ToInt32(txtNum.Text);
296
usr.code
Calcular(num);
catch (NumlmparException nie)
MesBageBox.Show(nie.Mesaage);
RESUMEN
El manejo de excepciones es un poderoso sistema para especificar cmo debe comportarse
nuestro programa cuando se produce algn evento no previsto. En el captulo siguiente anali
zaremos ms aspectos avanzados del lenguaje, entre ellos, uno de los ms interesantes y
atractivos de todos: Reflection.
u s r .c o d e
297
fflj
ACTIVIDADES
TEST DE AUTOEVALUACIN
1 Por qu es mejor utilizar el sistema de ex
excepcin ms especifica?
298
u s rx o d e
PROGRAMACIN C#
Captulo 1 0
Caractersticas
avanzadas
del lenguaje
En este captulo ingresaremos
en los aspectos ms avanzados
con los que cuenta el lenguaje.
Qu es el boxing/unboxing, qu son
y para qu se utilizan los atributos,
qu es Relection y cmo acceder
a libreras creadas en otros lenguajes.
Boxing/Unboxing
Atributos
300
301
Atributos predefinidos
Consultar tos atributos
en tiempo de ejecucin
Reflection
305
306
307
308
311
313
Resumen
315
Actividades
316
PROGRAMACIN C#
BOXING/ UNBOXING
Boxing es un proceso implcito que consiste en la insercin de un tipo de dato por
valor en un objeto. Esto ocurre cuando se espera una referencia pero se provee un
valor, entonces el framework automticamente crea un objeto al vuelo, coloca di
cho valor dentro de l y luego pasa la referencia a quien la esperaba.
int num = 10;
object obj = num;
Si estamos realizando una aplicacin de alto desempeo, ser importante conocer cundo
se
realiza este tipo de operaciones implcitas, debido a que consumen algunos ciclos extra de CPU,
especialmente, en zonas crticas como los bucles internos.
300
u s r .c o d e
Atributos
ATRIBUTOS
Los metadatos son datos acerca de los datos. C# ofrece un sistema para insertar metadatos en nuestros assemblies mediante atributos.
Un atributo simplemente se define por medio de una clase descendiente de System.
Attribute. Es bastante frecuente que el nombre que poseen estas clases descendientes
III
Los atributos nos permiten fijar informacin de las estructuras que posee nuestro programa. Es
to podra ser til en muchos casos y, en particular, cuando nuestros programas sean inspeccio
nados mediante Reflection (tema que veremos un poco ms adelante en este mismo captulo).
usr.code
301
PROGRAMACIN C#
CualquierNombreAttribute),
aunque no se
Luego, a nuestra clase de tipo atributo podremos agregarle propiedades, pero por el
momento analicemos un ejemplo bien sencillo:
f clase CualquierNombreAttribute : Attribute
{
}
CualquierNombreAttribute.
{
}
O .simplemente:
[CualquierNotnbre] clasB Poo
{
}
Estos dos ltimos listados de cdigo son equivalentes, ya que el compilador permi
te simplificar el nombre del atributo quitando el Attribute detrs de l.
Tambin podramos agregar atributos a mtodos, enumeradores, propiedades,
eventos, etc. No obstante ello, un atributo especfico podra restringir su rango
de aplicacin por medio de un parmetro de tipo
AttributeUsage
AttributeTargets
del atributo
En la documentacin oficial que acompaa a Visual Studio .NET podremos encontrar ms infor
macin sobre el uso de los atributos. Tambin podremos acceder a dicha informacin online des
de http://m sdn.m icrosoft.com /library/en-us/csref/htm l/vclrfintroductiontoattributes.asp.
302
u s r .c o d e
Atributos
[Attributesaga(AttributeTargeta.Class)]
public class CualquierNombreAttribute: Attribute
{
}
{
}
Nuestro atributo
CualquierNombre
All
Assembly
Definiciones de assemblies.
Class
Definiciones de clases.
Constructor
Delegate
Definiciones de delegados.
Enum
Definiciones de enumeradores.
Event
Definiciones de eventos.
Fietd
Definiciones de campos.
Interface
Definiciones de interfaces.
Meiod
Definiciones de mtodos.
Module
Definiciones de mdulos.
Parameter
Definiciones de parmetros.
Property
Definiciones de propiedades.
RetuinValue
Struct
Definiciones de estructuras.
303
PROGRAMACIN C#
el cofnpilawpo( comcco
ewm ^
meihod
^ module ^
lefrtrficattor
do attflKo
O
/7\ >1porm
ofro
y'Jrr^ poiipofui
- O
t(Q\
{
prvate string valor;
public CualquierNombreAttribute(string v) { valor = v; }
304
u s r .c o d e
A tributo?.
Tambin podramos definir una propiedad pblica, al igual que en cualquier clase:
(Attributesage (AttributeTargets.Class))
public class CualquierNcxnbreAt tribute: Attribute
{
private string valorl;
{
set { valor2 = valu; }
get '{ return valor2;
}
}
{
}
Atributos predefinidos
El framework .NET ofrece una serie de atributos predefinidos que pueden ser muy
tiles en la creacin de nuestros programas.
APLICABLE A
DESCRIPCIN
Conditonal
Mtodo
Dlllmport
Mtodo
1 NOMBRE DE ATRIBUTO
o no el mtodo relacionado.
Indica que el mtodo se encuentra definido dentro de una librera de enlace
dinmico con cdigo no gestionado por la plataforma .NET.
Obsolete
Mtodo
u s r .c o d e
305
PROGRAMACIN C#
[Conditional("DEBUG")]
public static void EjecutaEnDebugO
{
MegsageBox.ShowCEjecucin de mtodo EjecutaEnDebug");
}
}
El atributo
u s r.c o d e
Reflection
REFLECTION
Reflection es un sistema que permite analizar el contenido de un assembly en tiem
po de ejecucin. Este sistema bsicamente se utiliza para:
Analizar la informacin de atributos.
Descubrir nuevos tipos de datos e interactuar con ellos. De este modo podemos
utilizar desde nuestro programa objetos desconocidos, listando sus propiedades,
mtodos, eventos, etc.
Crear nuevos tipos en tiempo de ejecucin.
Para consultar por la informacin de atributos que posee un assembly, deberemos:
1. Obtener una referencia al assembly que deseamos inspeccionar.
2. Listar los mdulos que posee el assembly.
3. Listar los tipos (clases, interfaces, etc.) que posee cada mdulo.
4. Listar los atributos que posee cada tipo (con la posibilidad de solicitar todos o el
atributo del tipo especfico que estamos buscando).
// Obtengo ana referencia al assembly en ejecucin
Assembly asse = Assembly.GetRxecutingAssemblyO;
{
// Muestro en un cuadro de texto, el nombre del tipo actual
txtLog.Text = txtLog.Text +
String.Formatf'Tipo: {0}\r\nB, tipo.FulIName);
{
u s r .c o d e
307
PROGRAMACIN C#
txtLog.Text = txtLog.Text +
String.Pormat(" + Valor de atributo: {0}\r\n",
cna.OtroValor);
DialogResult.OK)
{
txtAasambly.Text a dlgAbrirArchivo.FileName;
BuscarModulos(dlgAbrirArchivo.FileName)?
308
usr.code
Reflection
);
}
}
{
if (mdulos.Length > 0)
{
tipos = nodulos[IsbModulos.Selectedlndex] .GetTypesO ;
if (tipos.Length > 0)
{
IsbTipos.Items.Clear() ;
foreach(Type t in tipos)
IsbTipos.Items.Add(t.ame);
}
}
}
Por medio del mrodo GetTypes del objeto mdulo seleccionado en la lista, obten
dremos todos los tipos que insertaremos dentro de otra lista.
Ahora, finalmente slo nos resta listar los mtodos del tipo seleccionado y colocar
los en otra lista. Para esto deberemos escribir en el cdigo:
u s r .c o d e
309
PROGRAMACIN C0
{
if (tipos.Length > 0)
{
mtodos s tiposUsbTipos.Selectedlndex] .GetMathodsO;
labMetodos.Items.Clear();
foreach(MethodInfo minfo in mtodos)
1sbMetodos.Items.Add(minfo.ama);
}
}
{
Methodlnfo ms = tipos[lsbTipos.Selectedlndex]
GetMethod(nombreHetodoInvocar);
if (ms != nuil)
{
try
{
ms.Invoke(null, nuil);
}
catch(Exception se)
{
MessageBox.Show(se.Message);
}
}
else
MessageBox.Show('No es posible encontrar el mtodo
especificado");
La nica restriccin que presenta nuestro ejemplo es que solamente est posibilita
do para invocar mtodos estticos que no posean parmetros (situacin que podra
modificarse de manera bastante sencilla). De otro modo se producir una excepcin
que luego se mostrar en un cuadro de texto.
310
u s r .c o d e
fx
A^semUy a nspecoorwr
[E7YuseTs\d>&go\kbro CS\code-cap9\ReftectKnApp!\t>n\D6
Mtod
ra n H H H H n a W a
IMtodo:
Metodo
Mtodo^
|Mtodo?
~
*:
In.'o;ar mtodo de componerte
LIBCPP_APIvoid fnl(void);
extern *C*
LIBCPP_APIint fn2(void);
311
PROGRAMACIN C#
Ahora observemos, en el siguiente cdigo, cmo debe ser nuestra clase en C # para
permitirnos el acceso a la librera.
using System;
using System.Runtime.InteropServices;
public class LibCpp
{
[Dlllmport("libcpp.dll", CharSet=CharSet.Auto, SetLaBtError=true)]
public static extern void ful();
IDllImport(,'libcpp.dll'
, CharSet=CharSet.Auto, SetLastError=true) ]
public static extern int fn2();
[DlllmportClibcpp.dll'
, CharSet=CbarSet.Auto, SetLastError=true)]
public static extern void fn3(byte[J pszTsxt);
La clase en cuestin posee un mtodo esttico por cada funcin mapeada. Cada uno
de estos mtodos posee un atributo preestablecido por el framework que nos per
mite relacionar la funcin con la librera.
Cada mtodo debe poseer el mismo prototipo que la funcin en C que deseamos
invocar. Es decir que debemos mapcar los tipos de datos a los que mejor se adapten
en lenguaje C#. Si uno de dichos parmetros es una estructura, podremos declarar
una anloga en C#, pero siempre deberemos tener en cuenta que en memoria las
variables internas de la estructura deben mapearse exactamente igual (hay que tener
mucho cuidado con la alineacin de los miembros de la estructura).
Hecho esto, las funciones podrn ser utilizadas como si fuesen nativas.
Invocar la primera funcin:
LibCpp.fni () ;
u s r .c o d e
Punteros
3 Fundones deOLLs
Invocw funcin 1
Invocar funcin 2
Valor de retorno
1
Parmetro tpo string
Eite es el mensaje de texto a posar
|
Invocar funcin 3
PUNTEROS
Un puntero es una variable que posee como valor una direccin de memoria asig
nada y desasignada explcitamente.
Este tipo de recursos es muy utilizado en los lenguajes de programacin C y C++,
debido al inmenso poder que otorgan, pero poseen una importante desventaja: es
fcil cometer errores en su manipulacin.
Los tipos de errores ms comunes son:
Errores de lectura o escritura en zonas de memoria no permitidas: si intenta
mos leer o escribir memoria que no nos pertenece, Windows, en forma preventi
va, cerrar inmediatamente nuestra aplicacin. este error se lo conoce como
error de proteccin general .
Errores en la desasignacin de memoria: si no liberamos la memoria de un modo
correcto, entonces un sector de sta quedar tomado por nuestra aplicacin pero no
ser utilizado (;memory leak). Si este error se comete repetidas veces en una aplicacin,
tarde o temprano se consumir todo el recurso de memoria de la plataforma.
u s r .c o d e
313
PROGRAMACIN C#
Por oiro lado, estos tipos de errores suelen ser muy difciles de extraer. Es por ello
que C#, al igual que Java, incorpor un gestor automtico de memoria para evitar
le al programador esta tediosa tarea.
Pero C# ofrece la posibilidad de utilizar punteros, si lo solicitamos explcitamente.
Para esto debemos hacerlo en un contexto no seguro (encerrado de un bloque unsafe); adems, deberemos modificar una opcin de nuestro proyecto para permitir
cdigo no seguro, y tambin debemos tener en cuenta que ciertas plataformas po
dran no permitir la ejecucin de aplicaciones con cdigo no seguro en su interior.
La operacin con punteros es algo diferente del manejo de variables convenciona
les. Observemos la tabla que se incluye a continuacin.
El operador & permite obtener la direccin de memoria donde se encuentra alojada la variable relacionada.
->_ _ _ _ _ _ _ _ _ _ El operador -> permite acceder a los miembros de una clase o estructura apuntada por un puntero.
Tabla 3. Manejo de operadores en los punteros.
int * pNum;
pNum
pNum
numl
num2
pNum
numl
numl = 10;
10
num2
pNum
numl
10
num2
10
pNum = Snuml;
314
u s r .c o d e
P u n te ro s
pNum
num2 = *pNum;
numl
10
num2
10
Otra de las precauciones que debemos tener en cuenta a la hora de trabajar con
punteros se encuentra relacionada con la gestin automtica de memoria que po
seen los elementos a los cuales apuntamos con los punteros.
Si el framework .NET entiende que una variable queda fuera de alcance, podra
querer reutilizar la memoria que sta ocupa, y de este modo, invalidar tal vez algn
puntero que la estaba utilizando.
Para evitar esto se utiliza la sentencia fixed de la siguiente manera:
int[] nums a new int [10];
fixed (int * pNum = nums)
:
{
//
}
I.L -U I ILII
En este captulo hemos analizado algunas de las caractersticas ms avanzadas que posee el
lenguaje. Las posibilidades que nos brinda el mecanismo de Reflection son enormes. Muy f
cilmente podramos incorporar a nuestro programa un sistema de scripting por medio del cual
el usuario pudiera extender las funcionalidades de la aplicacin (por ejemplo, como si fueran
macros de Microsoft Word), y todo utilizando C#, lo que permitira, sin esfuerzo alguno, que
se instanciaran clases de nuestro sistema. Por otro lado, la posibilidad de utilizar libreras
creadas en otros lenguajes es una caracterstica que muchos programadores C/C++ aplaudi
rn, ya que podrn reutilizar aos de trabajo; incluso podran decidir realizar ciertas tareas
crticas en C mientras que todo el front-end de la aplicacin se ejecutara en C#.
usr.code
315
ACTIVIDADES
TEST DE AUTOEVALUACIN
1 Cules son las ventajas y las desventajas
de Boxing/Unboxing?
316
u s r .c o d e
PROGRAMACIN C#
i_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Captulo 1 1
Servicios web
Los servicios web son uno de los aspectos
de la plataforma que ms han crecido
en popularidad en ios ltimos tiempos.
Si bien no son una caracterstica exclusiva
de NET, Microsoft iia impulsado mucho
esta tecnologa y ha hecho un gran trabajo
en facilitar la tarea de su construccin
y utilizacin desde su entorno
de desarrollo. Veremos aqu de qu trata
esla tecnologa y cmo podremos
utilizarla desde nuestro querido
C t .
318
Iect0res@mpedici0nes.com
Actividades
_ _ _ _ _ _ 332
PROGRAMACIN Cfl
(web Services)
objetos en distintos puntos de la Red que publiquen servicios, que luego otras aplica
ciones puedan consumir de una manera muy sencilla y, prcticamente, transparente.
Estos servicios, adems, permiten originar arquitecturas no dependientes de la pla
taforma, ya que se basan en protocolos abiertos. Una aplicacin .NET podra estar
consumiendo servicios creados en Java, o viceversa.
Un servicio posee asociada una direccin que identifica al recurso en la Red y pro
vee una descripcin de su interfaz, por medio de la cual los clientes pueden cono
cer los mtodos que ofrece dicho servicio.
Crear una aplicacin en .N ET que consuma servicios es muy sencillo. Veamos, por
ejemplo, cmo crear una aplicacin C# que use el servicio de bsqueda de Google.
III
QU ES WSDL?
WSDL [Web Service Description Language1es un formato estndar para definir servicios web. Se
encuentra expresado en XML, y establece cmo acceder al servicio y qu operaciones se pueden
realizar con l. Enlace relacionado: www.w3.org/TR/wsdl.
318
u s r.c o d e
E m a il n d d r e s s :
e.g. m yn3m c @ ex a m p le .co m . This w llb e y o u r u s e m a m e and signin.
P a s s w o rd :
M nim um o l 6 ch ara cle rs n length.
R e -e n te r p a ss w o rd :
W o rd V e riic a tio n :
% N f l9
Nuestra cuenta nos permitir realizar hasta mil consultas diarias, algo considerado
ms que suficiente para fines personales.
Creada la cuenta Google, nos enviarn por correo una licencia consistente en una
clave alfanumrica de 32 caracteres. Esta clave es importante, ya que nos ser soli
citada cuando deseemos ejecutar una consulta utilizando el servicio web.
Ahora, veamos los pasos que deberemos realizar con Visual Studio .NET para po
der interactuar con el servicio.
Crearemos una aplicacin de tipo Windows
desde el
Captulo 7.
control de cuadro de texto (que servir para especificar la consulta), un botn (que
usaremos para ejecutar la consulta) y una lista de visualizacin (donde sern mos
trados los resultados de la consulta).
Pero el paso ms importante y clave que nos posibilitar utilizar el servicio web se
r agregar una referencia web a nuestro proyecto. Por medio de esta referencia, le
indicaremos a Visual Studio .NET el servicio que deseamos utilizar mediante la es
pecificacin de un archivo
WSDL.
u s r .c o d e
319
PROGRAMACIN C#
JE S
S-
jHWindowsflpplicationl
S sal ira
l i Pre
reiE------------'y - - -- - -- - 0 APP'K0 I
F ] Assem blj
^ddReference...
A dd W g b R e e r e f K e ,..-
jj
1:
F o r m l.
^'-I4--5View
Una vez realizado esto, se abrir una ventana que nos solicitar el ingreso de la ubi
cacin de la descripcin del servicio:
dd Web Referente
1 M
kttw URL.
o 0 a
W i
II
Start Browsing for Web Services
aw
SVebservkwtajnAtthKUfa:
atarI
machlae
v. * t?.*
b ro w s e UODI S e rv e r s
o n th e lu rni niitv.orl
Quecy yojr loca) netwoikfcr UCCI wver.
.ULQPlPirtv.torjy
|
i
Cc!
Hek.
El archivo WSDL se encuentra ubicado dentro del paquete que liemos descargado de
Google. Hay que descomprimir dicho paquete y luego especificar la ruta completa
de acceso al archivo en cuestin, luego de lo cual Visual Studio .NET lo leer y en
contrar los mtodos que ofrece el servicio:
320
u s r .c o d e
Q u s o n lo s s e r v i c i o s w e b ?
O***-. O
O 0 !
IPL: |C:\ooglMrh.id
3 So
Vrebjorvxcs round d tm URI:
GoogleSearchService Description
1Service found:
- 'kcgieSearch
Methodv
doGetCachetlJage')
|
doGoogleSearchO
b doSfJcWngSuggetfiun!)
reftrence Qarno:
Webftderence
A d d R e /e re tx e
:
Centd
|
Reference,
el entorno de desarrollo crear una clase proxy que nos permitir interactuar con el
servicio como si fuera un componente local, al tiempo que emplea el protocolo SOAP
para dialogar con el servicio web.
Class V iew - C onsum iendoServiciosW ebl
S p l ConsumiendoServiciosWebl
5
so p a s s s
S
^
fr.
!+.
t i ^ i j frm M ain
Class Viaw | 1 ^ S d - j i i M i . . .
| 1 R.esoufa
u s r .c o d e
321
PROGRAMACIN CU
Figura 6. El proxy nos evita tener que trabajar con el protocolo SOAP.
key
<1
Trminos a buscar, Estetoto puedemilitar ciertosoperadores para ajustar los resultadosde la bsqueda
start
HHHHM
maxResutts
filter
restrict
SafeSearch
If
ie
Parmetro obsoleto. Estaba relacionado con la codificacin de caracteres utilizada para la entrada de datos.
oe
Parmetro obsoleto. Estaba relacionado con la codificacin de caracteres utilizada para la salida de datos.
Tabla 1. Parmetros del mtodo doGoogleSearch.
322
u s r .c o d e
Q u s o n lo s s e r v ic i o s w e b ?
clave_otorgadajpor_Google,
// clave
txtSaarch.Text,
// texto a buscar
0,
// ndice de comienzo
10,
true,
// filtro
String.Empty,
true,
// bsqueda segura
String.Empty,
String.Empty,
// Parmetro obsoleto
String.Empty);
/ Parmetro obsoleto
Por otro lado, el resultado devuelto por la bsqueda se incluye en un objeto del ti
po GoogleSearchResult, que posee las siguientes propiedades:
documentFiltering
searchComments
Cantidad total estimada de resultados que atoj la bsqueda (no la cantidad enviada hacia
nosotros, que como mximo es 10, sino el total que emiti la bsqueda por la base de datos),
estimatedlstxact
resultElements
searcbQuery
startlndex
consulta,
endlndex
ndicedel ltimoresultado.
searchTips
Texto para mostrarle al usuario final, conconsejos acerca de cmo utilizar Google.
directoiyCategories
searchTime
DD QU ES SOAP?
SOAP (Simple Object Access Protocol1es un protocolo basado en XML que estandariza el modo
de interaccin con tos servicios web. Enlace relacionado: www.w3.org/TR/soap.
u s r .c o d e
323
PROGRAMACIN C8
Para poder otorgarle la informacin al usuario sobre las pginas encontradas, debe
remos recorrer el array resultElement, que posee las siguientes propiedades:
summary
OflL
snippet
Un pequeo resumen del texto encontrado en la pgina que se relaciona con la bsqueda.
! Me"
Titulode la pginarelacionara.
cachedSize
1 letatedtafoimatkmPrsseiU
hostName
Para la segunda pgina encontrada relacionada con el mismo host, en esta propiedad se hallar
el nombre de ste.
: dlrectoryCategory
Categora de rfircctorioOOP.
324
u s r .c o d e
Q u s o n lo s s e r v i c i o s w e b ?
BegindoGetCachedPage y EnddoGetCachedPage
BegindoGoogleSearch y EnddoGoogleSearch
BegindoSpellingSuggestion y EnddoSpellingSuggestion
Es importante saber que esta versin de mtodos la ha creado Visual Studio, y
no son otros mtodos del servicio web que ofrezca Google.
Ahora, si en lugar de invocar
doGoogleSearch
invocamos
BegindoGoogleSearch,
el
AsyncCalIback callback
obiect state
u s r .c o d e
// clave
texto a
buscar
// ndice de comienzo
10,
true,
// filtre
String.Bnpty,
true
// bsqueda segura
325
PROGRAMACIN CU
String.Empty,
String.Empty,
// Parmetro obsoleto
String.Empty,
// Parmetro obsoleto
// estado
ConsultaTerminada ser el mtodo que indicamos que se invoque cuando los datos
se encuentren disponibles:
public void ConsultaTerminada(IAsyncResult ar)
{
GoogleSearchService gss (GoogleSearchService) ar.AsyncState;
// Recupero el objeto tipo GoogleSearchResult
GoogleSearchResult gsr = gsB.EnddoGoogleSearch(ar);
// Mostramos los resultados del modo usual
II
...
Como se puede apreciar en el listado anterior, primero recuperamos nuestro objeto Google
SearchService, que se encontraba encapsulado en el resultado de la operacin asincrnica.
Luego obtenemos el resultado que antes devolva el mtodo sincrnico, utilizando
M Bsqueda en Google
Bsqueda
|c#
Cantidad total d e resultados encontrados:
1070000
Search(Async)
Tiempo de bsqueda:
Titulo
0,106507
Enlace
http://msdn .microsolt.com/vcsharp/
http://msdn,.microsoft.com/vstudio/using/
C# Crner: C-Sharp, CI.NET, .NETDeveloper,.. http://www.c-sharpcorner.com/
C# C Sharp Help : For C# Developers -Csbar... http://www.csharphelp.com/
Mam Page - Mono
http://www,go-mono.com/
C# Statlon - Tutorial, links, Info - E Sharp
http://www,csharp-station.com/
C# Progtamming
http;//www, hitmiS.com/programmmg/dotNET/csharp..
APRESS . COM | BooPs for Professonals, by Pr... http://www.apress.com/
Visual C# Developer Center: Fromthe Team
http://www,,gotdotrvet.com/team/csharp/
C# C Sharp and Tutorials on C# Fnends.com
http://www.csharpfriend5.com/
326
u s r .c o d e
C r e a r u n s e r v ic i o w e b
Microsoft IIS
[Internet Information Server) 5.0 o superior ejecutndose. El sistema operativo Win
dows XP Professional incluye el IIS 5.1, pero no es instalado por predefinicin.
En primer lugar, debemos verificar que poseemos un servidor web
Por lo tanto, hay que ir al panel de control, ingresar en la opcin Agregar o Quitar
desde all elegir Agregar o quitar componentes de Windows y, finalmente,
Programas,
marcar la opcin
Con
New Project
lis j
letrpttes:
Project Typm:
t Visual C# Prcjects
ti? B
0
3! L l Othef Projects
Q Visual Studio Solutions
P
Consol
Application
Web Control
Lfcrary
Windows
Service
Empty Project
locatcn:
I http://localhost/WebServicel
_]
growse...
C*
Hetp
Lo que hace en este caso el asistente es crear una carpeta dentro del sitio web que
especificamos, V dentro de ella coloca los archivos que componen el proyecto.
u s r .c o d e
327
PROGRAMACIN C#
System.Web.Services.WebServices
_
NuestroWebService
El cdigo generado es bastante simple, y tiene un mtodo web escrito, pero bajo co
mentarios, que podremos eliminar.
Nuestro ejemplo consistir en crear cuatro mtodos diferentes, cada uno de ellos
con distintos tipos y cantidad de parmetros, simplemente para mostrar el mecanis
mo de funcionamiento de todo el sistema. Luego, estos mtodos podran trabajar
como lo hace cualquier aplicacin C# respecto al manejo de datos: accediendo a
una base va ADO .NET, o a archivos o a lo que nuestra aplicacin requiera.
Todos los mtodos que declaremos debern poseer un atributo llamado WebMethod
para que el compilador entienda que es un mtodo para incluir en el servicio. As,
pues, nuestros mtodos sern:
public clase Servicel : System.Web.Services.WebService
{
// Cdigo generado por Visual Studio .NET
//
II
...
Existe un tercer protocolo, muy utilizado en servicios web, pero no tanto como los otros dos
(SOAP, WSDL). Se llama UDDI 1Universal Description, Discovery and Integration), y permite loca
lizar e interrogar servicios web para descubrir qu operaciones ofrecen y de este modo poder uti
lizarlas. Enlace relacionado: www.uddi.org.
328
u s r .c o d e
C r e a r u n s e r v ic io w e b
[WebMethod]
public 3tring HetlO
{
,// Retorno un string arbitrario
return *el lenguaje C#*;
}
[WebMethod]
public string Met2(string str)
{
// Reto m o el string modificado
return *Me has pasado el string: * + str;
}
[WebMethod]
public int Met3(int numl, int num2)
{
// R e tomo la suma de los parmetros
return numl + num2;
}
[WebMethod]
public stringf] Met4()
{
string [] strs = new string [4];
strs[0] = "palabral"?
strs[l] = "palabra2";
strs [2] = ,1palabra3*';
stra[3] = "palabra4";
// Retorno la suma de los parmetros
return strs;
}
}
usr.code
329
PROGRAMACIN CU
fcdtn
Ve*
@ ,fa 0
prontos
3 $
P***
Service 1
0 1
*
HerramieotM Ayyda
Fawrto
Q 0- :^
V iQ Ir
Vf,edos ^
......
Met3
T e st
To t e j t th e o p eraticn using the HTTP POST protocol, dick th e ln v o k e b u tton.
Parame*r Valu
n u m l:
jj____
num2:
Irtrant* local
Intentemos ahora desarrollar una pequea aplicacin que consume nuestro servicio,
de la misma manera en que lo hemos hecho con el servicio de Google. Los pasos
que deberemos seguir son muy sencillos:
1. Crearemos una aplicacin tipo Windows
2. Agregaremos una referencia web.
Application.
3. Especificaremos la ubicacin del archivo aspx (en lugar del wsdl que habamos
utilizado en el ejemplo del servicio Google).
4. Instanciaremos la clase de nuestro servicio web y podremos invocar cualquiera
de los mtodos que posea.
330
u s r .c o d e
C r e a r u n s e r v ic io w e b
P ru e b a de Servicio Web
M e t ---------------- -----------
Met'J
:-M e t2
Parmetro (stiing):
M e t4 ............
---------
Valor de retorno:
HOLA!
Parmetro (int):
ipalabral
i palabta2
j palabta3
palabra-i
;
Valor de retomo:
Valor de retorno
Valor de retorno:
pasado el string ? i i! ^
.
Invocar
j
'
Invocar
Invocar
Invocai
;....................
Los archivos fuente completos de los ejemplos vistos en este captulo pueden ser
descargados desde el sitio
onweb.tectimes.com.
RESUMEN~
Los servicios web son la tecnologa de moda, y existen buenas razones para que lo sean. Mu
chas otras tecnologas persiguieron los mismos objetivos, y de hecho, fue posible conseguir
logros similares mucho antes de que los servicios web vieran la luz. Sin embargo, nunca fue
tan sencillo para el desarrollador construir y utilizar tecnologa que permitiese distribuir, tan
fcilmente, objetos por una red. Visual Studio .NET allana an ms el camino, convirtiendo en
un placer la construccin de aplicaciones distribuidas.
u s r .c o d e
331
activid ad es ;
TEST DE AUTOEVALUACIN
1 Cules son los Ires protocolos ms utilizados en los servicios web?
4 Un servicio web creado en ASP.NET puede ser utilizado desde plataformas Unix?
System.Web.Services.WebServices
1-------
NuestroWebService
332
u s r .c o d e
PROGRAMACIN C#
Captulo
Sockets
Si deseamos que nuestra aplicacin
se comunique con otra por medio
de una red de datos, varias soluciones
Qu es un socket?
334
lectoreS@ m pedicioneS.com
de sockets
Dilogo entre un cliente
y un servidor
Sincrnico vs. Asincrnico
La clase Socket
Resumen
334
334
335
335
341
Actividades
342
PROGRAMACIN C#
QU ES UN SOCKET?
Socket es una especificacin que define una interfaz para la programacin de apli
caciones de red. Se implemento inicialmente en sistemas operativos del tipo BSD
Unix a principios de los aos ochenta. Originalmente, la librera
Berkley Sockets
ofreca una interfaz de programacin en lenguaje C; hoy en da existen muchas implementaciones. As, podemos encontrar la implementacin sobre M FC llamada
de un servidor.
de un cliente.
usr.code
Q u e s u n s o c k e t?
hacer,
pero
335
PROGRAMACIN CH
La clase Socket
La clase Socket se encuentra dentro del espacio de nombres System.Net.Sockets; pa
ra hacer uso de ella, sin utilizar el nombre completamenre calificado, agregaremos:
using System.Net.Sockets;
El servidor
Habamos mencionado los pasos necesarios para crear el servidor y dejarlo escu
chando sobre un puerto. Veamos el cdigo necesario para ello.
Primero deberemos crear el socket, que representar el extremo de la comunicacin
del lado servidor. El constructor de la clase Socket posee el siguiente prototipo:
public Socket(
AddreBsFamily addressFamily,
SocketType socketType,
ProtocolType protocolType
);
.'. "
. .
-. . . V'* *
...'
V /** "i
...
'
SocketType,
colType.Udp.
ProtocolType.Tcp o Proto-
El segundo paso consistir en asociar el socket a un determinado endpoint. Un endrepresenta el direccionamiento a un extremo de la comunicacin, que en el
point
IP y un puerto.
336
IP
especial
u s r .c o d e
Q u e s u n s o c k e t?
IPEndPoint
Listen.
connSocket.Liaten(l);
El mtodo
Listen
{
Socket connSocket = (Socket) ar.AsyncState;
m_remoteSocket = connSocket.BndAccept(ar);
usr.code
337
PROGRAMACIN C#
)
La lnea de cdigo ms interesante del mtodo OnAccept es:
m remoteSocket * connSocket.BndAccept(ar);
Aqu, mediante
EndAccept
{
connSocket.Connect(ipEndP);
}
catch
{
// No es posible conectarse
)
338
...
u s r.c o d e
Q u e s u n s o c k e t?
Aqu utilizamos la versin sincrnica del mtodo, ya que el tiempo estimado de cone
xin a un servidor es bajo, y mientras tanto la aplicacin no debe realizar ninguna otra
tarea. Esto significa que, invocado el mtodo Connect, la aplicacin quedar bloquea
da durante unos instantes, mientras se est intentando la conexin. Si sta fracasa, el
mtodo arrojar una excepcin que deberemos manejar segn corresponda (en la apli
cacin de ejemplo, simplemente anunciamos dicho fracaso mediante un MessageBox).
Si la conexin fue satisfactoria, en la lnea posterior ai Connect asumiremos que existe
una conexin establecida y podremos comenzar a intercambiar datos con el servidor.
Cdigo operacin
(1 byte)
Tamao seccin
datos
(1 byte)
Datos
(hasta 256 bytes)
Paquete
Para el ejemplo, aqu slo haremos uso de un tipo de paquete (mensajes de texto),
pero se podra extender su utilizacin para otro tipo de aplicaciones.
Respecto a la recepcin de datos, ya dijimos que para manejar la operacin emplea
ramos un mtodo asincrnico. Para ello, tendremos que invocar BeginReceive y pa
sar como parmetro qu mtodo deber manejar dicha recepcin (similar a lo que
hicimos con BeginAccept). Analicemos detalladamente el prototipo del mtodo.
u s r .c o d e
339
PROGRAMACIN C#
bytell buffer,
j
int offset,
int eize,
SocketPlags sockatFlags,
AsyncCallback callback,
object atete
{
Socket connSocket = Socket) ar.AayncState;
int read = connSocket.EndReceive(ar
II ...
);
Recibidos los datos, nuestra aplicacin los manejar de manera conveniente, y lue
go, si corresponde, antes de finalizar volver a invocar BeginReceive para seguir per
mitiendo la recepcin de datos.
Mquinas de estado
Con relacin a los datos que recibe la aplicacin y cmo Jos maneja, es frecuente
que se implemento una mquina de estados. La mquina de la aplicacin de ejem
plo es bastante sencilla, y simplemente, se encarga de conmutar entre los distintos
estados posibles del servidor y del cliente. Es importante que la aplicacin implemente un mecanismo de este tipo, debido a que la recepcin asincrnica de datos
en ocasiones torna compleja la prediccin de cmo se sucedern los hechos; por lo
tanto, para que la aplicacin se comporte consistentemente en todo momento, se
debe verificar el estado en el que se encuentra antes de realizar una accin.
340
u s r.c o d e
Q u e s u n s o c k e t?
Los sockets nos permiten crear aplicaciones de red de manera muy sencilla y eficien
te. Sin embargo, debemos destacar que no implementan ningn protocolo de apli
cacin en particular; se ser nuestro trabajo. Si deseamos comunicarnos mediante
algn protocolo de aplicacin particular
otras clases de mayor nivel que ofrece la librera BCL del firamework
htoU M tN
Muchsimas aplicaciones populares hacen uso de sockets para comunicarse con oirs median
te una red de datos como Internet. ste es el caso de todas las aplicaciones P2P, como eMule,
Kaaza, BitComet, BitTornado, etc. Programar con sockets es sencillo, y se trata de un recurso
que siempre hemos de tener a mano como posible solucin a requerimientos de conectividad
que podran tener nuestras futuras aplicaciones.
u s t.c o d e
341
| c 2 ACTIVIDADES
TEST DE AUTOEVALUACIN
1 E s
p osib le c o n e c ta r s e a un s e rvid o r w e b
3 R e q u ie r e
h a c ie n d o uso de la c la s e S o c k e t e interac-
t u a r c o n l?
v id o r H T T P o S M T P ?
t* E s p o sib le c r e a r un se rv id o r H T T P u tili
zando s o c k e ts ? Y un clie n te H T T P co m o
un n a v e g a d o r w e b ?
5 S e r a
p osib le co n su m ir un se rv ic io w e b
342
u s r .c o d e
PROGRAMACIN C#
Captulo 1 3
Introduccin
a Managed
DirectX
En este captulo haremos una
introduccin a una de tas APIs
ms importantes en el mundo
de la programacin de aplicaciones
de alto rendimiento grfico y juegos.
Managed DirectX es una suma de clases
para .NET que nos permitirn hacer uso
de DirectX en su totalidad.
Managed DirectX
Qu necesitam os7
El sistema de coordenadas 3D
345
Antes de empezar
346
Inicializar Direct3D
347
Dibujar objetos
356
El mtodo ProcsVerts
de la clase Renderer
344
344
359
Ejecutar la aplicacin
360
Resumen
361
Actividades
362
PROGRAMACIN C#
MANAGED DIRECTX
DirectX es un conjunto de componentes creado por Microsoft para ser utilizado
en la creacin de juegos y aplicaciones multimedia de alto desempeo.
fue lanzada al pblico por primera vez el 20 de diciembre de 2002 y que pretende fa
cilitar el desarrollo de juegos y aplicaciones haciendo uso de esta tecnologa.
MDX es una gran API; en este captulo nos enfocaremos concretamente en su com
ponente ms popular: Direct3D.
Qu necesitamos?
(www.microsoft.com/windows/directx/default.asp).
(http://msdn.microsoft.com/netframework).
(www.microsofit.com/downloads/search.aspx?displaylang=en&categoryid=2).
Microsoft Visual Studio .NET, que facilite la gestin del proyecto y su depuracin.
Existe una base terica fundamental que deberemos conocer, previamente a empe
zar a navegar por los mares de Direct3D. Comenzaremos con una breve resea que
nos ser bastante til como introduccin a dicha teora.
344
u s r .c o d e
E l s is te m a d e c o o r d e n a d a s 3 D
EL SISTEMA DE COORDENADAS 3D
Por medio de Direct3D lograremos crear una imagen en dos dimensiones a partir
de un modelo tridimensional. Esto es as, naturalmente, porque nuestro monitor
slo puede generar una imagen chata de los datos procesados.
Adems,
Direct3D
Direct3D
tringulos, los cuales a su vez estarn formados por un conjunto de vrtices. Cada
uno de estos vrtices poseer los tres componentes requeridos para ser colocados
dentro de un sistema de coordenadas 3D, pero cabe mencionar que podrn tener
otras propiedades en funcin de las caractersticas que deber poseer el objeto del
cual forme parte, y que, en su debido momento, analizaremos.
Cada vrtice, antes de ser mostrado en pantalla, deber pasar por una serie de trans
formaciones que dictarn si el vrtice es finalmente mostrado y en qu posicin de
la pantalla estar. Estos cambios se darn dentro del denominado
pipeline.
cuyo
Vrtices
u
Transformacin
Transformacin
de Proyeccin >
de Vista
(View)
(Projection)
Transformacin
de Mundo
(World)
Pipeline de Transformacin
Recorte
y reescalado
de Vlewport
Rasterizador
u s r .c o d e
3 45
PROGRAMACIN C#
La matriz de mundo
La primera matriz de mundo cs utilizada con el propsito de colocar el objeto den
tro de la escena 3D. Realiza una transformacin que va desde el espacio del mode
lo al espacio del mundo en el cual trabajamos. La transformacin de mundo puede
incluir traslaciones, rotaciones y escalamientos.
La matriz de vista
La segunda matriz, llamada matriz de vista, reubica todos los objetos en funcin de .
un punto de visualizacin especificado.
La matriz de proyeccin
La tercera matriz, denominada matriz de proyeccin, especifica principalmente es
cala y perspectiva adoptada. Esta matriz determinar tambin cunto vemos de la
escena; es decir, el volumen de visualizacin.
ANTES DE EMPEZAR
Para hacer uso del API deberemos utilizar los espacios de nombre Microsoft.DirectX
9.0c.
346
u s r .c o d e
I n i c ia li z a r D ir e c t 3 D
La clase
tas para el manejo de las matrices del API y, principalmente, mantener alejadas el
resto de las clases de cdigo especfico de DirectX; por lo tanto, el da de maana
podramos realizar un cambio a otra librera, como OpenGL, sin por esto tener que
modificar cada vez todas las clases de nuestra aplicacin.
La clase Piso y la clase Pirmide representarn los objetos 3D que veremos en pan
talla. Cada una de ellas almacenar la informacin de geometra de los objetos y se
comunicar con la clase Renderer para transferrselos en el momento de tener que
colocarlos en pantalla.
La clase frmMain ser la principal de nuestra pequea aplicacin: coordinar el tra
bajo entre las otras clases y mantendr el bucle en el cual se invocarn los mtodos
necesarios de las otras clases para dibujar la escena en pantalla.
INICIALIZAR DIRECT3D
El mtodo Init ser el encargado de inicializar el API para poder comenzar a dibu
jar objetos. Para esto necesitamos hacer uso principalmente de la clase Device de Di-
rect3D
(espacio de nombres
Microsoft.DirectX.Direct3D),
que es el dispositivo de
PROGRAMACIN C#
Como primer paso, nos disponemos a realizar la creacin de un objeto del tipo Device por medio del operador new y haciendo uso del constructor de la clase que po
see parmetros. Analicemos a continuacin el prototipo del mtodo:
public Devicel
int adaptador,
DeviceType tipoDispositivo,
Control vetitanaeRenderiracin,
CreateFlags PlagaDeConportamiento,
PresentParameters parmetroaDePresentacifin
);
u s r.c o d e
In ic ia liz a r D ir e c t3 D
de especificar el procesa
CreateFlags.MixedVertexProcessing:
()>
ddPreaentParama.Windowad * true;
dJdPreaentParama.SwapSffeot = SwapEffect.Diacard;
Windowed:
completa. Esta opcin es muy importante, ya que el modo ventana implica una se
rie de restricciones en la determinacin de otros parmetros. Por ejemplo, no po
dremos cambiar la resolucin al haber otras aplicaciones en el mismo escritorio.
SwapEffect: existe un concepto bsico que utilizamos cuando dibujamos en panta
lla, y es que lo estamos haciendo en una superficie de memoria, que puede ser de
Existen configuraciones ms convenientes que otras respecto al tipo de dispositivo por elegir. Et
problema es que no todo el hardware existente soporta las mismas opciones. En ocasiones no que
dar otra opcin que procesar vrtices por software si deseamos que nuestra aplicacin funcione.
u s r .c o d e
34 9
PROGRAMACIN C#
{
PresentParameters d3dPresentParams = new PresentParameters();
d3dPresentParams.Windowed = truej
d3dPresentParams.SwapEffect = SwapEffect.Discardj
try
{
m_device = new Device(0, DeviceType.Hardware, devWin,
CreatePlags.HardwareVertexProcessing, d3dPresentParams);
}
catch (DirectXException)
{
try
{
m d evice = new Device(0, DeviceType.Hardware, devWin,
CreateFlags.SoftwareVertexProcessing, d3dPresentParams
);
}
catch (DirectXException)
{
return falsej
}
}
return DisponerEscenaO;
350
u s r.c o d e
In ic ia liz a r D ir e c t3 t)
El mtodo Init recibe el control sobre el que se crear el dispositivo.Existen dos blo
ques try.catch anidados, ya que en
primera instancia intentamos crearundispositi
vo que procese vrtices por hardware, pero en caso de fracasar, repetimos el inten
to especificando que el procesamiento de vrtices se realice por software.
Por ltimo, el mtodo
{
// Por el momento, no utilizaremos iluminacin
m_device.RenderState.Lighting = falee;
// Fijamos
el valor de
del mtodo
esttico de
Matrix, LookAtLH
4,
retura true;
; )
2.
medio de la propiedad RenderState.Lighting de la clase Device. La propiedad RenderState nos ser muy til en el futuro porque modifica opciones internas de Direct3D que alteran el modo en que son dibujados los objetos en pantalla.
Fijamos el valor de la matriz de vista haciendo uso del mtodo esttico LookAtLH
de la clase Matrix, que nos permite especificar, po: medio de tres parmetros, des
de qu punto deseamos mirar la escena, a qu punto deseamos mirar y, final
mente, cul es el arriba en nuestro mundo.
3. Fijamos el valor de la matriz de proyeccin por medio del mtodo esttico Pers
pectiveFovLH de la clase Matrix por medio de cuatro parmetros: campo de vi
sin (especificamos lo usual, que es el nmero PI dividido cuatro), la relacin
existente entre el alto y ancho de nuestra escena, el plano de recorte cercano y
el plano de recorte lejano. Todas estas propiedades delimitan el volumen de visualizacin de la escena que observaremos.
!
u s r .c o d e
351
PROGRAMACIN C#
Con nuestro flamante mtodo Init, veremos ahora cmo hacer uso de l por medio
de una instancia de Renderer en la clase frmMain:
- A'lt
'i:\ '
V^.A'-vv',&^ f'
{
// I n s t a n d o un nuevo o b je to
el
fo r m u la r io no sea d e s tr u id o
while(frm.Created)
{
// D ib u jo l a escena
frm.Dibujar ();
// A tie n d o eve n to s
Application.DoEvents();
}
}
En
la primera lnea, lo que hicimos fue crear una instancia del formulario frmMain.
Por medio del mtodo Show, lo mostramos en pantalla; luego invocamos un mto352
u s r .c o d e
In ic ia liz a r D ir e c t3 D
u s r .c o d e
353
PROGRAMACIN CU
{
mdevice.Clear(ClearPlags.Target, System.Drawing.Color.Black,
l.O f, 0))
}
FOROS DE AYUDA
354
usr.code
In ic ia liz a r D ir e c t3 D
u s r .c o d e
355
PROGRAMACIN C#
F.l mtodo ComienzoEscena de Renderer se ocupar de invocar el mtodo BeginScene de la clase Device. Direct3D nos indica que se debe llamar a este mtodo previa
mente a la realizacin del dibujado de cualquier objeto.
public void ComienzoEscena0 { m_device.EeginScene()?}
El mtodo
FinEscena
EndScene
de la clase Device.
Direct3D indica que se debe llamar este mtodo cuando finalizamos el procesa
miento de vrtices relacionados con una escena.
public void FinEscenaO { m device.EndScene(); }
DIBUJAR OBJETOS
Por cada objeto mostrado en pantalla deberemos poseer un array de vrtices, de!
formato seleccionado, con la informacin de geometra de ste. Por esta razn, es
conveniente crear una clase para cada uno de ellos. Luego, existir un mtodo lla
mado Dibujar en el cual le pasaremos a la clase Renderer el contenido de dicho
array para que sea procesado.
As, pues, crearemos la clase Piso con el array de vrtices correspondiente:
public class Piso
{
// Array de vrtices del piso
prvate CustomVertex.PositionColored[] m_verts =
new CuBtomVertex.Po8tionColored[6];
II ...
};
356
u s r.c o d e
D ib u ja r o b je to s
v4
v5
Como la informacin del piso no variar, lo nico que tendremos que rellenar se
r este array una vez. Esto no quiere decir que el piso no pueda ser movido, esca
lado o rotado en cualquier eje, porque para eso podremos modificar la matriz de
mundo, que rectificar a su vez el vrtice entrante para entonces colocarlo en la
posicin que nos plazca. En consecuencia, podremos completar la informacin
del array en el constructor de la clase Piso:
public Piso()
{
// Cara A
// Vrtice 1
1/
Vrtice 3
m _ v e rts [2 ] .X
- 2 5 . O f;
m _ v e rts [2 ].Y
-3 . O f;
m v e rts [2 ]. Z
2 5 . O f;
m_verts[2].Color = System.Drawing.Color.SkyBlue.ToArgb();
// Cara E
// Vrtice 1
usr.code
357
PROGRAMACIN C#
// Vrtice 2
m_vert8[4].X * 25.0; o_vert0[4].Y * -3.Of; mjrerts[41.Z * 25.Of;
m_verta{4].Color Syatea.Drawing.Color.SlateBlue.ToArgbO ;
// Vrtice 3
m_verts[5].X 25.Of; m_vertst5].Y = -3.Of; m_vert8[5].Z = -25.Of;
m_vertB[5] .Color a Syatem.Drawing.Color.SkyBlue.ToArgbO;
I }
Tal como podemos apreciar, cada uno de los vrtices posee una posicin y un color. Si
especificamos distintos colores para vrtices de un mismo tringulo, Direct3D se ocu
par de realizar una interpolacin de stos para otorgarles color a los pixeles interme
dios en el proceso de rasterizacin.
Ahora veamos el mtodo Dibujar de la misma dase:
public void Dibujar(Renderer rnd)
{
rnd.SetMatrixMode (eliatrixMode .MMJJORLD);
rnd.Loadldentity();
rnd.ProcsVertsfm verta, 6);
'
358
u s r.c o d e
D ib u ja r o b je to s
{
m d .SetHatrixMode (eMatrixMode.MM WORLD)
rnd.LoadldentityO;
// Modifico la escala |
if (ofEscalaX 1= l.Of || m_fBscalaY != l.Of jj m_fBscalaZ != l.Of)
rnd.Scale(m fBscalaX, m_fBscalaY, mfEscalaZ);
// Modifico el ngulo de rotacin sobre el eje Y
if (mjAngleY l O.Of)
rad.RotateY(mfAngleY) ;
rnd.ProcsVerts(jverts, 12);
(
mdevice.VertexFormat = CuatomVertex.PositionColored.Format;
mdevice.DrawDserPriBiitives (PrimitiveType .TriangleList,
iVertCount / 3, verts);
El mtodo
ProcsVerts,
Renderer,
tiene la
35S
PROGRAMACIN C#
VertexFormat de la clase Device al formato del vrtice que nos disponemos a pro
cesar. Luego, invocamos el mtodo DrawUserPrimitives. En el primer parmetro
especificamos el tipo de primitiva, en el segundo parmetro detallamos qu can
tidad de primitivas hay que realizar y, por ltimo, pasamos el array donde se en
cuentran los vrtices de nuestro objeto.
vl
v3
v5
LineUst
v4
v6
v2 V4 v6
LineStrip
Tira de lneas, Direct3D tomar ios dos primeros vrtices del grupo
y trazar un segmento, luego tomar el siguiente elemento y trazar
otro segmento conectado coo ei antenor, y as sucesivamente. De este
modo queda formada una sucesin de segmentos conectados entre s.
Tnanglelist
vi
v3
v5
vi
v3
v5
tringulos independientes.
TriangleSrip
v2
TriangieFan
v4
v6
v
Tabla 1. Tipos de primitivas.
360
u i.c o d e
E j e c u t a r la a p l ic a c i n
EJECUTAR LA APLICACIN
La escena puede ser rotada en los ejes X e Y por medio del uso del mouse, y tam
bin estaremos en condiciones de modificar la escala de la pirmide en cualquiera
de sus componentes y hacerla rotar sobre su eje Y. Todo esto, sencillamente, mani
pulando las matrices de mundo y vista.
En el sitio web
resum en
Direct3D es una API extensa y compleja, pero las posibilidades que ofrece son prcticamen
te ilimitadas. Sus usos tambin son muy variados, y no slo se utiliza en juegos de compu
tadora, sino tambin en aplicaciones de medicina, visualizacin de terrenos, grficos esta
dsticos dinmicos en 30, etc.
u s r .c o d e
361
ACTIVIDADES
TEST DE AUTOEVALUACIN
1 Se puede modificar la posicin de un obje
vrtices?
sus vrtices?
4x4?
diUMliZftddfl
(troifswj
puodtNmu
litwxj
362
.c o d e
PROGRAMACIN C#
Apndice
[-----------------------------'
Documentacin
de cdigo
La documentacin del cdigo de un
sistema (en un formato prctico) es una
tarea ardua y tiende a quedar obsoleta
con el devenir de nuevas versiones.
Pero el cdigo de un programa
debera estar debidamente comentado
para facilitar el trabajo del
programador y evitar los errores
derivados de una mala interpretacin
de lo que debera hacer una funcin.
364
367
368
PROGRAMACIN C#
lll
</summary>
namespace ProgCS
lll
lll
<summary>
Descripcin de la ciase Classl
/,// </summary>
///
claas Classl
lll
H
lll
<summary>
Descripcin del mtodo mi
</suramary>
public void m i {)
{
}
/// <summary>
lll
lll
{
}
j!
lll
<summary>
Descripcin del mtodo mi
/// </summary>
364
u t 't .c o d e
C m o d o c u m e n ta r c d ig o
{
return true;
}
}
Hecho esto, el compilador generar (adems de la salida usual del programa com
pilado) un archivo llamado docxml.xml (podra llamarse de cualquier otro modo),
que para nuestro ejemplo poseer el siguiente contenido:
<?xml version="1.0,'?>
<doc>
<assembly>
<name>Classl</naine>
-c/assembly?
<members>
<member name="T:ProgCS.Classl">
<suinmary>
Descripcin del namespace ProgCS </summary>
</member>
cmember name="H:ProgCS.Clasel.ml">
<summary>
Descripcin del mtodo mi
c/summary?
</member>
u s r .c o d e
365
PROGRAMACIN CU
<memher
<aummary>
Descripcin del mtodo m2
</summary>
</member>
<member name="M:ProsCS.Claasl ,m3 (System.Int32)">
<summary>
Descripcin del mtodo m3
</summary>
<param name=',nun*>Descripcin parmetro num</param>
<returns>Descripcin del retorno del mtodo</returns>
</member>
</members>
</doc>
File.
orfiguration: |ActiYt<Debug)
E3
L j Common Properte-s
G j Conbguratco Properties
jr ]
CQnfijxatJcn Manager.,.
<
y Cutd
Optimia Code
Debugpng
Advenced
Falte
Falte
Waming level 1
Falte
b<n\Debug\
: '
X M l D o c u m e n ta tio n F ie
Specfie the ame dt a We hto *hctr docimeotation comments ivtfi be
pcocessod. Path mus be relaive lo the pro)ect rectory (/doi:).
| Acepta
Cancdar
Ayuda
366
u s r.c o d e
C m o d o c u m e n ta r c d ig o
i
;
;
i
i
ave Web Pages in:
| C:lprojects\DocXirACosifr:onnmeRetrt
firOWM... i
&
tfeip
Presionando el botn
pginas abiertas por el entorno, o bien podremos abrirla con cualquier navegador.
Code Comment Web Report
UUmf |
"71
P r o g c s . c ia s s i c la s s
Dcisrce** del ivt.ii.-k frc?:s
u.
0wijvJn dl mnodo n:
III
> j\
367
PROGRAMACIN C#
/// <summary>
/// Descripcin del mtodo mi
III
</sununary>
{
}
</summary>
{
}
III
<sumniary>
/// </summary>
III
{
return true;
<example>...</example>:
368
u s r .c o d e
PROGRAMACIN CS
Apndice B
La notacin
Hngara
*' .
La convencin
Un tipo base
Un prefijo
Un calificador
370
370
370
371
Algunos ejemplos
371
Ventajas y desventajas
lectores@mpediciones.com
de la convencin
372
PROGRAMACIN CS
LA CONVENCIN
Al nombrar las variables, dificultamos la lectura del programa. Si a una variable sim
plemente la llamamos X , luego podramos no recordar su contenido, ocasionando
errores o retrasos en la codificacin.
Los identificadores de esta notacin se dividen en tres partes.
Un tipo base
Corresponde a la variable que ser nombrada. No siempre corresponde a un tipo de
dato fundamental, sino a uno ms abstracto. Debe ser escrito en minsculas.
1 TIPO BASE H f f l H I
Short
s
h ,n
:
Int
Long
US
Usliort
ui
Uint
ul
Ulong
Char
Double
Roat
le
b
Enum
Bool
Un prefijo
Se especifica antes de! tipo base y describe el uso de la variable.
Array
Contador
Elemento de un array
Variable global
; >
i
Handler (manejador)
ndice de un array
m_
Variable miembro
Puntero
Tabla 2. Prefijos.
370
u s r .c o d e
A lg u n o s e je m p lo s
Un calificador
Es la parte descriptiva de la variable o funcin que completa el nombre. Se reco
mienda usar nombres que tengan un significado apropiado con cada variable.
Si un calificador est compuesto por ms de una palabra, stas se escribirn juntas,
pero se colocar la primera letra de cada palabra en mayscula (no se permite la se
paracin de palabras con guiones de ningn tipo).
mn
first
last
lint
max
i, j, K, m,n
Contadores
Tabla 3. Calificadores estndar.
ALGUNOS EJEMPLOS
Veamos, finalmente, algunos ejemplos de nombramientos:
Identificador
m_iCantidad
U-Jui
i
-Calificador. Relacionado con el fin o oso de la variable.
. Tipo base. En este caso indica que el tipo de date
de la variable es un nmero entero.
. Prefijo. En este caso indica que
la variable es miembro de una clase.
usr.code
371
PROGRAMACIN CU
el califi
el resultado de una operacin (variable local)?: bRes (b es el tipo base [bool] y Res
es el calificador que abrevia la palabra resultado; no posee prefijo).
un array de nmeros flotantes que correspondiese a una lista de medidas (propie
dad de una clase)?: m_afMedidas
po arrayj,
usr.code
PROGRAMACIN C#
Apndice
UML
El lenguaje de modelado unificado,
tambin conocido como UML, es un
sistema notacional destinado al modelado
de aplicaciones que se basen,
principalmente, en conceptos de la
programacin orientada a objetos.
Introduccin
374
Diagramas de casos de uso "3 7 4
Diagramas de clases
'375
Diagramas de objetos
' 375
376
Diagramas de secuencia
Diagramas de estados
Diagramas de colaboracin
377
378
Diagramas de actividad
Diagramas de componentes
Extensiones a UML
379
380
380
PROGRAMACIN C#
INTRODUCCIN
El U M L se encuentra compuesto por una serie de diagramas que nos ayudarn a di
sear y documentar los diferentes componentes del sistema.
Muchos programadores comienzan sus proyectos escribiendo cdigo, pero en proyec
tos de gran complejidad, esto es un error, sobre todo si existe un equipo de trabajo
donde muchos programadores deben trabajar en distintas piezas de un rompecabezas.
Qu ocurrira si luego de meses de ardua labor las piezas no se conectaran correcta
mente? Sera necesario un anlisis y un diseo: U M L es la herramienta para ello.
Veamos cada uno de los diagramas y los elementos que componen este sistema.
In tro d u c c i n
Diagramas de clases
Describen la estructura esttica de un sistema, crr.o se encuentra estructurado ms
que cmo se comporta. Contiene los siguientes elementos:
Clases: que representan entidades con caractersticas comunes (atributos, opera
ciones y asociaciones).
Asociaciones: que representan relaciones entre eos o ms clases.
Es uno de los ms populares. Posee distintos niveles de detalles (mostrando o no
atributos y operaciones).
cardinalidad s
Diagramas de objetos
Describen la estructura de un sistema en un determinado momento; el diagrama de
clases lo hace en todo tipo de situacin (ya que no es posible crear clases de modo
dinmico), pero la cantidad de objetos de nuestro sistema puede cambiar durante
la ejecucin.
Contiene los siguientes elementos:
Objetos: representan entidades en particular. Son instancias de clases,
usr.code
375
PROGRAMACIN CS
- -
NaveOl: Sprte
Nombre
de la clase
* -
chequearCollsln =si
-----------
posicin x *=10
posicin y
=40
.
1
1
.......
relacin de
/
"composicin/
textOl: Textura
nombre - nave01.bmp
tam x -128
tamy =128 * ------
- -propiedades
Diagramas de secuencia
Describen interacciones entre objetos. Estas interacciones se modelan como inter
cambio de mensajes. Estos diagramas se focalizan en los mensajes que se intercam
bian para mostrar determinado comportamiento o accin.
Contiene los siguientes elementos:
Roles de clases: representan las funciones que los objetos asumen en determina
das interacciones.
Lneas de vida:
tiempo.
376
t:s :r.c o c le
In tro d u c c i n
objeto
objeto annimo
Diagramas de estados
Los objetos poseen un estado, y es posible que la accin que ejecutarn en funcin
de estmulos externos se base en el estado en el que se encuentren. El diagrama de
estados se encarga de describir cules son los posibles para un determinado objeto
y de que modo se pasa de uno a otro. Est compuesto por los siguientes elementos:
Estados: representan situaciones durante el tiempo de vida de un objeto cuando
se cumplen ciertas condiciones, se realiza o se espera la ocurrencia de un evento.
Transiciones: representan relaciones entre los diferentes estados de un objeto.
u s r .c o d e
377
PROGRAMACIN C#
estado final
Diagramas de colaboracin
Describen la interaccin entre clases y asociaciones. Estas interacciones son mode
ladas como intercambios de mensajes entre clases a travs de sus asociaciones.
direccin de los
mensajes
378
usr.code
In tro d u c c i n
Diagramas de actividad
Describen la actividad de una clase determinada. Estos diagramas son similares a los
de estado y utilizan una convencin similar, slo que describen el comportamiento
de una clase en respuesta a procesos internos, y no a eventos externos.
estado
inicial
estado de
accin
Patrullar
decisin
<>"
[no se avista
enemigos)
[se avista
eriem.go]
flujo de
/ control
ry [fuera de
alcance de
vistasj
__________ /
[enemigo
muerto]
estado
final
usr.code
379
PROGRAMACIN Cfl
Flujos de acciones:
una entidad.
Flujos de objetos:
Diagramas de componentes
Describen la organizacin y dependencia entre los distintos componentes de soft
ware en una implementacin. Sus componentes representan unidades fsicas distribuibles, incluyendo cdigo fuente, cdigo objeto y cdigo ejecutable.
dp
CZZI
Extensiones a UML
Un diagrama puede ser incapaz ce expresar una cierta arista de nuestro sistema. Por
dio U M L posee un sistema de extensin y personalizacin con el cual se puede
agregar nueva simbologa a los diagramas existentes, para que se adapten a nuestras
necesidades y poder usar nuevos estereotipos, propiedades, valores y restricciones.
380
.c e d e
PROGRAMACIN C#
Servicios
al lector
En esta seccin encontrar una completa
gua de sitios que contienen compiladores
para la plataforma .NET. Adems,
el ndice temtico, que le permitir
acceder al contenido de este manual
de forma precisa y rpida.
lectores@mpediciones.com
Lenguajes .NET
382
ndice temtico
385
PROGRAMACIN C#
LENGUAJES .NET
En ia siguiente lista se detallan compiladores especficos que generan cdigo en
MSIL para poder ser ejecutados sobre plataforma .NET. En algunos casos son len
guajes nuevos, y en otros, compiladores basados en conocidos lenguajes que ante
ceden a .NET.
Como podr apreciar, no son pocos los emprendimientos que se sumaron a la mo
vida .NET,
1 LENGUAJE BASE
A#
www.usafa.af.mil/dfcs/bios/mcc_htm/a_sharp.html
API
DyalogAPL
wyw.dyalog.com/
Basic
http://msdn.microsoft.com/vbasic/
i Basic
mbas
www.go-mono.com/mijas.html
c
ic
lee
www.cs.princeton.edu/software/lcc/
C1
http://msdamicrosofLcom/vcsharp/
mes
viww.go-mono.com/c-sharp.html
Ada
C#
m
o n o . .
D w nkrfdt O tK )H uphti
So m u M i O m u m M i U sa J u p
0(tfi
C++
Managed 0+
Caml
F#
http://research.microsoft.com/projects/ilx/fsharp.aspx
0CAMIL
www.ppsjussieu.fr/-montela/ocamil/cocumentation.html
pCaml
Coboi
http://msdn.microsoft.com/vsiudio/techinfo/articles/upgrade/inanagedexi.asp
NetCobol
www.netcobol.com/
NetExpress
www.microfocus.com/products/netexpress/
Delphi
Delphi 2005
www.borland.com/delphi/
Delphi
DeLphi.NET
http://sourceforge.net/projects/delphinet
Eiffel
Eiffel .NET
www.eiffel.com/
forth
DeLtaForth.NET
wwwdataman.ro/dforth/
fjcobof
382
usr.code
L e n g u a je s .N E T
LENGUAJEBASE
COMPILADOR
ENLACEASITIO
Fortran
FNT95
www.silverfrost.com/1l/ftn95/ftn95_fortran_95_for_wndows.asp
B B B 8
Hugs98for.NET
. http://gakKS.com/~SQf/hugs98.net/
Mondrian
www.mondrian-scriptorg/
HaskeS
HaskeH.NET
fitm://pu>.tn.ufpebr/-rasMf/h3Ske}kfetnet/
Java
Visual J# .NET
http://msdn.mlcrosoft.com/vjstiarp/
Haskell
J# es una
implementacln
particular del lenguaje
Java realizada por
Microsoft. En vez de
ejecutarse sobre una
mquina virtual de
Java, se ejecuta sobre
la plataforma .NET.
Java
IKVK1.NET
http://weblog.ikvm.net/
JavaScript
JScript .NET
www.gotdotnet.com/team/jscript/
JavaScript
JANET
hitpy/janetjs.sourciforge.net/
Lxico
Lxico
http://riosur.net/
USP
DotLisp
http://sourreforge.net/projects/dotiisp/
RDNZL
www.weitz.de/rdnzl/
USP
. LOGO
LOGO
: La
Mercuiy
Mixal
Monologo
http://monocigo^oiiicefofgejiet/
Turtlelracks
www.mech.upatras.gr/-TObgroup/logo/turtletracks/index.html
ljua.NET
www.lua.mf.puc-rio.br/luanet/
Mercury on .NET
www.cs.mu.oz.au/research/mercury/dotnet.html
Moal
http://sowceforge.net/projflcts/mixiid/
Nemerie
http://nemerle.org/
Perl
PerlSharp
http://taubz.for.net/code/pertsharp/
Perl
PeriNET
http://aspn.activestate.com/ASPN/NET
Chrome
www.chromesvritexom/
TMT.NET
www.tmt.com/neLhtm
Nemerie
i Pascal
Pascal
www.php.net/-rterting/mono/
Prolog
P#
www.dcs.ed.ac.Uk/home/jjc/psharp/psharp-l.l/dlpsharp.html
: PHP
Python
boo
http://boo.codehausrorg/
Python
IronPython
http://ironpython.com/
Python
Pythonfor .NET
http://star5hip.python.net/crew/mhammond/dotnet/
u s r .c o d e
383
PROGRAMACIN C#
1 LENGUAJE BASE
Ruby
COMPILADOR
ENLACEASITIOORCIAL
NetRuby
www.geocities.co.jp/SiliconVailey-PaloAlto/9251/ruby/nrb.html
wwwialtypicWe.com/fubydotnet/
Rutt
ftutry/.NET
Scala
Scala on .NET
http://scala.epfl.ch/index.html
Scheme
Larceny
www.ccs.neu.edu/home/will/l3fceny/
Scheme
Dot-Scheme
www.rivendell.ws/riot-scheme/
Welcome
Vchme i: the dvt-KhccK weftfAft d .M d m iri; 1 i L':~. i/.r fcotet I:- tht 1 w b T raratttw . h r. Ji i c<cf<cbe:_*r.i * ;;;< lFT
s-ff-rsf rd 'Z jirJ tr*rj.i.n hxr.Jk{. rej };<: f.r UTT
t u l i r A l.y Ij ito; feuxid l'T T ud .c. i
Documentation
To Ujo ax< ahtit
lenguajes que al da
v-/* <>.
C V c k a th? St oteiifffjS
A t vhetK w s rk sio
f^
6y#.c tbeMtf rayyj
P w tbf 'K
t
r
x
'jr
:. f Or m ;
de hoy mantienen
U *. i--* b
>
&
r j l : tuefii!)
cierta popularidad
Download
en la comunidad
te pxaets
poseen sus
Scheme no es una
excepcin.
i
1.
HotDog
http://novef.cs.northwestefn.edu/-scbeme/
Scheme
Tachy
www.kenrawlings.com/pages/Tachy
Scheme
Scheme.NET
www.cs.indian3.edu/igrinbla/index.htm
SmallTalk
#SmallTalk
www.refactoiy.com/Software/SharpSmalltalk/
SmallTalk
VMXSmallTalk
http://vmx-net.com/
SML
SML.NET
www.cl.cam.ac.uk/Research/TSG/SMLNEf/
Spiy
Spiy
httpV/spry-lang.org/
Tcl/Tk
TickleSharp
http://forge.novell.com/modules/xfmod/project/7ticklesharp
384
u sr.code
n d ic e t e m tic o
INDICE TEMATICO
A
356
Dibujar objetos
Application
221
Diccionarios
190
Archivos
256
Direct3D
367
68
Arrays
158
Do
Arrays multidimensionales
173
Documentacin de cdigo
Asincrnico
335
Double
Atributos
301
B
...
366
66
j-
'
286
Errores
36
266
Espacios de nombres
Bases de datos
263
Estructuras
109
Boxing/Unboxing
300
Eventos
201
Excepciones
287
break
77
Bucle
66
F
File
256
66
C#
20
Float
C++
22
Flujo de ejecucin
55
Clase
8?
for
70
156
Clases abstractas
19
CLR
Colecciones
185
Comentarios
38
foreach
Formularios
Framework .NET
68, 87
Constantes
128
Constructores
Continu
77
Controles
222
Convencin
370
Hashtable
191
Herencia
116
ICollection
188
18?
Convenciones de nombramiento
61
IComparable
Convert
52
Identificadores
Coordenadas 3D
365
D
Decimal
185
lEnumerator
185
If
279
66
60
lEnumerable
55
II st
18?
Indexadores
179
Delegados
196
Int
Destructores
132
Interfaces
u s r .c o d e
19
38
Consol
DataSet
76
227
63
153
385
PROGRAMACIN C#
Managed DirectX
364
Sentencia de bucle
260
Sentencias condicionales
257
Servicios web
Mtodos
Mtodos virtuales
145
Modificadores de acceso
122
MSIL
19
Short
Sincrnico
Sintaxis
Sobrecarga de mtodos
Sobrecarga de operadores
Sockets
.NET
19
Notacin Hngara
370
SQL
Streams
switch
System.Timers.Timer
Objetos
86
Operadores
53, 60,141
Tags
P
Palabras reservadas
v .'
40
params
172
Polimorfismo
137
Tipo base
Tipo de datos
42,
Prefijo
370
UML
ProcsVerts
359
using
Propiedades
123
Punteros
313
37
Variable
39,
Variables estticas
Reflection
307
Renderer
359
Resolucin
209
w
while
Windows.Forns
66
196
WriteLine
386
u s r .c o d e
E q u iv a le n c ia d e t rm in o s
EQUIVALENCIA DE TRMINOS
1En este libro
Acceso dial up
Otras formas
T En ingls
Acceso de marcacin
Actualizacin
Update, Upgrade
Actualizar
Refresh
Bandwidth
Ancho de banda
Archivos
Files
Archivos adjuntos
Attach, Attachment
Backup
Balde de pintura
Bote de pintura
Database
Base de datos
Booteo
Inicio/Arranque
Boot
Buscador
Search enghe
Captura de pantalla
Snapshot
Folder
Carpeta
Casilla de correo
Buzn de correo
CD-ROM
Disco compacto
Compact disk
Chequear
Check
Chip
Pastilla
Cibercaf
Caf de Internet
Clipboard
Portapapeles
Cliquear
Pinchar
Colgar
Trabar
Tilt
Controlador
Adaptador
Driver
E-Mail,
Correo electrnico
Download
Defrag
Desfragmentar
Destornillador
Desarmador
Disco de inicio
Disco de arranque
Disco rgido
Hard disk
Disquete
Disco flexible
Floppy drive
Firewall
Cortafuego
Startup disk
Formatear
Format
Fuente
Font
Gabinete
Chasis, Cubierta
Grabadora de CD
Quemadora de CD
Grupo de noticias
CD Burn
Newsgroup
PROGRAMACIN CU
E n este libro
Otras formas
Handheld
Computadora de mano
En ingls
HyperText
Hipertexto
Hospedaje de sitios
Alojamientc de sitios
Hub
Concentrador
Hosting
Impresora
Printer
Inalmbrico
Wireless
E-Book
Libro electrnico
Lista de correo
Lista de distribucin
Motherboard
Mouse
Ratn
Browser
Navegador
Notebook
Mailing list
Computadora de mano,
Computadora porttil
Offline
Fuera de lnea
Online
En linea
Pgina de inicio
Home page
Panel de control
Control panel
Parlantes
Bocinas, Altavoces
PC
Personal Computer
Ficha, Solapa
Pila
Batera
Battery
Soundboard
Placa de sonido
Enchufar y usar
Por defecto
Por predefinicin
By default
Programas
Aplicacin, Utilitarios
Software, Applications
Protector de pantalla
Screensaver
Proveedor de acceso
Internet Service
a Internet
Provider
Puente
Bridge
Puerto Serial
Serial Port
Ranura
Slot
Red
Net, Network
Servidor
Server
Sistema operativo
SO
Sitio web
Site
Tarjeta de video
Placa de video
Tipear
Vinculo
38
Link
u s r.c o d e
A b r e v ia tu r a s c o m n m e n te u tiliz a d a s
Abreviatura
Definicin
ADSL
AGP
ANSI
ASCII
BASIC
BIOS
Bit
Bps
CD
Compact Disk
CGI
CPU
CRC
DNS
DPI
DVD
FTP
GB
Gigabyte
HTML
HTTP
IDE
IEEE
IP
Internet Protocol
IR
Infra Red
IRC
IRQ
ISO
ISP
KB
Kilobyte
LAN
LCD
LPT
MB
Megabyte
MBR
MHz
Megahertz
u s r .c o d e
389
PROGRAMACIN CA
1 A breviatura
Y Definicin
NETBEUI
OEM
OS
Operative System
NETBios
OSI
PCMCIA
PDA
Perl
PGP
PHP
P0P3
PPP
RAM
ROM
SMTP
SPX/IPX
SQL
de transferencia de correo
SSL
TCP/IP
UML
UDP
UPS
URL
USB
VGA
WAN
WAP
WWW
XML
390
u s r .c o d e
Sobre el autor
y la editorial
atencin
diseo
2 alPreste
Compare
precios
Tiene valores
agregados?
Visite
nuestro
sitio web
. jf
Verifique
el idioma
onweb.tectimes.com
Revise la fecha
de publicacin