Está en la página 1de 241

Capítulo 1

El Lenguaje C# y el Framework .NET

XÄ ÑÜ|Çv|ÑtÄ Å°Ü|àÉ wxÄ ÄxÇzât}x xá Ät vÄtÜ|wtw


ZtÄxÇ

Xå|áàx âÇ ÄxÇzât}x Öâx ät Åöá tÄÄö wx Ätá ÑtÄtuÜtáA


ctâÄÉ VÉxÄ{É

Tabla de Contenido

1.1 C# y el Framework de .NET........................................................................................................................ 1.2


1.2 Common Language Runtime (CLR) ........................................................................................................ 1.6
1.3 Microsoft Intermediate Language (MSIL)........................................................................................... 1.9
1.4 Lenguaje de programación C# ................................................................................................................1.11
1.5 Antecedentes del lenguaje ........................................................................................................................1.12
1.6 Características principales de C# ..........................................................................................................1.12

1.1 Capítulo 1: El Lenguaje C# y el Framework .NET


1.1 C# y el Framework de .NET

C# (pronunciado “C Sharp”) es el nuevo lenguaje de propósito general orientado a


objetos creado por Microsoft para su nueva plataforma .NET

Microsoft .NET es el conjunto de nuevas tecnologías en las que Microsoft ha estado


trabajando estos últimos años con el objetivo de mejorar tanto su sistema operativo
como su arquitectura de desarrollo anterior, para obtener una plataforma con la que sea
sencilla la construcción de software. Su objetivo es crear un marco de desarrollo de
software sencillo, reduciendo las vulnerabilidades y aumentando la seguridad de los
programas desarrollados. Imaginemos que es el intermediario entre el sistema operativo
y las aplicaciones, las aplicaciones dicen que hacer y el .Net Framework le dice al
sistema operativo como hacerlo.

El primer gran cambio que vivimos, fue el paso de la programación en MSDOS a la


programación Windows (Win16), más tarde con la evolución de los sistemas operativos,
el segundo cambio, las aplicaciones Win32, y ahora estamos viviendo la tercera de las
revoluciones, lo que Microsoft llama .NET Framework o más comúnmente .NET.

El .NET Framework, en general, es un marco de desarrollo que permite el desarrollo y


ejecución de diversas aplicaciones hechas en los diversos lenguajes que soportan,
.NET Framework, es una plataforma para construir, distribuir y ejecutar servicios Web y
aplicaciones.

La plataforma .NET ofrece numerosos servicios a las aplicaciones que para ella se
escriban, como son un recolección de basura, independencia de la plataforma, total
integración entre lenguajes (por ejemplo, es posible escribir una clase en C# que derive
de otra escrita en Visual Basic.NET que a su vez derive de otra escrita en Cobol)

Como se deduce del párrafo anterior, es posible programar la plataforma .NET en


prácticamente cualquier lenguaje, pero Microsoft ha decidido sacar uno nuevo porque
ha visto conveniente poder disponer de un lenguaje diseñado desde cero con vistas a
ser utilizado en .NET, un lenguaje que no cuente con elementos heredados de
versiones anteriores e innecesarios en esta plataforma y que por tanto sea lo más
sencillo posible para programarla aprovechando toda su potencia y versatilidad.

C# combina los mejores elementos de múltiples lenguajes de amplia difusión como C++,
Java, Visual Basic o Delphi. De hecho, su creador Anders Heljsberg fue también el
creador de muchos otros lenguajes y entornos como Turbo Pascal, Delphi o Visual J++.
La idea principal detrás del lenguaje es combinar la potencia de lenguajes como C++
con la sencillez de lenguajes como Visual Basic, y que además la migración a este
lenguaje por los programadores de C/C++/Java sea lo más inmediata posible.

Microsoft lanza esta nueva tecnología como respuesta a tecnología Java de Sun. El
Framework .NET tiene grandes similitudes con la plataforma Java, por eso todos
aquellos que estén familiarizados con Java comprenderán en seguida el funcionamiento
de .NET.

1.2 Capítulo 1: El Lenguaje C# y el Framework .NET


Además de C#, Microsoft proporciona Visual Studio.NET, la nueva versión de su
entorno de desarrollo adaptada a la plataforma .NET y que ofrece una interfaz común
para trabajar de manera cómoda y visual con cualquiera de los lenguajes de la
plataforma .NET (por defecto, C++, C#, Visual Basic.NET y JScript.NET, aunque
pueden añadirse nuevos lenguajes mediante los plugins que proporcionen sus
fabricantes).

Centrándonos en el concepto Framework .NET, como el término en inglés dice


(Framework = Armazón) es un marco en donde nuestras aplicaciones correrán.
Nuestras aplicaciones ya no corren directamente bajo el sistema operativo si no que
corren bajo este armazón o marco.

Elementos principales .NET Framework:

CLR (Common Language Runtime) l


Conjunto de clases del .NET Framework
ASP.NET
Los servicios Web Remoting
Windows Forms

El CLR es el motor de ejecución de las aplicaciones .NET, lo que en Java sería la


máquina virtual de Java, este motor se encarga de ejecutar todo el código .NET para
ello a de ser en dicho lenguaje. El CLR es el encargado de convertir este lenguaje
intermedio en leguaje máquina del procesador, esto normalmente se hace en tiempo
real por un compilador JIT (Just-In-Time) que lleva incorporado el CLR. Ver sección 1.2

El conjunto de clases del .NET Framework es la piedra angular de cualquier


desarrollador de .NET, es un rico conjunto de clases, interfaces, tipos que simplifican y
optimizan el desarrollo de aplicaciones .NET además de proporcionar acceso a la
funcionalidad del sistema. Como desarrolladores el dominio de este conjunto de clases
es vital para un buen desarrollo en .NET.

ASP.NET es la parte del .NET Framework dedicada al desarrollo Web. A través del
servidor Web (IIS) nuestras aplicaciones ASP.NET se ejecutarán bajo el CLR y
podremos usar el conjunto de clases del .NET Framework para desarrollarlas,
obteniendo así una versatilidad y una potencia nunca antes conseguida en las
aplicaciones ASP.

También son destacables los servicios Web, que nos permitirán comunicarnos a través
de Internet entre diferentes computadoras, incluso entre distintos sistemas. Así como
.NET Remoting que nos permite tener objetos en máquinas remotas e invocarlos desde
otras máquinas. Y Windows Forms, parte del .NET Framework que permite crear
aplicaciones en el más clásico de los sentidos.

En la figura 1.1 se puede observar en términos generales como se realiza la


compilación de un programa escrito en algún lenguaje como C#, el bloque CLR se
describe en la sección 1.2

1.3 Capítulo 1: El Lenguaje C# y el Framework .NET


Figura 1.1

Asimismo, usando Microsoft Visual C# 2008 Express Edition podemos desarrollar


aplicaciones de consola y de interfaz gráfica de usuario (GUI), junto con aplicaciones
Windows Forms, sitios Web, aplicaciones Web y servicios Web tanto en código nativo
como en el código administrado.

La unidad básica sobre la que trabaja el .NET Framework es el assembly (o


ensamblado en español), y en el mundo real lo podemos ver como los ejecutables (exe),
o librerías DLL generados usando algún lenguaje de programación.

Existen varias versiones del .NET Framework: 1.0, 1.1, 2.0, 3.0 y 3.5. En estas dos
ultimas versiones, el CLR es el mismo de la versión 2.0, pero con el agregado de 3
componentes más, como puede apreciarse en la figura 1.2:

1.4 Capítulo 1: El Lenguaje C# y el Framework .NET


-Windows Presentation Foundation (WPF): este permite obtener una mejor apariencia
de las aplicaciones Windows o web, usando para eso XAML (un lenguaje basado en
XML).

-Windows Communitation Foundation (WCF): este componente permite la


intercomunicación de aplicaciones .NET

-Windows Workflow Foundation (WWF): este componente permite la definición,


ejecución y gestión de flujos de trabajo (workflows).

Figura 1.2

1.5 Capítulo 1: El Lenguaje C# y el Framework .NET


No todas las versiones de .NET Framework se pueden instalar en todas las versiones
de Windows:

- v1.0: es soportada en Windows 98, NT 4.0, 2000, y XP


- v1.1: es soportada en Windows 98, NT 4.0, 2000, XP y Server 2003.
- v2.0: es soportada en Windows 98, 2000, XP, Server 2003, incluida por defecto en
Windows Vista y Server 2008.
- v3.0: es soportada en Windows XP SP2, Server 2003, incluida por defecto en Vista y
Server 2008.
- v3.5: es soportada en Windows XP SP2, Server 2003, Vista y Server 2008.

Por cierto que con Windows Vista ha salido ya el .Net Framework 3.0.

Existe un proyecto que está tratando de llevar esta arquitectura al mundo de Linux. Este
proyecto se llama Mono, y puedes encontrar información en la siguiente liga electrónica:
http://www.mono-project.com/Main_Page

1.2 Common Language Runtime (CLR)

El CLR es el verdadero núcleo del Framework de .Net, ya que es el entorno de


ejecución en el que se cargan las aplicaciones desarrolladas en los distintos lenguajes,
ampliando el conjunto de servicios que ofrece el sistema operativo estándar Win32. La
herramienta de desarrollo compila el código fuente de cualquiera de los lenguajes
soportados por .Net en un mismo código, denominado código intermedio (MSIL,
Microsoft Intermediate Language). Para generar dicho código el compilador se basa en
el Common Language Specification (CLS) que determina las reglas necesarias para
crear código MSIL compatible con el CLR.

Es el núcleo de la plataforma .NET. Es el motor encargado de gestionar la ejecución de


las aplicaciones para ella desarrolladas y a las que ofrece numerosos servicios que
simplifican su desarrollo y favorecen su fiabilidad y seguridad. Las principales
características y servicios que ofrece el CLR son:

• Modelo de programación consistente: A todos los servicios y facilidades


ofrecidos por el CLR se accede de la misma forma: a través de un modelo de
programación orientado a objetos. Esto es una diferencia importante respecto al
modo de acceso a los servicios ofrecidos por los algunos sistemas operativos
actuales (por ejemplo, los de la familia Windows), en los que a algunos servicios
se les accede a través de llamadas a funciones globales definidas en DLLs y a
otros a través de objetos (objetos COM en el caso de la familia Windows)

• Modelo de programación sencillo: Con el CLR desaparecen muchos


elementos complejos incluidos en los sistemas operativos actuales (registro de
Windows, GUIDs, HRESULTS, IUnknown, etc.) El CLR no es que abstraiga al

1.6 Capítulo 1: El Lenguaje C# y el Framework .NET


programador de estos conceptos, sino que son conceptos que no existen en la
plataforma .NET

• Eliminación del “infierno de las DLLs”: En la plataforma .NET desaparece el


problema conocido como “infierno de las DLLs” que se da en los sistemas
operativos actuales de la familia Windows, problema que consiste en que al
sustituirse versiones viejas de DLLs compartidas por versiones nuevas puede
que aplicaciones que fueron diseñadas para ser ejecutadas usando las viejas
dejen de funcionar si las nuevas no son 100% compatibles con las anteriores. En
la plataforma .NET las versiones nuevas de las DLLs pueden coexistir con las
viejas, de modo que las aplicaciones diseñadas para ejecutarse usando las
viejas podrán seguir usándolas tras instalación de las nuevas. Esto, obviamente,
simplifica mucho la instalación y desinstalación de software.

• Ejecución multiplataforma: El CLR actúa como una máquina virtual,


encargándose de ejecutar las aplicaciones diseñadas para la plataforma .NET.
Es decir, cualquier plataforma para la que exista una versión del CLR podrá
ejecutar cualquier aplicación .NET. Microsoft ha desarrollado versiones del CLR
para la mayoría de las versiones de Windows: Windows 95, Windows 98,
Windows ME, Windows NT 4.0, Windows 2000, Windows XP y Windows CE
(que puede ser usado en CPUs que no sean de la familia x86) Por otro lado
Microsoft ha firmado un acuerdo con Corel para portar el CLR a Linux y también
hay terceros que están desarrollando de manera independiente versiones de
libre distribución del CLR para Linux. Asimismo, dado que la arquitectura del
CLR está totalmente abierta, es posible que en el futuro se diseñen versiones del
mismo para otros sistemas operativos.

• Integración de lenguajes: Desde cualquier lenguaje para el que exista un


compilador que genere código para la plataforma .NET es posible utilizar código
generado para la misma usando cualquier otro lenguaje tal y como si de código
escrito usando el primero se tratase. Microsoft ha desarrollado un compilador de
C# que genera código de este tipo, así como versiones de sus compiladores de
Visual Basic (Visual Basic.NET) y C++ (C++ con extensiones gestionadas) que
también lo generan y una versión del intérprete de JScript (JScript.NET) que
puede interpretarlo. La integración de lenguajes es tal que es posible escribir una
clase en C# que herede de otra escrita en Visual Basic.NET que, a su vez,
herede de otra escrita en C++ con extensiones gestionadas.

• Gestión de memoria: El CLR incluye un recolector de basura que evita que el


programador tenga que tener en cuenta cuándo ha de destruir los objetos que
dejen de serle útiles. Este recolector es una aplicación que se activa cuando se
quiere crear algún objeto nuevo y se detecta que no queda memoria libre para
hacerlo, caso en que el recolector recorre la memoria dinámica asociada a la
aplicación, detecta qué objetos hay en ella que no puedan ser accedidos por el
código de la aplicación, y los elimina para limpiar la memoria de “objetos basura”
y permitir la creación de otros nuevos. Gracias a este recolector se evitan errores
de programación muy comunes como intentos de borrado de objetos ya
borrados, agotamiento de memoria por olvido de eliminación de objetos inútiles o
solicitud de acceso a miembros de objetos ya destruidos.

1.7 Capítulo 1: El Lenguaje C# y el Framework .NET


• Seguridad de tipos: El CLR facilita la detección de errores de programación
difíciles de localizar comprobando que toda conversión de tipos que se realice
durante la ejecución de una aplicación .NET se haga de modo que los tipos
origen y destino sean compatibles.

• Aislamiento de procesos: El CLR asegura que desde código perteneciente a


un determinado proceso no se pueda acceder a código o datos pertenecientes a
otro, lo que evita errores de programación muy frecuentes e impide que unos
procesos puedan atacar a otros. Esto se consigue gracias al sistema de
seguridad de tipos antes comentado, pues evita que se pueda convertir un
objeto a un tipo de mayor tamaño que el suyo propio, ya que al tratarlo como un
objeto de mayor tamaño podría accederse a espacios en memoria ajenos a él
que podrían pertenecer a otro proceso. También se consigue gracias a que no
se permite acceder a posiciones arbitrarias de memoria.

• Tratamiento de excepciones: En el CLR todos los errores que se puedan


producir durante la ejecución de una aplicación se propagan de igual manera:
mediante excepciones. Esto es muy diferente a como se venía haciendo en los
sistemas Windows hasta la aparición de la plataforma .NET, donde ciertos
errores se transmitían mediante códigos de error en formato Win32, otros
mediante HRESULTs y otros mediante excepciones.

El CLR permite que excepciones lanzadas desde código para .NET escrito en un
cierto lenguaje se puedan capturar en código escrito usando otro lenguaje, e
incluye mecanismos de depuración que pueden saltar desde código escrito para
.NET en un determinado lenguaje a código escrito en cualquier otro. Por
ejemplo, se puede recorrer la pila de llamadas de una excepción aunque ésta
incluya métodos definidos en otros módulos usando otros lenguajes.

• Soporte multihilo: El CLR es capaz de trabajar con aplicaciones divididas en


múltiples hilos de ejecución que pueden ir evolucionando por separado en
paralelo o intercalándose, según el número de procesadores de la máquina
sobre la que se ejecuten. Las aplicaciones pueden lanzar nuevos hilos,
destruirlos, suspenderlos por un tiempo o hasta que les llegue una notificación,
enviarles notificaciones, sincronizarlos, etc.

• Distribución transparente: El CLR ofrece la infraestructura necesaria para


crear objetos remotos y acceder a ellos de manera completamente transparente
a su localización real, tal y como si se encontrasen en la máquina que los utiliza.

• Seguridad avanzada: El CLR proporciona mecanismos para restringir la


ejecución de ciertos códigos o los permisos asignados a los mismos según su
prioridad o el usuario que los ejecute. Es decir, puede no darse el mismo nivel de
confianza a código procedente de Internet que a código instalado localmente o
procedente de una red local; puede no darse los mismos permisos a código
procedente de un determinado fabricante que a código de otro; y puede no darse
los mismos permisos a un mismo códigos según el usuario que lo esté
ejecutando o según el rol que éste desempeñe. Esto permite asegurar al
administrador de un sistema que el código que se esté ejecutando no pueda
poner en peligro la integridad de sus archivos, la del registro de Windows, etc.

1.8 Capítulo 1: El Lenguaje C# y el Framework .NET


• Interoperabilidad con código antiguo: El CLR incorpora los mecanismos
necesarios para poder acceder desde código escrito para la plataforma .NET a
código escrito previamente a la aparición de la misma y, por tanto, no preparado
para ser ejecutando dentro de ella. Estos mecanismos permiten tanto el acceso
a objetos COM como el acceso a funciones sueltas de DLLs preexistentes (como
la API Win32)

Como se puede deducir de las características comentadas, el CLR lo que hace es


gestionar la ejecución de las aplicaciones diseñadas para la plataforma .NET. Por esta
razón, al código de estas aplicaciones se le suele llamar código gestionado, y al código
no escrito para ser ejecutado directamente en la plataforma .NET se le suele llamar
código no gestionado.

1.3 Microsoft Intermediate Language (MSIL)

Los compiladores que generan código para la plataforma .NET no crean código
máquina para las diferentes plataformas hardware. Generan código escrito en un
lenguaje intermedio denominado Microsoft Intermediate Language. Cuando decimos
que un compilador crea código para la plataforma .NET, estamos diciendo que crea
código MSIL, que es el único lenguaje que es capaz de interpretar el CLR.

MSIL ha sido creado por Microsoft, después de consultar a numerosos especialistas en


compiladores y lenguajes. Se trata de un lenguaje de un nivel de abstracción más
elevado que los lenguajes de código máquina de las CPUs existentes, ya que permite
por ejemplo trabajar directamente con objetos (crearlos, destruirlos, inicializarlos, etc)
así como tablas y excepciones (lanzarlas, capturarlas y manejarlas). Hemos comentado
antes que el compilador de C#, desarrollado por Microsoft, genera código fuente MSIL,
así como que Microsoft ha desarrollado extensiones de sus compiladores de Visual
Basic y C++ que generan también código MSIL. Pero no son éstos los únicos lenguajes
que generan código MSIL, sino que son bastantes los lenguajes que han optado por
desarrollar una extensión que genere código MSIL para la plataforma .NET, como por
ejemplo Fortran, Haskell, java, Pascal, Perl, Python, o Smalltalk. Como se puede
observar la oferta es bastante amplia, ya que debido a la arquitectura de la plataforma
.NET, podemos programar nuestra aplicación en cualquiera de estos lenguajes,
accediendo a todos los servicios ofrecidos por el CLR.

Las principales ventajas del código MSIL es que facilita la ejecución multiplataforma y la
integración entre lenguajes al ser independiente de la CPU. Sin embargo, dado que las
CPU's no pueden ejecutar directamente código MSIL, es necesario convertirlo antes al
código nativo de la CPU en la que vayamos a ejecutar nuestra aplicación. De esto se
encarga un componente del CLR, denominado Compilador JIT (Just in Time). Este
compilador convierte dinámicamente el código MSIL a código nativo según sea
necesario. Se distribuye en tres versiones principales: compilador JIT normal,
económico y prejitter. El compilador JIT normal, es el que se suele usar por defecto.
Éste sólo compila el código MSIL a código nativo a medida que va siendo necesario, ya
que así se ahorra tiempo y memoria, al evitarse tener que compilar innecesariamente el
código que nunca se va a ejecutar. El compilador JIT económico funciona de forma
similar al compilador normal, solo que no realiza ninguna optimización de código al
compilar, sino que traduce cada instrucción MSIL por su equivalente en el código

1.9 Capítulo 1: El Lenguaje C# y el Framework .NET


máquina sobre el que se ejecute la aplicación. Está pensado para ser usado en CPUs
con poca potencia o memoria, ya que necesita menos tiempo para compilar y menos
memoria. Además de las dos versiones anteriores del compilador JIT, Microsoft
distribuye una tercera versión llamada prejitter, que se distribuye como una aplicación
en línea de comandos mediante la cual es posible compilar completamente cualquier
ejecutable o biblioteca que contenta código gestionado y convertirlo a código nativo.

Tras conocer casi al completo la arquitectura .NET, ya sabemos que las aplicaciones
primero se convierten al lenguaje MSIL para posteriormente convertirlas al lenguaje
nativo de la arquitectura hardware donde se ejecuten. Podemos pensar que la actuación
del compilador JIT puede disminuir el rendimiento de la aplicación compilada, debido a
que debe invertirse un cuantum de tiempo adicional para volver a compilar la aplicación
dependiendo de la arquitectura del procesador. Esto es cierto, pero comparándolo con
arquitecturas similares, como Java, resulta ser más eficiente ya que cada código no es
interpretado y compilado al lenguaje nativo cada vez que se ejecuta, sino que es
traducido una única vez; cuando se llama al método al que pertenece. Además, el
hecho de que el compilador JIT tenga acceso en tiempo de ejecución a la máquina
donde se ejecuta la aplicación hace que posea mucha más información de ella, por lo
que puede realizar más optimizaciones que las que podría realizar cualquier compilador
tradicional.

El Microsoft IL (Intermediate Language) es el lenguaje de programación que emiten, de


forma interna, los compiladores de lenguajes .NET, como VB.NET y C#. Nosotros
podemos escribir directamente en ese lenguaje, aunque, hay que admitirlo, no es una
tarea de todos los días. El aspecto de un programa escrito en IL es el de un texto,
donde cada renglón puede tener una instrucción simple. Nos recuerda el formato de
otros lenguajes de procesador. Pero hay que recordar, que el "procesador" para el cual
se escribe el IL, no existe: es sólo el CLR, la máquina virtual de .NET, el que sabe cómo
interpretar y ejecutar el código compilado IL.

1.10 Capítulo 1: El Lenguaje C# y el Framework .NET


El lenguaje IL es el lenguaje base de .NET, los compiladores producen un ejecutable IL,
que puede también ser generado con ilasm, y desensamblado con ildasm.

Para manipular IL, Microsoft nos provee de dos herramientas gratuitas, incluidas en el
.NET Framework SDK: el lldasm, que nos permite desensamblar un ejecutable .NET, y
ver su código IL, y el llasm, que dado un texto IL lo compila a ejecutable .NET.

Notablemente, .NET en su librería tiene funciones para la emisión de código IL, desde
nuestros programas, lo cual nos permite generar ejecutables "en el momento",
capacidad que puede ser aprovechada creativamente.

1.4 Lenguaje de programación C#

C# (pronunciado "si sharp") es un lenguaje de programación orientado a objetos


desarrollado y estandarizado por Microsoft como parte de su plataforma .NET, que
después fue aprobado como un estándar por la ECMA e ISO.
C# intenta aprovechar, en la medida de lo posible, las características de la plataforma
.NET. Este nuevo lenguaje, evolución natural de Java y C++, también intenta facilitar a
los programadores el cambio de plataforma, por su parecida sintaxis al lenguaje Java.
Su sintaxis básica deriva de C/C++ y utiliza el modelo de objetos de la plataforma .NET
el cual es similar al de Java aunque incluye mejoras derivadas de otros lenguajes (más
notablemente de Delphi y Java). C# fue diseñado para combinar el control de lenguajes
de bajo nivel como C y la velocidad de programación de lenguajes de alto nivel como
Visual Basic.

Sus principales creadores son Scott Wiltamuth y Anders Heljslberg, éste último conocido
por haber sido el diseñador del lenguaje Turbo Pascal y la herramienta de diseño rápido
Delphi. En la plataforma .NET es posible escribir código en muchos otros lenguajes,

1.11 Capítulo 1: El Lenguaje C# y el Framework .NET


pero C# es el único que ha sido diseñado específicamente para ser utilizado en ella.
Utilizar este lenguaje para programar en ella es mucho más sencillo e intuitivo que
hacerlo con cualquiera de los otros lenguajes que nos provee la plataforma .NET. Es
por esta razón que se suele decir que C# es el lenguaje nativo de .NET.

1.5 Antecedentes del lenguaje

Las batallas legales entre Microsoft y Sun Microsystems acerca de Java durante casi
cuatro años llevaron a Microsoft a plantearse la necesidad de un nuevo lenguaje de
programación. Mientras que Sun Microsystems sugería a Microsoft que asumiera los
términos de licencia del lenguaje Java, Microsoft desarrollaba su propia versión de Java,
J++, basada en la tecnología licenciada de Sun. La última versión de J++, la 7.0, no fue
tal, y Microsoft decidió lanzar C#, trabajando conjuntamente con el ECMA, para
estandarizar el lenguaje al mismo tiempo. Microsoft originalmente desarrollo un lenguaje
llamado “COOL’, que representaba únicamente una mejora del lenguaje C++. El
resultado significó la respuesta de Microsoft a la tecnología Java de Sun Microsystems.

De hecho, la sintaxis y estructuración de C# es muy similar a la de C++ y de Java, ya


que una de las intenciones de Microsoft era facilitar la migración de códigos escritos en
estos lenguajes a C#, y facilitar el aprendizaje a los desarrolladores habituados a ellos.
Sin embargo, su sencillez y el alto nivel de productividad son igualables a los de Visual
Basic. Un lenguaje que hubiese sido ideal para utilizar estas características hubiera sido
Java, pero debido a las inacabables batallas legales entre la empresa creadora de esta
tecnología, Sun Microsystems, y Microsoft, éste último ha tenido que desarrollar un
nuevo lenguaje que añadiese a las ventajas de Java las modificaciones que Microsoft
tenía pensado para mejorar esta tecnología, para convertirlo en un lenguaje orientado al
desarrollo de componentes.

En resumen, podemos afirmar que C# es un lenguaje de programación que hereda las


principales virtudes de sus predecesores, como Java, C++ o incluso Visual Basic, y las
combina en un único lenguaje. El hecho de que haya nacido hace poco no implica que
sea inmaduro: Microsoft ha escrito la mayor parte de la BCL (biblioteca de clases base)
usando este mismo lenguaje, por lo que es el más depurado y optimizado de los
incluidos en la plataforma de desarrollo de .NET.

1.6 Características principales de C#

A continuación enumeramos las principales características que definen al lenguaje de


programación C#. Algunas de estas características no son propias del lenguaje, sino de
la plataforma .NET, aunque se listan aquí ya que tienen una implicación directa en el
lenguaje.

Sencillez de uso C#
Elimina muchos elementos añadidos por otros lenguajes y que facilitan su uso y
compresión, como por ejemplo ficheros de cabecera, o ficheros fuentes IDL Interface
Definition Language, en inglés, lenguaje de definición de interfaces. Es por ello que se
dice que C# es autocontenido. Además, no se incorporan al lenguaje elementos poco
útiles, como por ejemplo macros, herencia múltiple u operadores diferentes al operador

1.12 Capítulo 1: El Lenguaje C# y el Framework .NET


de acceso a métodos (operador punto) para acceder a miembros de espacios de
nombres.

Modernidad
Al ser C# un lenguaje de última generación, incorpora elementos que se ha demostrado
a lo largo del tiempo que son muy útiles para el programador, como tipos decimales o
booleanos, un tipo básico string, así como una instrucción que permita recorrer
colecciones con facilidad (instrucción foreach). Estos elementos hay que simularlos en
otros lenguajes como C++ o Java.

Orientado a objetos
C# como lenguaje de última generación, y de propósito general, es orientado a objetos.
C# no permite la inclusión de funciones ni variables globales que no estén incluidos en
una definición de tipos, por lo que la orientación a objetos es mas pura y clara que en
otros lenguajes como C++. Además, C# soporta todas las características del paradigma
de la programación orientada a objetos, como son la encapsulación, la herencia y el
polimorfismo.

En lo referente a la encapsulación es importante señalar que aparte de los típicos


modificadores public, private y protected, C# añade un cuarto modificador llamado
internal, que puede combinarse con protected e indica que al elemento a cuya definición
precede sólo puede accederse desde su mismo ensamblado.

Respecto a la herencia -a diferencia de C++ y al igual que Java- C# sólo admite


herencia simple de clases ya que la múltiple provoca más quebraderos de cabeza que
facilidades y en la mayoría de los casos su utilidad puede ser simulada con facilidad
mediante herencia múltiple de interfaces. De todos modos, esto vuelve a ser más bien
una característica propia del CTS que de C#.

Orientado a componentes
La propia sintaxis de C# incluye elementos propios del diseño de componentes que
otros lenguajes tienen que simular mediante construcciones más o menos complejas.
Es decir, la sintaxis de C# permite definir cómodamente propiedades (similares a
campos de acceso controlado), eventos (asociación controlada de funciones de
respuesta a notificaciones) o atributos (información sobre un tipo o sus miembros).

Recolección de basura
Todo lenguaje incluido en la plataforma .NET tiene a su disposición el recolector de
basura del CLR. Esto implica que no es necesario incluir instrucciones de destrucción
de objetos en el lenguaje.

Seguridad de tipos
C# incluye mecanismos de control de acceso a tipos de datos, lo que garantiza que no
se produzcan errores difíciles de detectar como un acceso a memoria de ningún objeto,
por ejemplo. Para ello, el lenguaje provee de una serie de normas de sintaxis, como por
ejemplo no realizar conversiones entre tipos que no sean compatibles. Además, no se
pueden usar variables no inicializadas previamente, y en el acceso a tablas se hace una
comprobación de rangos para que no se excedan ninguno de los índices de la misma.
Se puede controlar así mismo los desbordamientos en operaciones aritméticas,
produciéndose excepciones cuando se produzcan.

1.13 Capítulo 1: El Lenguaje C# y el Framework .NET


Instrucciones seguras
Para evitar errores comunes como se producían programando en otros lenguajes, en C#
se han impuesto una serie de restricciones en el uso de instrucciones de control mas
comunes. Por ejemplo, la evaluación de toda condición ha de ser una expresión
condicional y no aritmética, como ocurría por ejemplo en C o en C++. Así se evitan
errores por confusión del operador igualdad con el de asignación. Otra restricción que
se impone en la instrucción de selección switch, imponiendo que toda selectora de la
instrucción finalice con una instrucción break o goto que indique cuál es la siguiente
acción a realizar.

Unificación de tipos
En C# todos los tipos derivan de una superclase común llamada System.Object, por lo
que automáticamente heredarían todos los miembros definidos en esta clase. Es decir,
son objetos. A diferencia de Java, en C# esta característica también se aplica para los
tipos básicos.

Gestión automática de memoria


Como ya se comentó, todo lenguaje de .NET tiene a su disposición el recolector de
basura del CLR. Esto tiene el efecto en el lenguaje de que no es necesario incluir
instrucciones de destrucción de objetos. Sin embargo, dado que la destrucción de los
objetos a través del recolector de basura es indeterminista y sólo se realiza cuando éste
se active –ya sea por falta de memoria, finalización de la aplicación o solicitud explícita
en el fuente-, C# también proporciona un mecanismo de liberación de recursos
determinista a través de la instrucción using.

Eficiente
En principio, en C# todo el código incluye numerosas restricciones para asegurar su
seguridad y no permite el uso de punteros. Sin embargo, y a diferencia de Java, en C#
es posible saltarse dichas restricciones manipulando objetos a través de punteros. Para
ello basta marcar regiones de código como inseguras (modificador unsafe) y podrán
usarse en ellas punteros de forma similar a cómo se hace en C++, lo que puede resultar
vital para situaciones donde se necesite una eficiencia y velocidad procesamiento muy
grandes.

Compatible
Para facilitar la migración de programadores, C# no sólo mantiene una sintaxis muy
similar a C, C++ o Java que permite incluir directamente en código escrito en C#
fragmentos de código escrito en estos lenguajes, sino que el CLR también ofrece, a
través de los llamados Platform Invocation Services (PInvoke), la posibilidad de acceder
a código nativo escrito como funciones sueltas no orientadas a objetos tales como las
DLLs de la API Win32. Nótese que la capacidad de usar punteros en código inseguro
permite que se pueda acceder con facilidad a este tipo de funciones, ya que éstas
muchas veces esperan recibir o devuelven punteros.

En resumen este es el marco de trabajo .NET

1.14 Capítulo 1: El Lenguaje C# y el Framework .NET


1.15 Capítulo 1: El Lenguaje C# y el Framework .NET
Capítulo 2

Introducción al entorno de
desarrollo integrado Visual C# 2008
Express Edition
”dâ° xá âÇ xáÑ•Ü|àâ vâÄà|ätwÉR Xá xÄ Öâx Ñâxwx Å|ÜtÜ Ätá vÉátá wxáwx Åâv{Éá ÑâÇàÉá wx
ä|áàtA ;[xÇÜç YA TÅ|xÄ<
f| {tç âÇ áxvÜxàÉ wxÄ uâxÇ °å|àÉ Üxá|wx xÇ Ät vtÑtv|wtw ÑtÜt tÑÜxv|tÜ xÄ ÑâÇàÉ wx ä|áàt wxÄ
ÑÜ™}|ÅÉ ç äxÜ Ätá vÉátá wxáwx xáx ÑâÇàÉ wx ä|áàt tá• vÉÅÉ wxÄ ÑÜÉÑ|ÉA
;[xÇÜç YÉÜw<

Tabla de Contenido
2.1 Compilación de un programa C# en la consola ............................................................................... 2
2.2 Compilación de un programa C# en Microsoft Visual C# 2008 Express Edition .......... 6
2.3 Elementos esenciales de un programa en C# ............................................................................... 12
2.3.1 Espacios de nombres ............................................................................................................................. 13
2.3.2 La función Main ( ) .................................................................................................................................. 14
2.4 Descripción del entorno de desarrollo IDE .................................................................................... 15
2.5 El explorador de soluciones ................................................................................................................... 18
2.6 Ventana de Propiedades .......................................................................................................................... 21
2.7 Lista de errores............................................................................................................................................. 21
2.8 Personalizando nuestro entorno de trabajo de Visual C# ..................................................... 23
2.9 Característica IntelliSense ...................................................................................................................... 25
2.10 Configuración de botones y menús ................................................................................................. 26
2.11 Ventana Inmediato y Depuración..................................................................................................... 28
2.12 La ayuda de Visual C#............................................................................................................................. 32

2.1 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
2.1 Compilación de un programa C# en la consola

Para compilar un programa desde la consola utilizamos el siguiente comando csc que
significa C Sharp Compiler, pero si observamos en la siguiente pantalla nos
muestra un error que nos indica que no reconoce el comando.

Podemos ver las variables de entorno de la variable path y debemos de agregar la ruta
C:\Windows\Microsoft.NET\Framework\v3.5 que es donde se encuentra el archivo
csc.exe, si observamos en la siguiente pantalla no aparece dicha ruta.

Para configurar dicha variable de entorno procedemos a configurar la variable de


entorno path, nos vamos a Panel de control → Sistema → Configuración
avanzada del sistema → Variables de Ambiente → Path → Edit y
agregamos la ruta: C:\Windows\Microsoft.NET\Framework\v3.5, como se muestra
en las siguientes dos pantallas. Antes de agregar la nueva ruta separamos con un punto y coma
;.

2.2 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Posteriormente procedemos a probar nuestro programa, en primer lugar comprobamos
que se encuentre la ruta especificada, con el comando echo “%path%” y observamos
que en la última línea ya se encuentra la ruta
C:\Windows\Microsoft.NET\Framework\v3.5

2.3 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Para comprobar que funciona damos el comando csc y vemos que nos da la versión
que estamos utilizando así como la compañía que lo creo es decir Microsoft, el error que
marca es debido a que no especificamos que archivo queremos compilar.

Si necesitamos conocer todas las opciones de compilación y como usarlas podemos


teclear el comando csc /? , y nos mostrara la ayuda del comando.

Vamos a realizar el siguiente programa, incluso puede realizarse en el bloc de notas, en


este caso aún no utilizaremos el entorno de desarrollo integrado: Visual C# 2008
Express Edition
2.4 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
Lo guardamos en el lugar que deseemos y desde la línea de comandos debemos de
observar el archivo a compilar, en este ejemplo se llama prueba.cs, la extensión del
archivo deberá ser cs.

Lo compilamos con el comando csc Prueba.cs y posteriormente lo ejecutamos


escribiendo simplemente Prueba, como se observa en la siguiente pantalla el programa
imprime simplemente dos líneas:

2.5 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Podemos comprobar que efectivamente se creo un archivo con el mismo nombre pero
con la extensión .exe, es decir se genero el archivo Prueba.exe

2.2 Compilación de un programa C# en Microsoft Visual C# 2008 Express


Edition

Vamos a realizar el mismo programa pero ahora con ayuda de Visual C# 2008 Express
Edition, para tal efecto abrimos

2.6 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
O si lo preferimos también podemos abrir el programa desde ejecutar y escribiendo el
comando VCSExpress:

Nos abrirá la siguiente pantalla:

2.7 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Nos vamos a Archivo → Nuevo Proyecto → Aplicación de Consola y le
damos el nombre Prueba.

Automáticamente nos mostrara el siguiente código:

2.8 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Copiamos las tres líneas después del Main que se encuentran en el bloc de notas y la
copiamos después de la llave de apertura del Main:

Nos vamos a Generar → Generar Solución o simplemente tecleamos F6 para


compilar nuestro proyecto otra opción más rápida es dar clic en Depurar → Iniciar
Depuración o F5:

2.9 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Al final en la ventana deberá de aparecer el mensaje Compilación Correcta si
elegimos la primera opción o F5:

Si elegimos la segunda opción o F6 automáticamente se ejecuta el programa:

Esto sucederá si no existe ningún error, intencionalmente en la línea donde imprimimos


Mi primer programa en C# vamos a quitar el punto y coma ; observemos que ocurre:

2.10 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Nos indica que en la línea 13 columna 67 del archivo Program.cs se
encuentra el error en este caso nos dice Se esperaba; observemos también que el
código nos indica con rojo que falta algo si damos doble clic al error 1 el cursor se
posicionara en donde se encuentra el error:

Finalmente guardamos nuestro proyectos nos vamos a Archivo → Guardar todo y


nos pedirá el nombre del proyecto en este ejemplo le di el nombre de Prueba, por
default lo guarda en la siguiente ruta: C:\Users\avalera\Documents\Visual
Studio 2008\Projects\Prueba que básicamente es dentro de la carpeta mis
documentos del nombre de usuario en la carpeta\Visual Studio
2008\Projects\, claro que podemos cambiar el origen de donde se guarda el
proyecto si uno así lo desea, para elegir otra ruta tendríamos que dar clic en examinar.

2.11 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
2.3 Elementos esenciales de un programa en C#

Nuestro primer programa es programa muy sencillo que se limita a imprimir dos líneas
de texto en pantalla. Nada útil desde un punto de vista práctico, pero suficiente para que
el principiante se familiarice con las herramientas de su entorno de trabajo y asimile
cuáles son los conceptos más elementales del lenguaje. Como puede ver, los
comentarios se pueden escribir al estilo del lenguaje de programación en C, con el
símbolo //, o bien delimitados por los símbolos /* y */. Este programa se encuentra
en un espacio de nombres llamado proyecto1 que sirve como una especie de carpeta
en la que agrupar clases de objetos relacionadas entre sí. Por lo tanto, para hacer
referencia a una clase es frecuente que no baste con su nombre y que sea necesario
indicar también el espacio de nombres en el que se encuentra. Por ejemplo, en nuestro
caso tenemos una única clase llamada Class1 en el espacio de nombres proyecto1,
por lo que su nombre completo sería proyecto1.Class1.

Por convenio, todo programa tiene una clase llamada Program con un método llamado
Main que es en el que comienza la ejecución. Fíjese en que Main debe escribirse con
la primera letra en mayúscula pues, la norma dice que todos los miembros públicos de
una clase deben empezar por una letra mayúscula. Fíjese también en que se trata de
un método con el modificador static, lo que significa que no es necesario tener ningún
objeto de la clase Program para poder llamarlo; esto es especialmente útil al comienzo
de la ejecución de un programa puesto que en ese momento aún no se ha creado
ningún objeto.

Para mostrar las dos líneas se utiliza la instrucción Console.WriteLine. Console es


una clase de objetos que cuenta con un método static llamado WriteLine. gracias
al cual es posible mostrar por pantalla cualquier información. Es importante insistir en
que Console es una clase de objetos, pero gracias a que el método WriteLine es static,
no es necesario crear ningún objeto de ella para poder escribir algo en pantalla. Algo
similar ocurre con el método ReadLine, que sirve para leer lo que el usuario introduce
por teclado, aunque en este ejemplo tan sólo lo usemos para parar el programa hasta
que el usuario pulsa la tecla Enter ya que descartamos lo que devuelve.

En este punto es importante aclarar que la clase Console se encuentra en el espacio


de nombres System, lo que se indica mediante la cláusula using System al comienzo

2.12 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
del programa. Este espacio contiene otras muchas clases que iremos descubriendo
poco a poco, pero por el momento es suficiente.

2.3.1 Espacios de nombres

Los espacios de nombres se utilizan en gran medida en la programación de C# de dos


maneras. En primer lugar, .NET Framework utiliza los espacios de nombres para
organizar sus múltiples clases, de la forma siguiente:

System.Console.WriteLine("UACM ");

System es un espacio de nombres y Console es una clase incluida en ese espacio de


nombres. Se puede utilizar la palabra clave using a fin de que no se requiera el nombre
completo, de la manera siguiente:
using System;
Console.WriteLine("UACM");
.NET Framework tiene clases en multitud de espacios de nombre predefinidos que pueden
usarse en otros códigos de C#. A continuación describimos algunos de los más comunes e
importantes.

System; Este espacio de nombre contiene clases que implementan funcionalidades


básicas, como conversiones de tipos de datos, operaciones matemáticas, invocación a
programas y gestión del entorno de procesos. El espacio de nombres System es el
mayor de los proporcionados por .NET Framework también contiene el espacio de
nombre Microsoft que brinda compatibilidad con versiones anteriores.

Sytem.Collections; Este espacio de nombre contiene clases que implementan


colecciones de objetos, como listas, colas, matrices, tablas hash y diccionarios.

Sytem.ComponentModel; contiene clases que se usan para crear componentes y


controles durante el tiempo de diseño y ejecución. Este espacio de nombre proporciona
interfaces y clases para crear atributos, establecer enlaces a varias fuentes de datos,
conceder licencias de componentes, además de convertidores de tipos.

System.IO; contiene clases que pueden leer y escribir flujos de datos y archivos de
disco. Las clases contenidas en este espacio de nombre pueden gestionar la entrada y
salida de archivos sincrónica y asincrónica.

System.Text; Contiene clases que permiten trabajar con codificaciones de caracteres


ASCII. Unicode, UTF-7 y UTF-8.

System.Windows.Forms; contiene clases para crear aplicaciones completas para


Windows. Proporcionan un entorno de clase .NET con los controles típicos de Windows
como cuadros de diálogo, menús y botones.

2.13 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
System.Drawing; contiene clases que implementan funcionalidad de dibujo del
Dispositivo de interfaz gráfica (GDI).

System.Data; contiene clases que componen la arquitectura de acceso a datos de


ADO.NET. La arquitectura ADO.NET permite construir componentes que pueden
gestionar datos de varias fuentes de datos en modo desconectado o conectado.

2.3.2 La función Main ( )

La función Main() es una parte importante de las aplicaciones ya que es donde


comienza a ejecutarse nuestro programa. Todas las aplicaciones escritas en C# deben
tener una clase con una función llamada Main() ; es conocida como el punto de entrada
de sus aplicaciones y la ejecución de las aplicaciones C# empieza con el código en Mai
n (); Si el código contiene mas de una clase, solo una de ellas puede tener una función
llamada Main() . Si olvida definir una función Main() recibirá varios mensajes de error
por parte del compilador.

Definida en la línea 6 no devuelve nada (por eso la palabra clave void) y no toma
argumentos (de ahí los paréntesis vacíos). El compilador C#. de hecho, acepta
cualquiera de las cuatro posibles construcciones de la función Main () :
static void Main(string[ ] args)

static void Main()


static int Main()
static int Main(string[] args)

La primera variante, static void Main(string[ ] args) es la forma usada en nuestro


proyecto, no devuelve un valor al que la llama. Sin embargo, toma una matriz de
cadenas. Cada cadena de la matriz corresponde a un argumento de la línea de
comando suministrado al ejecutar el programa.

2.14 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
2.3.3 Comentarios en el código

Comentar el código nos permite añadir notas a los archivos fuente de C#. Estas notas
pueden ayudarnos a documentar el diseño y el funcionamiento de la aplicación.
Podemos colocar comentarios en cualquier parte del código fuente de C# donde inicia
un bloque importante, clase, ciclo, para explicar el objetivo de cierto código.

Los comentarios de una línea empiezan con dos barras inclinadas y afecta el resto de la
línea, en ocasiones cuando probamos nuestro código y queremos borrar o eliminar una
línea temporalmente para observar que pasaría si eliminamos dicha línea, utilizamos al
inicio de la línea dicho comentario para no borrarla, posteriormente podemos regresar al
código original al eliminar nuevamente las dos barras inclinadas. En nuestro código en
la línea 3 existe este tipo de comentario.
{ //Este es un comentario

Existe una segunda forma de comentar el código y este se utiliza cuando es un


comentario extenso y ocupa varías líneas, empiezan por una barra inclinada seguida de
un asterisco y su efecto permanece hasta que encuentra un asterisco seguido por una
barra inclinada

/* Este es un comentario
de más de una línea podemos
escribir cuantas líneas deseamos
hasta concluir con asterisco diagonal */

La línea 10
System.Console.ReadLine();
Nos sirve para detener la pantalla de ejecución en MSDOS, si no la incluimos no
veríamos la ejecución de nuestro proyecto.

Es importante mencionar que las líneas 8, 9 y 10 podemos quitar la palabra System


que se encuentra al inicio de cada línea, debido a que tenemos declarado el espacio de
nombres using System; y el proyecto funciona exactamente igual, es decir dichas
líneas podrían quedar de la siguiente manera:

2.4 Descripción del entorno de desarrollo IDE

El entorno de desarrollo Microsoft Visual C# 2008 Express básicamente,


cuentan con los mismos elementos que podemos encontrar en cualquier otra
aplicación: ventanas con menús de opciones, barras de botones, menús
2.15 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
emergentes, paletas de herramientas, etc. En este sentido, el entorno de
desarrollo de Visual C# 1 no se diferencia en exceso del que podríamos
encontrar en un procesador de texto, retoque de imágenes una hoja de cálculo
o una aplicación de diseño. La diferencia, obvia, es que nosotros tratamos con
elementos relativamente abstractos: diseñamos ventanas y componentes y
codificamos una lógica de implementación que queda oculta.

En resumen podemos ver esta imagen que ilustra de manera general las ventanas
principales de entorno de Visual C#

Para poder hacer nuestro trabajo necesitamos, lógicamente, conocer el entorno


en el que vamos a desenvolvernos. En nuestro caso esto significa conocer los
elementos del entorno de desarrollo de Visual C#. Ese es el objetivo de este
sección indicar qué elementos son los más importantes y la manera de
utilizarlos.

Cuando ejecutamos nuestra aplicación esta es la primera pantalla que


observaremos, independientemente de los menús y botones situados en la parte
superior esta se divide básicamente en tres partes.

1Por simplicidad de aquí en adelante solo mencionaremos Visual C# y no el


nombre completo Microsoft Visual C# 2008 Express
2.16 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
1. Proyectos Recientes
2. Noticias para desarrolladores en Español
3. Introducción

Nótese que en la parte derecha de la pantalla se encuentra el explorador de


soluciones y en la parte inferior se encuentra la lista de errores ambas vacías
pues no tenemos ningún proyecto abierto.

Si abrimos nuestro primer proyecto llamado prueba a la siguiente pantalla:

2.17 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
El proyecto contiene todo el material necesario para la aplicación. Además de los
archivos de código fuente, incluye los archivos de recursos, como iconos, las
referencias a archivos externos de los que depende la aplicación y los datos de
configuración, como los valores del compilador. Cuando se genera un proyecto, Visual
C# invoca al compilador de C# y otras herramientas internas para crear un ensamblado
ejecutable con los archivos del proyecto. Mas adelante cuando se analice el Explorador
de Soluciones se mencionarán los objetivos y características de los archivos generados
por Visual C#

Si necesitamos abrir un proyecto debemos de ingresar a la carpeta del proyecto y abrir


el archivo con la extensión .sln o en su defecto abrir el archivo con la extensión
.csproj que se encuentra más al interior en la carpeta con el mismo nombre del
proyecto. Si trabajamos el proyecto en la Universidad y queremos trasladarlo a la PC de
nuestra casa o trabajo, o viceversa, es necesario copiar toda la carpeta completa de lo
contrario nuestro proyecto no funcionara.

Básicamente del lado derecho en la parte superior tenemos el Explorador de


Soluciones y en la parte derecha inferior la ventana de Propiedades, en la parte
inferior de la pantalla encontramos a la ventana que muestra la lista de errores cuando
compilamos el proyecto.

2.5 El explorador de soluciones

En la ventana del explorador de soluciones tenemos tres archivos correspondientes al


proyecto

2.18 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
El nodo Properties o Propiedades representa opciones de configuración que se
aplican a la totalidad del proyecto y se almacenan en el archivo .csproj de su carpeta de
soluciones. Esta configuración incluye opciones de compilación, seguridad e
implementación, entre muchas otras2.

En el contexto de un proyecto, una referencia o References identifica simplemente


un archivo binario que la aplicación necesita para poder ejecutarse. Normalmente, una
referencia identifica un archivo DLL, como uno de los archivos de la biblioteca de clases
de .NET Framework. También puede hacer referencia a un ensamblado .NET
(denominado shim) que permite que la aplicación llame a los métodos de un objeto
COM o de un archivo DLL nativo de Win32. Si su programa crea una instancia de una
clase definida en otro ensamblado, debe agregar una referencia al archivo
correspondiente en el proyecto antes de compilarlo. Para agregar una referencia, haga
clic en Agregar referencia en el menú Proyecto. Todos los proyectos de C#
incluyen de forma predeterminada una referencia a mscorlib.dll, que contiene las clases
básicas de .NET Framework. Puede agregar las referencias a archivos DLL de .NET
Framework adicionales y a otros archivos haciendo clic en el Menú Proyecto y
seleccionando Agregar referencia.

En caso de no mostrar la Ventana Propiedades o el Explorador de


Soluciones nos vamos al menú ver y seleccionamos la opción que necesitemos, es
importante mencionar que podemos encontrar en lugares diferentes dichas ventanas y
moverlos como nos convenga pero normalmente esta es la disposición de las ventanas
principales.

Un proyecto puede incluir cualquier número de archivos .cs adicionales asociados o no


a un formulario Windows Forms concreto. En la ilustración anterior del Explorador de
soluciones, program.cs contiene el punto de entrada para la aplicación. Un solo
archivo .cs puede contener cualquier número de definiciones de clases y estructuras.
Puede agregar archivos o clases nuevas o existentes al proyecto haciendo clic en
Agregar nuevo elemento o Agregar elemento existente en el menú
Proyecto.

2 http://msdn.microsoft.com/es-mx/library/ms173077(VS.80).aspx

2.19 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Otra manera de acceder a los diferentes
opciones del menú Ver es utilizando las teclas
de acceso rápido, por ejemplo para ver la
Ventana Propiedades utilizamos
Ctrl+W,P y para acceder al Explorador de
Soluciones utilizamos Ctrl+W,S.

El Explorador de soluciones nos permite ver


elementos y realizar tareas de administración
de elementos en una solución o en un
proyecto.

Cada uno de los elementos que aparece en el


Explorador de soluciones se almacena en un
archivo con una determinada extensión y
formato. La solución que relaciona a los demás
elementos, se guarda en un archivo de texto
con extensión sln. Una solución es un grupo de uno o varios proyectos y los elementos
asociados. Cada vez que se trabaja en el entorno de desarrollo integrado (IDE) está
trabajando con una solución; cada instancia de IDE puede contener una sola solución.
Los archivos sln Organiza proyectos, elementos de proyecto y elementos de solución y
proporciona al entorno referencias a sus ubicaciones en disco.

En la carpeta de Mis documentos, se encuentra una carpeta llamada Visual Studio


2008 y dentro de esta una carpeta llamada Projects en donde se alojan una carpeta
con cada uno de los proyectos generados y en cada carpeta del proyecto se encuentran
todos los archivos generados y relacionados con el proyecto, se sugiere revisar dicha
carpeta. En la siguiente pantalla se observa cuando queremos guardar un proyecto la
ruta por default en la que se guardara nuestro proyecto va asignando nombres como
ConsoleApplication1, se recomienda cambiar el nombre por uno que sugiera de
que trata el proyecto y sea fácil de identificar, también si lo deseamos en la pestaña
Examinar podemos cambiar la ruta donde guardaremos el proyecto.

Los proyectos de C# se almacenan con la extensión csproj, generado en XML que


contiene referencias a todos los elementos del proyecto, como formularios y clases,
2.20 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
además de referencias de proyecto, esta configuración incluye opciones de compilación,
seguridad e implementación, entre muchas otras.

2.6 Ventana de Propiedades

La ventana de propiedades es muy útil cuando trabajamos con Windows Forms por
ejemplo en botones, etiquetas, podemos cambiar el color, el texto, tamaño, tipo de letra,
etc, propiedad que se analizará con detalles en el capítulo 4, por lo pronto vemos en la
siguiente pantalla las propiedades del archivo program.cs.

2.7 Lista de errores

Cuando se hace clic en Generar Solución en el


menú Generar, se invoca al compilador de C#. Si la
generación se realiza correctamente, el panel de
estado muestra un mensaje Generación
satisfactoria.

Si se producen errores de compilación, aparece la ventana Lista de errores aparece


debajo de la ventana del editor/diseñador con una lista de errores.
En la lista de errores nos mostrara cada error encontrado si damos doble clic a la línea
donde se encuentra el error nos llevara a la línea de código correspondiente donde se

2.21 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
encuentra el error, es importante mencionar que a veces nos muestra muchos errores
pero en ocasiones están en cadena, esto significa que un error a su vez genera otros, al
corregir uno en ocasiones se corrigen otros, por eso a veces es bueno corregir un error
y volver a generar la solución para ver si nuestra solución es correcta y observar cuanto
errores nos quedan por resolver.

En nuestro ejemplo al final de una línea omitimos el ; (punto y coma) para ver que
sucede

Si seleccionamos el error, y presionamos la tecla F1 automáticamente nos dirigirá a la


documentación de Ayuda correspondiente al error resaltado.

El depurador tiene distintas ventanas que muestran valores de variables e información


de tipos a medida que se ejecuta la aplicación. Puede utilizar la ventana Editor de
código mientras depura el programa para especificar una línea en la que desee hacer
2.22 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
una pausa durante la ejecución en el depurador y para recorrer el código línea a línea.
Para obtener más información, vea Generar y depurar (Visual C#).

2.8 Personalizando nuestro entorno de trabajo de Visual C#

Para personalizar nuestro entorno de trabajo de Visual C# debemos ir a Opciones del


menú Herramientas

Una vez que entramos se muestra la siguiente pantalla, tenemos diferentes opciones
podemos configurar nuestro entorno, proyectos y soluciones, editor de textos, etc.

2.23 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Si entramos a Entorno, en la opción Fuentes y Colores, podemos cambiar los
valores predeterminados de nuestro Entorno de Programación, por ejemplo podemos
modificar el tamaño y tipo de letra, los colores del primer plano del elemento y del fondo.

En Proyectos y soluciones podemos cambiar la ruta donde se guardaran


nuestros proyectos, y agregar algunas opciones como Guardar nuevos proyectos
al crearlos o Mostrar ventana de resultados cuando empiece la
compilación.

2.24 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Otra opción interesante es la parte del Editor de texto, en C# podemos por
ejemplo seleccionar la opción Números de línea, esta opción es útil cuando nos
marca los errores nos indica el número de línea y si tenemos habilitada esta opción nos
facilitara el trabajo de corregir el código.

2.9 Característica IntelliSense

IntelliSense es una característica muy eficaz que puede aumentar de manera


significativa la velocidad de escritura de código, ya que proporciona elementos de
código lógicos que se pueden seleccionar en un menú desplegable cuando escribe
código. Está diseñado para facilitar el desarrollo de la aplicación ya que nos ayuda a
generar automáticamente el código. Este proceso puede reducir el tiempo que
invertimos en escribir y nos ayuda a evitar errores tipográficos en el código.

En el ejemplo de la figura, nosotros escribimos Console. después del punto nos


aparecerá las diferentes opciones que podemos seleccionar, si escogemos WirteLine
nos aparece un texto explicando su uso, en este caso nos dice que escribe la cadena
de texto especificada seguida de nueva línea, que es la diferencia con Write pues
esta no aplica un enter al finalizar la impresión del texto.

2.25 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
2.10 Configuración de botones y menús

En la parte superior del entorno de Visual C# aparecen varias barras de botones que
facilitan el acceso rápido a las opciones más habituales, la barra de botones cuentan en
el extremo izquierdo con una asa, al posicionarnos nos muestra una flecha tipo estrella
que apunta hacia los cuatro lados (abajo, arriba, izquierda, derecha) si damos clic con
botón principal de Mouse, podemos tomar la barra completa y llevarlas a cualquier otro
punto, disponiéndolas horizontal o verticalmente en los márgenes del entorno o bien
dejándolas como ventanas flotantes.

La configuración de las paletas de botones no es estática, podemos tanto ocultar como


mostrar barrad de botones, así como modificar los botones contenidos en ellas. En la
parte final de cada barra existe una flecha pequeña dirigida hacia abajo, si damos clic
en ella nos da la opción de agregar o quitar botones, como se muestra en la siguiente
pantalla.

2.26 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Otra manera de agregar o quitar barra de botones es ir al menú Ver → Barra de
Herramientas, y elegimos la barra que deseamos mostrar en nuestro entorno.

Cuando agregamos una barra nos muestra completamente todos los botones de la
barra, pero de acuerdo a nuestras necesidades podremos personalizar las diferentes
barras de botones quitando o agregando solo un elemento, para tal efecto damos clic
en la opción de Personalizar… y en la opción comandos, seleccionamos el elemento
que queremos incluir y lo arrastramos a la barra donde queremos que aparezca sin
necesidad de incluir toda una barra, de manera similar si damos clic en la un botón que
queramos eliminar lo arrastramos a esta ventana y se eliminara.

2.27 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
2.11 Ventana Inmediato y Depuración

La ventana Inmediato se utiliza en tiempo de diseño para depurar y evaluar


expresiones, ejecutar instrucciones, imprimir valores de variables, etc. Permite escribir
expresiones que el lenguaje de programación evalúa o ejecuta durante la depuración.
Para mostrar la ventana Inmediato, abra un proyecto para su edición, a continuación,
elija Ventanas en el menú Depurar y seleccione Inmediato.3

3 http://msdn.microsoft.com/es-es/library/f177hahy.aspx

2.28 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
En la ventana Inmediato escribimos la expresión que deseamos evaluar precedida por
el signo de interrogación, como se muestra en la siguiente pantalla:

En el primer caso obtenemos la raíz cuadrada de 144, en el segundo caso elevamos 5


al cubo y finalmente evaluamos la expresión 2+5*7.
Vamos a utilizar la Ventana Inmediato en un proyecto, para ello a nuestro código
agregamos dos líneas la línea 12 y 15.

Posteriormente seleccionamos la línea 12 y damos clic con el botón izquierdo del Mouse
y nos aparece el siguiente submenú, y seleccionamos la opción Punto de
2.29 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
Interrupción → Insertar punto de interrupción. Repetimos el mismo
procedimiento para la línea 15. En la línea 12 realmente realizamos el procedimiento
tres veces pues existen tres expresiones en dicha línea.

Cuando agregamos puntos de interrupción, aparece un círculo rojo y el texto


seleccionado indicando que existen puntos de interrupción. Los puntos de interrupción
indican el depurador que una aplicación debería interrumpirse, o hacer una pausa
durante la ejecución, en cierto punto. Cuando se produce una interrupción, se dice que
el programa y el depurador están en modo de interrupción.

Posteriormente nos vamos al menú Depurar → Iniciar depuración o


presionamos la tecla F5

2.30 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Presionamos F5 y automáticamente el programa se ejecutara paso a paso, deteniéndose en
cada punto de interrupción, en color amarillo nos indica en que punto nos encontramos:

Si deseamos eliminar los puntos de interrupción solo damos un clic sobre el texto o en el círculo
rojo y se eliminan.

En este parte podemos utilizar también la Ventana Inmediato y preguntar por el valor de las
variables de nuestro programa e incluso realizar operaciones con ella:

Otra ventana importante es la venta de Variables locales, en ella nos muestra el nombre
de la variable, su valor y el tipo.

2.31 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
2.12 La ayuda de Visual C#

Todas las opciones relativas a la ayuda las encontraremos en el menú del mismo
nombre. Desde él podremos acceder a la tabla de contenidos, buscar una cierta palabra
clave, establecer filtros, etc.

Si elegimos la opción Buscar del menú de Ayuda y tecleamos la palabra o instrucción


del tema que deseamos buscar nos mostrará la ayuda correspondiente por ejemplo en
la siguiente pantalla se muestra la ayuda de la instrucción repetitiva for, incluso nos
da un ejemplo de código que podemos copiar y pegar en el editor par comprobar su
funcionamiento.

2.32 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Una opción muy importante se encuentra en el siguiente menú Ver → Otras
ventanas → Explorador Web.

2.33 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Nos mostrara una gran cantidad de recursos en línea como Aprendizaje que contiene
tutoriales, videos, descargas, soporte técnico, foros.

Esta pantalla nos muestra los temas que se encuentra en discusión en la sesión de
Foros:
2.34 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#
2008 Express Edition
Si elegimos la opción Informar de un error del menú Ayuda,

2.35 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Nos invitan a participar en Microsoft Connect, que junto con la comunidad y Microsoft se
tiene la oportunidad aprender y colaborar en proyectos interesantes. O al menos encontrar
respuesta a nuestras dudas. Debemos de tener una cuenta en Windows Live para participar si
no contamos con una podemos crearla.

2.36 Capítulo 2: Introducción al entorno de desarrollo integrado Visual C#


2008 Express Edition
Capítulo 3

Métodos, Arreglos y Estructuras


La mejor estructura no garantizará los resultados ni el rendimiento. Pero la estructura
equivocada es una garantía de fracaso.
Peter Drucker
El éxito no se logra sólo con cualidades especiales. Es sobre todo un trabajo de constancia, de
método y de organización.
J.P. Sergent

Tabla de Contenido
Métodos .........................................................................................................................................................................................3.2
Métodos Estáticos.....................................................................................................................................................................3.4
Sobrecarga de Métodos .........................................................................................................................................................3.5
Paso de variables por valor y por referencia. ......................................................................................................... 3.11
Arreglos ...................................................................................................................................................................................... 3.13
Arreglos Unidimensionales .............................................................................................................................................. 3.14
Clase System.Array ............................................................................................................................................................... 3.15
Foreach........................................................................................................................................................................................ 3.27
Arreglos bidimensionales.................................................................................................................................................. 3.29
Estructuras ..................................................................................................................................... 3.34

3.1 Capítulo 3: Métodos, Arreglos y Estructuras


Métodos
Hasta ahora todo el código que hemos necesitado para que nuestros programas
funcionen lo hemos insertado, por regla general, en el método Main( ) porque en
realidad se ha tratado de llevar a cabo operaciones bastante sencillas. Sin embargo,
cuando el programa tenga alguna finalidad más que la simple acción de operaciones
básicas, comprobación o prueba de un control, la cantidad de código necesaria
crecerá y en ocasiones necesitaremos el mismo código en distintos puntos del
programa. Obviamente la solución no es introducir una y otra vez todo el código. Para
evitarlo podemos crear nuestros propios métodos introduciendo en ellas el código que
después podrá ser utilizado con una simple llamada.

En Introducción a la Programación manejamos funciones en C# en lugar de funciones


se conocen como métodos.

La denominación método se aplica a funciones que forman parte de una clase.


WriteLine( ), por ejemplo, es un método de la clase Consolé. Dado que en C# todas las
funciones tienen, obligatoriamente, que pertenecer a alguna clase, podríamos decir que
todas las funciones en C# son métodos. Por ello los términos función y método se
utilizan indistintamente en estecapítuloLa ejecución de las instrucciones de un método
puede producir como resultado un objeto de cualquier tipo. A este objeto se le llama valor de
retorno del método y es completamente opcional, pudiéndose escribir métodos que no
devuelvan ninguno.

La ejecución de las instrucciones de un método puede depender del valor de unas variables
especiales denominadas parámetros del método, de manera que en función del valor que se
dé a estas variables en cada llamada la ejecución del método se pueda realizar de una u otra
forma y podrá producir uno u otro valor de retorno.

Para definir un método hay que indicar tanto cuáles son las instrucciones que forman su cuerpo
como cuál es el nombre que se le dará, cuál es el tipo de objeto que puede devolver y cuáles
son los parámetros que puede tomar. Esto se indica definiéndolo así:

<tipoRetorno><nombreMétodo>(<parámetros>)
{
<cuerpo>
}

En <tipoRetorno> se indica cuál es el tipo de dato del objeto que el método devuelve, y si no
devuelve ninguno se ha de escribir void en su lugar.

Como nombre del método se puede poner en <nombreMétodo> cualquier identificador válido.

Aunque es posible escribir métodos que no tomen parámetros, si un método los toma se ha de
indicar en <parámetros> cuál es el nombre y tipo de cada uno, separándolos con comas si son
más de uno y siguiendo la sintaxis que más adelante se explica.

3.2 Capítulo 3: Métodos, Arreglos y Estructuras


El <cuerpo> del método también es opcional, pero si el método retorna algún tipo de objeto
entonces ha de incluir al menos una instrucción return que indique cuál objeto.

A continuación se muestra un ejemplo de cómo definir un método de nombre MisDatos() cuyo


cuerpo consiste en escribir en la consola mis datos como nombre, materia, mail, fecha y hora,
no devuelve ningún valor de retorno y tampoco tiene argumentos.

public void MisDatos() //método MisDatos


{Console.WriteLine('UACM IZTAPAPALAPA');
Console.WriteLine('PROGRAMACION ORIENTADA A OBJETOS EN C#');
Console.WriteLine('Armando Valera Paulino');
Console.WriteLine('mail: avalera@hotmail.com');
Console.WriteLine(DateTime.Now); Console.WriteLine('\n');
}

Veamos como quedaría el método dentro de un programa:

3.3 Capítulo 3: Métodos, Arreglos y Estructuras


Si modificamos el Main agregando las líneas que aparecen sombreadas de la siguiente
manera:

static void Main(string[] args)

{
Program prg=new Program();//Crea un objeto de la clase Program
prg.MisDatos();//Llama al método
// new Program().MisDatos();
}

Aquí creamos un objeto de la clase Program y posteriormente llamamos al método con el


objeto creado.

Métodos Estáticos
Una tercera versión del mismo programa es declarar el método MisDatos() estático con la
palabra clave static de esta manera al llamar al método simplemente lo realizamos con el
nombre de la clase punto el nombre del método es decir con la instrucción
Program.MisDatos();

static void Main(string[] args)

Program.MisDatos();

public static void MisDatos() //método MisDatos()

Los métodos static, son aquellos que se pueden ejecutar sin necesidad de instanciar la clase
donde está escrito. Un método estático es un método que existe en una clase como un todo
más que en una instancia específica de la clase. Por lo tanto, el hecho de que el método Main
tenga que ser static no es un capricho, ya que, de lo contrario, el CLR no sería capaz de
encontrarlo pues antes de que se ejecute la aplicación, lógicamente, no puede haber instancias
de ninguna de las clases que la componen.

En cualquiera de las tres versiones del programa el resultado de la ejecución sería el siguiente:

3.4 Capítulo 3: Métodos, Arreglos y Estructuras


Sobrecarga de Métodos

La sobrecarga de métodos consiste en poner varios métodos con el mismo nombre en la


misma clase, pero siempre que su lista de argumentos sea distinta, es decir, no puede haber
dos métodos que se llamen igual con la misma lista de argumentos, aunque devuelvan datos
de distinto tipo. El compilador sabría a cuál de todas las sobrecargas nos referimos por los
argumentos que se le pasen en la llamada, pero no sería capaz de determinar cuál de ellas
debe ejecutar si tienen la misma lista de argumentos. Lo que diferencia las listas de
argumentos de las diferentes sobrecargas no es el nombre de las variables, sino el tipo de cada
una de ellas.

En el siguiente ejemplo Sobrecarga1.cs tenemos tres métodos llamados Triple dentro de la


clase Principal, lo único que lo hace diferente es el tipo de argumento que recibe y que
devuelve, cuando se llama al método Triple dentro del método SobreCarga el compilador
sabrá cual de los tres ejecutar dependiendo del tipo de dato con que lo llame ya se int, double
o long.

3.5 Capítulo 3: Métodos, Arreglos y Estructuras


Observemos otra característica importante el método Triple es llamado dentro del método
SobreCarga el cual a su vez es llamado desde Main, entonces podemos concluir que dentro
de un método podemos llamar a otro método.

Ejecución del programa:

3.6 Capítulo 3: Métodos, Arreglos y Estructuras


En el primer caso al método se le llama con la instrucción int y = Triple(x); y
automáticamente por el tipo de dato que se le proporciona que en este caso es entero utiliza el
método respectivo private int Triple(int val) lo mismos sucede con los otros dos
métodos que se invocan.

#region permite especificar un bloque de código que se puede expandir o contraer cuando se
utiliza la característica de esquematización del editor de código de Visual C#.

Por ejemplo:

#region

private int Triple(int val)

return 3 * val;

private long Triple(long val)

return 3 * val;

private double Triple(double val)

return 3 * val;

#endregion

Utilizando el compilador observamos como en la línea 9 aparece en color gris #region aquí
estan ocultos los tres métodos Triple que corresponde a métodos sobrecargados para
terminar una región utilizamos #endregion . De forma predeterminada, todo el texto se
muestra en el editor de código, pero podemos hacer que no se vea parte del mismo. El editor
de código nos permite seleccionar una región de código y contraerla, de forma que aparezca
debajo de un signo más (+).

3.7 Capítulo 3: Métodos, Arreglos y Estructuras


Podremos expandir u ocultar la selección haciendo clic en el signo más (+) situado junto al
símbolo. El código esquematizado no se elimina, simplemente se oculta.

Si deseamos expandir y ver los métodos damos clic sobre el cuadro con el simbolo + y
obsevaremos lo siguiente:

Esta característica de esquematización es muy útil para organizar nuestro código y visualizar el
alcance de cierta sección de código, también en programas muy extensos esta propiedad es de
gran ayuda.

3.8 Capítulo 3: Métodos, Arreglos y Estructuras


Regresando a los métodos sobrecargados veamos el programa Sobrecarga2.cs,
observemos que los métodos ahora se encuentran definidos después del Main como lo
comentamos anteriormente pueden ir antes o después lo que debemos cuidar es que
pertenezca a la misma clase Principal, el programa muestra la sobrecarga de métodos
mayor lo único que cambia es el tipo de argumento y retorno que son int, char y double.

Esta el resultado de la ejecución del programa:

3.9 Capítulo 3: Métodos, Arreglos y Estructuras


El programa Sobrecarga3.cs es un caso totalmente diferente al anterior se aplica la
sobrecarga de método mayor pero con diferente números de argumentos 2, 3 y 4 argumentos,
nótese que en este caso el tipo de dato no cambia todos son de tipo entero.

Ejecución:

Si al programa Sobrecarga3.cs agregamos las líneas 13, 14 y 15 en el Main, muestra el titulo


POO en C#, en texto en color verde y fondo blanco.

3.10 Capítulo 3: Métodos, Arreglos y Estructuras


Ejecución:

Paso de variables por valor y por referencia.


En C# es posible pasar variables a los métodos de dos maneras: Por referencia y por valor. La
diferencia entre el uno y el otro es básicamente que:

Cuando una variable es pasada por valor, el método recibe una copia del valor de la variable.
Por lo tanto, los cambios realizados a esa variable dentro del contexto de la función, no afecta a
la variable original.

Cuando es pasada por referencia, el método recibe la referencia a la variable original. Por tanto
los cambios realizados a esa variable dentro del contexto de la función, afecta a la variable
original.

¿Cual debo usar?

Eso depende de lo que queramos hacer. Cada una tiene sus ventajas y desventajas. Al pasar
una variable por valor, estás asegurando que dicho valor no va a ser modificado por
equivocación. Por otro lado, al pasar una variable por referencia, aunque la variable puede ser
modificada por equivocación, ahorramos tiempo de ejecución y memoria, puesto que no es
necesario crear una copia de la variable.

Pasar variables por referencia

Todas las variables que pasamos a un método declarado normalmente, son por valor. Para
pasar argumentos por referencia es necesario utilizar las palabras reservada ref o out, tanto al
declarar el método como al invocarlo. Cuando pasamos un argumento usando ref, es necesario
que dicha variable esté ya inicializada, de lo contrario obtendremos una excepción o error. Si la
variable que deseamos pasar por referencia no está inicializada, es nesesario usar out, de tal
manera que podamos inicializar la variable dentro del contexto del método.

En el programa Valor1.cs observamos que al llamar una variable y modificarla el valor dentro
del método cambia a 25, posteriormente el valor después de llamar al método original no
cambia permanece en 5.

3.11 Capítulo 3: Métodos, Arreglos y Estructuras


Ejecución:

En contraparte en el programa Referencia1.cs despúes de llamar al método y modificar el la


variable el valor si cambi pues permanece en 25, para este caso utilizamos la palabra
reservada ref líneas 12 y 17 para indicar que el valor es pasado por referencia.

3.12 Capítulo 3: Métodos, Arreglos y Estructuras


Ejecución:

Arreglos

Los tipos de datos que hemos usado hasta ahora, en ejemplos previos, tan solo
pueden contener un dato, ya sea simple: un número, un carácter o una cadena.
Cuando se tiene la necesidad de almacenar múltiples valores, del mismo tipo y con
información relacionada, se usan los arreglos.
Un arreglo es una lista de variables del mismo tipo que comparten el nombre,
distinguiéndose unas de otras por un índice, l o s arreglos también son conocidos como
vectores para arreglos de una dimensión o matrices para arreglos de dos dimensiones.
Una variable de tipo arreglo no aloja el valor sino una referencia al bloque de memoria
donde éste se encuentra.

Los arreglos, al igual que el resto de las variables se identifican con un nombre. Al
emplear ese nombre, se hace referencia a la estructura de datos como un todo, es
decir, con todos sus elementos. El lenguaje interpreta dicho nombre como un puntero.
Para acceder a sus elementos se utiliza el nombre del arreglo en forma indexada, es
decir, combinado con índices, para acceder a un elemento en particular de un arreglo

3.13 Capítulo 3: Métodos, Arreglos y Estructuras


se usa por lo tanto el nombre del arreglo y un subíndice entre corchetes. La dirección
más baja corresponde al primer elemento que sería el subíndice cero y la más alta al
último que correspondería al subíndice n-1, donde n es el número total de elementos.

El lenguaje C# no controla la validez de los índices que se emplean para referenciar


un arreglo. Esto quiere decir que es posible cometer errores graves y difíciles de
detectar.

Arreglos Unidimensionales
Los arreglos, al igual que las demás variables deben declararse antes de poder
utilizarlas, los arreglos de una sola dimensión reciben también el nombre de vectores.

La sintaxis de la declaración de un arreglo unidimensional es la siguiente:


<tipo-base>[] <identificador>;
Observaciones:

• El <tipo-base> puede ser cualquiera de los tipos básicos del lenguaje, o incluso
algunos complejos como estructuras.

• El <identificador> es el nombre que distinguirá el arreglo.

• Los corchetes [] son obligatorios y denotan que el identificador descrito, del tipo
de variable indicado, es un arreglo.

• En esta declaración no se define el tamaño que tendrá el arreglo (aunque se


puede determinar las dimensiones, lo que se verá más adelante).

El tamaño del arreglo se determina en una segunda declaración, que puede ir en la


siguiente línea, como se muestra a continuación.

<identificador> = new <tipo-base> [<NumElementos>]

En esta declaración, se dimensiona el arreglo con una cantidad determinada de elementos,


todos correspondientes a tipo-base.

Es posible hacer la declaración del arreglo y su dimensionamiento en una misma sentencia:


<tipo-base>[] <identificador> = new <tipo-base>[<NumElementos>]

Adicionalmente es factible declarar, dimensionar, e inicializar un arreglo con todos sus


elementos, en una sola declaración:
<tipo-base>[] <identificador> = {valor1, valor2, ..., valorN};

Esta última declaración implícitamente dimensiona el arreglo para almacenar los N elementos
descritos, por lo que no se requiere dimensionarlo aparte.
Es decir:

• Con los valores indicados entre llaves { } se inicializarán los elementos del arreglo.

3.14 Capítulo 3: Métodos, Arreglos y Estructuras


• Los valores deben ser del <tipo-base> del arreglo.
También es factible declarar, dimensionar, e inicializar un arreglo con todos sus elementos, en
una sola declaración, pero sólo indicando un subconjunto de los valores que el arreglo puede
guardar:

<tipo-base>[] <identificador> = new <tipo-base>[N] {valor1, ..., valorM};

donde M<N, y N debe ser una expresión constante, como por ejemplo 10. Es factible hacer una
declaración donde M>N, en cuyo caso, el real dimensionamiento del arreglo se regirá por M.

Algunos ejemplos:

// Arreglo para 10 enteros


int [] numeros; numeros = new int[10];

// Arreglo para 10 enteros


int [] numeros = new int[10];

// Arreglo para 10 enteros


int [] numeros = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

A continuación se lista una tabla con los principales operaciones que se pueden realizar a un
arreglo las cuales pertenece a la clase System.Array

Clase System.Array

Método o Descripción
Propiedad

IsFixedSize Propiedad que indica si el arreglo es de tamaño fijo

Length Propiedad que retorna el tamaño del arreglo

Rank Propiedad que retorna el número de dimensiones del arreglo

Clear( ) Establece el valor de un rango de elementos de un arreglo


en 0

Copy( ) Copia una sección de un arreglo a otro arreglo

CopyTo( ) Copia todos los elementos de un arreglo a otro

IndexOf() Retorna el índice de la primera ocurrencia de un valor en


un arreglo unidimensional

LastIndexOf( ) Retorna el índice de la última ocurrencia de un valor en un

3.15 Capítulo 3: Métodos, Arreglos y Estructuras


arreglo unidimensional

Reverse() Invierte el orden de los elementos en un arreglo


unidimensional

Sort ( ) Ordena los elementos (que deben implementar IComparable) de


un arreglo unidimensional usando el algoritmo Quicksort

GetLength() Regresa el número de elementos de la dimensión especificada


de un arreglo.

GetLowerBound() Obtiene el índice del primer elemento del arreglo o límite


inferior de la dimensión especificada de un array

GetUpperBound() Proporciona el índice del último elemento del arreglo o


límite superior de la dimensión especificada de un array

Exists() Determina si el arreglo especificado contiene elementos que


coinciden con las condiciones definidas.

Find() Busca un elemento que coincida con las condiciones


definidas y devuelve la primera aparición en todo el
arreglo.

FindAll() Encuentra todos los elementos del arreglo que cumplen con
la condición.

FindIndex() Regresa el índice del primer elemento que cumple con la


condición.

FindLast() Regresa el último elemento que cumple con la condición.

FindLastIndex() Regresa el índice del último elemento que cumple con la


condición.

Remove() Elimina el primer elemento que se pasa como parámetro.

RemoveAt() Elimina el elemento de la posición especificada

RemoveRange() Elimina un rango de elementos

RemoveAll() Elimina todos los elementos que cumplen con la condición

3.16 Capítulo 3: Métodos, Arreglos y Estructuras


Analicemos el ejemplo del programa Arreglo1.cs:

En la línea 10 se declara e inicializa el arreglo de tipo entero llamado a con 10 elementos,


observemos que el número de elementos que irían entre corchete no contiene la dimensión
está vacío.

En la línea 11 se declara el arreglo b de diez elementos, pero no se inicializa, por tal razón se
inicializan automáticamente con cero.

En la línea 14 utilizamos un ciclo for para ir sumando cada uno de los elementos del arreglo y
almacenar la suma en la variable total, suma 1+2+3…. + 10 que da como resultado 55. En
esta línea utilizamos a.Length que es el tamaño del arreglo a que es 10, el ciclo for empieza
en 0 y termina en 9.

Para usar números aleatorios en C# podemos utilizar la clase Random del namespace System,
de la siguiente manera línea 20: Random objeto = new Random(); El método Next de la
clase Random genera y devuelve un número aleatorio entre 0 y la constante Int32.MaxValue
(2,147,483,647). El número es generado utilizando una semilla (seed) que por default es la
hora del sistema. En la línea 23 {b[i]=objeto.Next(1,99); asignamos a cada elemento del
arreglo un valor generado aleatoriamente entre 1 y 99, por lo que en cada ejecución los
elementos serán diferentes, el ciclo for de la línea 22 también nos sirve para imprimir cada
elemento del arreglo b.

3.17 Capítulo 3: Métodos, Arreglos y Estructuras


Ejecución:

3.18 Capítulo 3: Métodos, Arreglos y Estructuras


En el ejemplo Histograma.cs utilizamos un arreglo llamado x de 10 elementos y por cada
valor imprimimos n asteriscos por ejemplo en el primer valor del arreglo se imprimen 17
asteriscos, en el segundo 4 asteriscos, y así sucesivamente, lo realizamos con la ayuda dos
ciclos for el primero imprime el número de elemento y su valor, y el segundo ciclo for o el más
anidado imprime el número de asteriscos adecuado, nótese que también utilizamos el
parámetro x.Length para determinar el número de elementos, la ventaja de utilizarlo de esta
manera es que si aumentan o disminuyen los elementos este parámetro no es necesario
actualizarlo o cambiarlo.

Ejecución:

3.19 Capítulo 3: Métodos, Arreglos y Estructuras


En el programa Ordenar.cs mostramos el método Array.Sort para ordenar los elementos de
un arreglo, una vez ordenados se imprimen los elementos del arreglo para comprobar que
están ordenados. Después de cerrar la llave de la clase Ordenar línea 17, entre comentarios
aparece la instrucción foreach línea 19 esta puede ser utilizada en lugar del ciclo for y el
resultado será el mismo, más adelante se muestra un ejemplo completo de su uso.

Ejecución:

En el programa MetodosArray.cs mostramos básicamente los principales métodos de la


clase System.Array.
En la línea 14 Array.Copy(a,b,a.Length); copiamos el contenido del arreglo a en el arreglo
b el cual está vacío, en la líneas 15 y 16 imprimimos cada valor del arreglo b para comprobar
que efectivamente los elementos del arreglo a fueron copiados al arreglo b.

En la línea 19 Array.Reverse(a); invertimos los elementos del arreglo a, en la línea 20


copiamos el arreglo a invertido en el arreglo c e imprimimos los valores para comprobar el
resultado.

En las líneas 24 con la instrucción Array.IndexOf(c,5); buscamos la primera posición o


índice del valor 5 dentro del arreglo con Array.LastIndexOf(c,5); obtenemos la última
posición.

3.20 Capítulo 3: Métodos, Arreglos y Estructuras


Con la instrucción a.Rank en la línea 31 determinamos la dimensión del arreglo que es uno
por ser unidimensional. En la línea 32 la instrucción a.IsFixedSize determina si el arreglo es
de tamaño fijo, que en este caso es true o verdadero.

Finalmente en la línea 35 Array.Clear(a,2,5); a partir del elemento 2 coloca 5 elementos


en cero.

3.21 Capítulo 3: Métodos, Arreglos y Estructuras


En el programa Estadisticas1.cs, creamos e inicializamos un arreglo llamado a el cual
contiene las calificaciones de un grupo de alumnos, el objetivo es determinar la frecuencia o
cuantas veces aparece cada calificación dentro del arreglo. Creamos un arreglo llamado
frecuencia con 11 elementos, en la línea 19 con la instrucción
++frecuencia[calificaciones[j]]; almacenos en el arreglo frecuencia cuantas veces
aparece cada calificación, en la línea 25 imprimimos el resultado.

3.22 Capítulo 3: Métodos, Arreglos y Estructuras


El programa Estadistica2.cs es similar al programa Estadistica1.cs, agregamos la función
calificaciones.Length en la línea 33 para determinar el número total de estudiantes, de la
línea 43 a 51 creamos un método llamado máximo para determinar dentro del arreglo
frecuencia cual calificación se repite más vemos que la función regresa el valor del índice
así en la línea 36 imprimimos cual calificación se repite mas que es el 7 y en la línea 37
frecuencia[indice] imprimimos cuantas veces se repite que son 10 veces.

3.23 Capítulo 3: Métodos, Arreglos y Estructuras


3.24 Capítulo 3: Métodos, Arreglos y Estructuras
Ejecución:

El programa Estadistica3.cs es muy similar al 2 simplemente movimos la función máximo a


la parte de arriba de la clase líneas 8 a 15, y en la función máximo en lugar de regresar el
índice regresamos el valor que en este caso es max línea 14, con
Array.IndexOf(frecuencia,maximo(frecuencia))) línea 43 determinamos la calificación
que se repite más y para determinar cuanta veces se repite utilizamos maximo(frecuencia)
línea 44. La ejecución del programa es exactamente igual a la del programa
Estadistica2.cs.

3.25 Capítulo 3: Métodos, Arreglos y Estructuras


3.26 Capítulo 3: Métodos, Arreglos y Estructuras
Foreach

La instrucción foreach repite un grupo de instrucciones incluidas en el bucle o ciclo para cada
elemento de una matriz o de un objeto collection. La instrucción foreach se utiliza para
recorrer en iteración una colección de elementos y obtener la información deseada, pero no se
debe utilizar para cambiar el contenido de la colección, ya que se pueden producir efectos
secundarios imprevisibles. Las instrucciones del bucle o ciclo siguen ejecutándose para cada
elemento de la matriz o la colección. Cuando ya se han recorrido todos los elementos de la
colección, el control se transfiere a la siguiente instrucción fuera del bloque foreach.

En cualquier punto dentro del bloque foreach, puede salir del ciclo utilizando la palabra clave
break o pasando directamente la iteración siguiente del ciclo mediante la palabra clave
continue. También se puede salir de un bucle foreach mediante las instrucciones goto,
return, throw.

En el programa Foreach1.cs creamos un arreglo unidimensional con cuatro elementos


llamado calificaciones, en la línea 18 con un ciclo for imprimimos el arreglo utilizando
GetLowerBound(0) que obtiene el índice del primer elemento del arreglo y
GetUpperBound(0) nos proporciona el índice del último elemento del arreglo, el cero
representa la dimensión del arreglo como es unidimensional se utiliza el cero, en la línea 22
imprimimos el arreglo utilizando foreach, establecemos una variable entera int k para
recorrer los elementos del arreglo y definimos cuál arreglo in calificaciones.

3.27 Capítulo 3: Métodos, Arreglos y Estructuras


Ejecución:

3.28 Capítulo 3: Métodos, Arreglos y Estructuras


Arreglos bidimensionales.

Un arreglo bidimensional tiene dos dimensiones, en C# las dimensiones se manejan por medio
de un par de corchetes, dentro de los que se escriben, separados por comas, los valores de las
dos dimensiones.

La declaración de un arreglo consiste en establecer las características del arreglo y sus


elementos, por medio de la siguiente sintaxis:
<tipo> [ , ] < identificador > ;

Donde:
tipo indica el tipo correspondiente a los elementos del arreglo ,
identificador es el nombre del arreglo, y
el par de corchetes y la coma, [ , ], representan las dimensiones del arreglo y encierra dos
números enteros, cuyo producto corresponde al número de elementos del arreglo.

Ejemplos:
int [ , ] matriz ;
double [ , ] posicion ;
Chasis [ , ] automovil; // Chasis es una clase.

Observe que, en la declaración, el espacio entre los corchetes está vacío. Esto se debe a que,
durante dicha operación, no se reserva espacio en la memoria.

La creación de un arreglo bidimensional consiste en reservar espacio en la memoria para


todos sus elementos, utilizando la siguiente sintaxis:

< identificador > = new <tipo> [ dim1, dim2 ] ;

Donde:

new es el operador para gestionar espacio de memoria, en tiempo de ejecución,

dim1 y dim2 son valores enteros que representan las dimensiones del arreglo.

El tamaño del arreglo es el resultado de multiplicar los valores de las dimensiones y representa
el número de elementos del arreglo.

Ejemplos:

matriz = new int [2, 3] ; // Se crea el arreglo matriz, con 6 elementos de tipo entero
posicion = new double[4,2] ; // Se crea el arreglo posicion, con 8 elementos tipo doble
automovil= new Chasis[5,2] ; // Se crea el arreglo , Chasis con 10 objetos de la clase
automóvil.

3.29 Capítulo 3: Métodos, Arreglos y Estructuras


Las operaciones de declaración y creación anteriores se pueden agrupar en una sola
instrucción, como se muestra enseguida:
int [ , ] matriz = new int [2,3] ;
double [ , ]posicion = new double[4, 2] ;
Chasis [ , ] automovil = new Chasis[5,2] ;

Inicialización.
Un arreglo es un objeto que, cuando es creado por el compilador, se le asignan
automáticamente valores iniciales predeterminados a cada uno de sus elementos, de acuerdo a
los siguientes criterios:

Si el tipo del arreglo es numérico, a sus elementos se les asigna el valor cero.
Si el tipo del arreglo es char, a sus elementos se les asigna el valor '\u0000'.
Si el tipo del arreglo es bool, a sus elementos se les asigna el valor false.
Si el tipo del arreglo es una clase, a sus elementos se les asigna el valor null.

Cuando se requiere asignar valores iniciales diferentes de los predeterminados, es posible


agrupar las operaciones de declaración, creación e inicialización en una sola instrucción, por
ejemplo:

int [ , ] matriz = { {1,5, 2 } , {3, 9, 4} };


double [,] posicion = { {5.2, 6.0} , {7.6, 9.2} , {3.7, 10.1}, {5.4 , 1.8}};
string [ , ]RFC ={{"VAPA760912D55", "CBCD880101B89"} , { "CGTI992012",
"MESL700719"}};

Acceso.
Se puede acceder a los valores de los elementos de un arreglo bidimensional a través del
nombre del arreglo y dos subíndices. Los subíndices deben escribirse entre corchetes y
representa la posición del elemento en el arreglo. Así, podemos referirnos a un elemento del
arreglo escribiendo el nombre del arreglo y los subíndices del elemento entre corchetes. Los
valores de los subíndices empiezan en cero para el primer elemento, hasta el tamaño del
arreglo menos uno.

Ejemplo:
double [ , ] posicion = new double[4,3] ;
// Crea el arreglo posicion, con 12 elementos de tipo double
posicion[ 2, 1] = 9.8 ;
double p = posición[ 2, 1] ;
// Asigna a la variable p el valor de 9.8, el mismo valor del arreglo en la
posición [2, 1]

En el siguiente ejemplo Matriz1.cs creamos un arreglo del 6 elementos del tipo string es
decir podemos almacenar en este cadenas de texto, consta de 3 filas y 2 columnas, con un
ciclo for anidado capturamos el nombre de 6 materias que deseamos inscribir en un
semestre, posteriormente con otro ciclo for anidado imprimimos los valores almacenados.
3.30 Capítulo 3: Métodos, Arreglos y Estructuras
Ejecución:

En el ejemplo Matriz2.cs declaramos un arreglo de 4 filas, 3 columnas con un total de 12


elementos de tipo entero, a diferencia del anterior en este arreglo se declaran e inicializa al
mismo tiempo cada elemento, esto se efectúa en la línea 14, posteriormente con el ciclo for
anidado imprimimos el valor de cada elementos así como la posición que le corresponde.

3.31 Capítulo 3: Métodos, Arreglos y Estructuras


En el programa Matriz3.cs declaramos tres matrices de tipo entero, ambas con el mismo
número de filas y de columnas que se piden previamente. En las dos primeras matrices
almacenamos los valores que deseamos y en la tercera matriz almacenamos el resultado de la
suma de las dos primeras matrices. Al final solo imprimimos el valor de la matriz resultante.
Observemos que utilizamos tres ciclos for anidados en todo el programa, los dos primeros
para leer los valores de las dos primeras matrices y el tercer ciclo for anidado suma las
matrices A y B elemento por elemento y al mismo tiempo imprime el resultado.

3.32 Capítulo 3: Métodos, Arreglos y Estructuras


3.33 Capítulo 3: Métodos, Arreglos y Estructuras
Ejecución:

Estructuras
Una estructura es muy similar a una clase la cual puede contener campos, propiedades y
métodos, de hecho una estructura es un tipo especial de clase pensada para representar
objetos ligeros. Es decir, que ocupen poca memoria y deban ser manipulados con velocidad,
como objetos que representen puntos, fechas, etc. Ejemplos de estructuras son la mayoría de
los tipos básicos (excepto string y object).

Listamos las cosas habituales en las clases que no se pueden hacer con las estructuras:

Puede escribir constructores, pero estos han de tener argumentos. Dicho de otro modo, no se
puede escribir un constructor sin argumentos para una estructura.

Lógicamente, al tratarse de un tipo valor que se almacena en la pila, las estructuras no admiten
destructores.

No soportan herencia, lo cual implica que no pueden ser utilizadas como clases base ni como
clases derivadas. No obstante, sí pueden implementar interfaces, y lo hacen igual que las
clases.

Los campos de una estructura no pueden ser inicializados en la declaración. O sea, por
ejemplo, no se vale decir int a=10; porque tendríamos un error de compilación.

3.34 Capítulo 3: Métodos, Arreglos y Estructuras


Las estructuras, si no se especifican los modificadores ref o out, se pasan por valor, mientras
que las clases se pasan siempre por referencia. No es necesario instanciar una estructura para
poder usar sus miembros.

En el siguiente programa Estructura1.cs declaramos una estructura de tipo entero en el cual


definimos la propiedad Valor para establecer los valores, dentro del código set hacemos
referencia al valor que se solicita, asignando a través de un parámetro especial del mismo tipo
de dato que la propiedad llamado value, posteriormente con el método Leer se utiliza para
Leer el dato. En el Main() creamos un objeto de tipo Natural que viene siendo una estructura
línea 25, en la línea 28 accedemos a la propiedad de la estructura y en la línea 30 llamamos al
método de la estructura para leer un valor, por último en la línea 32 imprimimos el valor leído.

3.35 Capítulo 3: Métodos, Arreglos y Estructuras


Ejecución:

En el programa Estructura2.cs creamos una estructura llamada Real para establecer y leer
los valores de un número real, posteriormente creamos otra estructura llamada Rectangulo
con dos propiedades para establecer el ancho y alto, y un método llamado CrearRectangulo
para leer los valores. En el Main() línea 49 creamos una variable del tipo Rectángulo, que en
realidad es una estructura, la palabra var puede ser reemplazado por Rectángulo, en las
líneas 55 a 60 accedemos a las características del rectángulo y calculamos el área y perímetro.

C# 3.0 ofrece inferencia de tipos que es una magnifica característica de cualquier Lenguaje.
Conserva la seguridad del tipo, mientras nos permite escribir un código más "relajado". En otras
palabras, podemos definir variables y utilizarlas sin preocuparnos demasiado acerca de los
tipos, dejando que el compilador determine el tipo correcto de una variable por inferencia a
partir de la expresión de asignación a la variable misma. Nos permite definir una variable
mediante el uso de la palabra reservada var en lugar de un tipo específico. Cuando se utiliza
var, el compilador infiere el tipo de la expresión utilizada para inicializar las variables. El código
generado por el compilador contiene tipo inferido.

3.36 Capítulo 3: Métodos, Arreglos y Estructuras


3.37 Capítulo 3: Métodos, Arreglos y Estructuras
Ejecución:

3.38 Capítulo 3: Métodos, Arreglos y Estructuras


En el programa Estructura3.cs establece una estructura llamada Localizacion y un método
llamado MiFunc esta se encuentra en la clase Principal, en la estructura sobre escribimos el
método ToString() para imprimir dos valores, en el Main() creamos dos objeto uno del tipo
estructura el cual llamamos dos veces y otro del tipo Myfunc el cual se llama una sola vez entre
los dos anteriores para comparar como se imprimen ambos valores.

3.39 Capítulo 3: Métodos, Arreglos y Estructuras


Capítulo 4

Programación Orientada a Objetos


La belleza de los objetos reside en la mente de quien los contempla.

Cuando cambiamos interiormente, debemos cambiar también los objetos que nos rodean

Tabla de Contenido
Conceptos de clase y objeto .............................................................................................................................. 4.2
Sintaxis de definición de clases ....................................................................................................................... 4.2
Visibilidad de una clase y sus miembros. ................................................................................................... 4.4
Constructores ......................................................................................................................................................... 4.4
Llamada al Constructor. ..................................................................................................................................... 4.5
Clase base, derivada y herencia ...................................................................................................................... 4.8
Polimorfismo ....................................................................................................................................................... 4.13
Enlace estático y enlace dinámico. ............................................................................................................. 4.13
Clases Abstractas ............................................................................................................................................... 4.14
Destructor. ............................................................................................................................................................ 4.17
Encapsulación. .................................................................................................................................................... 4.18
Concepto de propiedad ................................................................................................................................... 4.24

4.1 Capítulo 4: Programación Orientada a Objetos


Conceptos de clase y objeto

C# es un lenguaje orientado a objetos puro, lo que significa que todo con lo que vamos
a trabajar en este lenguaje son objetos. Un objeto es un agregado de datos y de
métodos que permiten manipular dichos datos, y un programa en C# no es más que un
conjunto de objetos que interaccionan unos con otros a través de sus métodos.

Una clase es la definición de las características concretas de un determinado tipo de


objetos. Es decir, de cuáles son los datos y los métodos de los que van a disponer
todos los objetos de ese tipo. Por esta razón, se suele decir que el tipo de dato de un
objeto es la clase que define las características del mismo.

Para definir una clase usamos la palabra clave class, después de esta pondremos el
nombre o identificador de la clase. Abrimos una llave y listamos los miembros de la
clase en la líneas siguientes, hasta finalizar la definición con la llave de cierre.

Las clases se usan para modelar las aplicaciones como si estuvieran compuestas de
objetos más o menos discretos. Al interior de una clase es posible definir otras.

De manera implícita, a menos que indiquemos lo contrario, toda ciase está derivada del
tipo object que es la base de todos los tipos de datos de C#. Éste cuenta con una serie
de miembros que, por tanto, son heredados por todas las ciases que podamos definir.
Si nuestra clase está derivada de otra, heredará, asimismo, todos los miembros de su
clase base y los de la clase base de la base, ascendiendo en la jerarquía hasta llegar a
object.

Tanto la clase como sus miembros pueden contar con múltiples modificadores, los
cuales se listan en la sección: Visibilidad de una clase y sus miembros.

Sintaxis de definición de clases

Para crear una nueva clase primero debemos declararla y definir sus campos y
métodos, para crear una clase usamos la palabra clave class, la sintaxis completa es:

[atributos] [modificadores de acceso] class identificador [:[clase-base


[,interface(s)]]
{cuerpo de la clase}

Esta es la definición formal, pero todo lo que esta entre corchetes es opcional es decir
puedo o no escribirse dependiendo de las necesidades de nuestra clase, por lo tanto
una clase esta definida por un atributo que es opcional, seguida de un modificador de
acceso que es también opcional, y la palabra clave class que no es opcional debe ir
siempre, seguido del identificador que también es obligatorio, opcionalmente despúes

4.2 Capítulo 4: Programación Orientada a Objetos


del identificador se puede agregar la clase base y la interface. Si colocamos una clase
base o una interface deben de ir seraradas por una coma. Después de todo esto
abrimos una llave para definir el cuerpo de la clase y cerramos con una llave para
terminar de definir a la clase.

Para no confundirnos citamos un ejemplo simple:


public class Perro : Mamifero
{
// Cuerpo de la clase se define aquí
}

El programa Clase1.cs mostramos la creación de una clase llamada Hola y dentro de


esta un método llamado Saludo(), tambien existe la clase principal donde se encuentra
el Main(), aquí creamos un objeto de la clase Hola línea 27 y en la línea 28 invocamos
al método Saludo().

Ejecución:

4.3 Capítulo 4: Programación Orientada a Objetos


Visibilidad de una clase y sus miembros.
Las clases, como acaba de decirse, pueden estar incluidas en un ámbito con nombre o
en otras clases. Su visibilidad, fuera de ese ámbito, dependerá de los modificadores que
dispongamos delante de la palabra class en el momento de la definición. Estos
modificadores pueden también aplicarse a los miembros de la clase: métodos,
propiedades, variables, etc. Las posibilidades son las siguientes:

• public - La clase, o el miembro, es visible en todos los ámbitos, no sólo en el que se


ha definido. Las clases públicas, por ejemplo, pueden usarse desde ámbitos con
nombre externos al propio. Los miembros públicos de una clase son accesibles, al crear
un objeto, desde fuera de la propia clase.

• protected - Este modificador sólo es aplicable a los miembros de una ciase, no a la


clase en sí. La visibilidad está reducida a la propia clase y las que pudieran derivarse de
ella. Es decir, un miembro protegido no es accesible externamente.

• private - Es el ámbito más reducido. Una clase privada sólo puede utilizarse en el
interior del ámbito en que se encuentra incluida, ya sea un namespace u otra clase. Los
miembros que tienen este modificador, igualmente, sólo pueden ser usados desde el
interior de la clase donde se han definido, nunca desde fuera, ni siquiera en clases
derivadas.

• internal - Es similar a public. Si bien la clase o el miembro es visible desde fuera de su


ámbito inmediato, esta regla solamente se aplica dentro del ensamblado al que
pertenece. Una clase public puede usarse desde otros ensamblados, mientras que una
internal no.

• protected internal - Como puede suponer, es una combinación de protected e


internal. El resultado es que los identificadores pueden utilizarse en el ensamblado en
que se han definido, así como en clases derivadas a pesar de que se encuentren en
otros ensamblados.

La visibilidad de las clases y sus miembros es algo que debe deducirse directamente
del diseño lógico de la propia aplicación. Normalmente ésta constará de una serie de
clases públicas a partir de las cuales se crearán los objetos fundamentales, exponiendo
métodos y propiedades que permitan a las aplicaciones configurar su funcionamiento.
Internamente, estas clases pueden utilizar otras no visibles desde el exterior, así como
miembros privados y protegidos.

Constructores
Para crear un objeto se necesita reservar suficiente espacio en memoria e inicializar los
valores de los campos que representan el estado del objeto.

Este trabajo es realizado por un tipo especial de metodo denominado constructor. Un


método constructor de una clase es un método especial que: tiene el mismo nombre
que la clase y no tiene tipo de retorno.

4.4 Capítulo 4: Programación Orientada a Objetos


La sintaxis para la declaración de un método constructor es:

[atributos] [modificadores] <identificador> ( [parámetros] )


[inicializador]
{ // Cuerpo del constructor }

Donde:

atributos (opcional) es información declarativa adicional.


modificadores (opcional) se restringen a extern y a los modificadores de acceso.
identificador es el nombre del método constructor (igual al nombre de la clase).
parámetros (opcional) es la lista de parámetros pasados al constructor.
inicializador (opcional). Con el inicializador, el constructor invoca previamente a otro
constructor.

El inicializador puede ser uno de los siguientes:


base([listaDeParámetros])
this([listaDeParámetros])
Cuerpo del constructor es el bloque de programa que contiene las instrucciones para
inicializar la instancia de clase (objeto).

Es importante mencionar que los constructores no se heredan

Llamada al Constructor.
Al constructor de una clase se le llama en el momento en que se crea algún objeto de la
misma usando el operador new. De hecho, la forma de uso de este operador es:
new <llamadaConstructor>

El programa Constructor1.cs es un ejemplo simple que muestra la creación e


invocación de un constructor.

Ejecución:

4.5 Capítulo 4: Programación Orientada a Objetos


El programa Constructor2.cs tiene una clase llamada Ejemplo1 junto con su
constructor, pero la clase también cuenta con un método llamado datos().

4.6 Capítulo 4: Programación Orientada a Objetos


El programa Constructor3.cs tiene una clase llamada Prueba con dos constructores
el primero por default sin argumentos y el segundo constructor con un argumento de
tipo entero.

4.7 Capítulo 4: Programación Orientada a Objetos


Clase base, derivada y herencia
Uno de los mecanismos más interesantes de los lenguajes orientados a objetos,
categoría en la que cae C#, es el de herencia. Gracias a él, es posible definir una nueva
clase partiendo de otra existente, de tal forma que la derivada hereda de la base todos
sus miembros, lo cual implica contar, ya de partida, con la misma funcionalidad. La
clase derivada puede acceder a todos los miembros de la base exceptuando aquellos
que son privados.

En un sistema orientado a objetos, la herencia es la capacidad de un objeto de heredar


datos y funcionalidad de su objeto padre. De esta forma, el objeto padre puede ser
sustituido por un objeto hijo. La herencia también permite crear nuevas clases a partir
de otras ya existentes, en lugar de crearlas partiendo de cero, y añadir luego el código
que sea necesario para la nueva clase. La clase padre en la que está basada la nueva
clase se llama clase base, mientras que la clase hija se conoce como clase derivada.
Cuando se crea una clase derivada hay que tener en cuenta que puede sustituir al tipo
de clase base. Esto significa que la herencia no sólo es un mecanismo para la
reutilización de código, sino también un mecanismo de clasificación de tipos. Este último
aspecto es más importante que el primero.

Mediante el mecanismo de herencia se contribuye a la reutilización del código, algo


habitual en todos los lenguajes orientados a objetos. La novedad, en C#, es que dicho
código no tiene por qué estar escrito en el mismo lenguaje. Desde C# podemos derivar
una nueva clase tomando como base otra escrita en Visual Basic .NET, J#, C++ o
COBOL, por poner algunos ejemplos. Como se dijo anteriormente, todas las clases
derivan por defecto de object. Si deseamos otra base distinta tendremos que indicarla
tras el nombre de la que está definiéndose y dos puntos, como puede verse en el
ejemplo mostrado a continuación.

Las clases que derivan de otras se definen usando la siguiente sintaxis:

class <nombreHija>:<nombrePadre>
{
<miembrosHija>
}

A los miembros definidos en <miembrosHijas> se le añadirán los que hubiésemos


definido en la clase padre. Por ejemplo, a partir de la clase Persona puede crearse una
clase Trabajador así:

class Trabajador:Persona
{
public int Sueldo;
public Trabajador(string nombre, int edad, string curp, int sueldo)
: base(nombre, edad, curp)
{
Sueldo = sueldo;
}
}

4.8 Capítulo 4: Programación Orientada a Objetos


Los objetos de esta clase Trabajador contarán con los mismos miembros que los
objetos Persona y además incorporarán un nuevo campo llamado Sueldo que
almacenará el dinero que cada trabajador gane. Nótese además que a la hora de
escribir el constructor de esta clase ha sido necesario escribirlo con una sintaxis
especial consistente en preceder la llave de apertura del cuerpo del método de una
estructura de la forma:

: base(<parametrosBase>)

A esta estructura se le llama inicializador base y se utiliza para indicar cómo deseamos
inicializar los campos heredados de la clase padre. No es más que una llamada al
constructor de la misma con los parámetros adecuados, y si no se incluye el compilador
consideraría por defecto que vale :base(), lo que sería incorrecto en este ejemplo
debido a que Persona carece de constructor sin parámetros.

public class A
{
public A() { }
}

public class B : A
{
public B() { }
}

Un ejemplo que pone de manifiesto cómo funciona la herencia es el siguiente:

4.9 Capítulo 4: Programación Orientada a Objetos


Ejecución:

4.10 Capítulo 4: Programación Orientada a Objetos


Otro ejemplo:
// Esta clase tiene como base a Object
public class ClaseBase
{
// cuenta con un método que devuelve una cadena
public string Saludo()
{
return "UACM POO";
}
}

// Esta clase está derivada de la anterior


public class ClaseDerivada : ClaseBase
{
// y añade un método para elevar al cubo un número
public int Cubo(int z)
{
return z*z*z;
}
}

La clase ClaseDerivada hereda los métodos de ClaseBase y también los de object,


que es la ascendiente de ClaseBase. Disponiendo el código anterior en un módulo de
un proyecto de consola, podríamos añadir el fragmento siguiente para crear un objeto
de la clase ClaseDerivada e invocar a los métodos Cubo() y Saludo()
.

public class Principal


{
static void Main(string[] args)
{
// Creamos un objeto de la clase derivada
ClaseDerivada MiClase = new ClaseDerivada();
// e invocamos a los dos métodos
Console.WriteLine("{0},{1}",MiClase.Saludo(), MiClase.Cubo(4));
Console.ReadLine();
}
}

El programa completo sería:

4.11 Capítulo 4: Programación Orientada a Objetos


Ejecución:

En caso de que haya escrito una clase de la cual no le interese que se deriven otras,
por considerarla una clase de uso final, tenemos que anteponer la palabra sealed antes
de class. Para probar si la utilizamos en la clase ClaseBase veremos como no se
puede compilar el programa obteniendo un mensaje de error, esa clase, por lo tanto,
solo podría utilizarse para crear objetos, pero nunca para derivar otras partiendo de ella.

public sealed class ClaseBase

4.12 Capítulo 4: Programación Orientada a Objetos


También podemos encontrarnos justamente en el caso contrario: haber definido una
clase cuyo objetivo es servir de base para otras. La clase puede no tener funcionalidad
propia, sirviendo simplemente como raíz común de clases que compartirían algunos
miembros. Suponga que va a definir una serie de clases que representarán entidades
gráficas y, para facilitar el trabajo, quiere que todas esas clases compartan una serie de
miembros comunes. Definir una raíz común tendrá diversas ventajas. En la siguiente
sección se definen las clases abstractas.

Polimorfismo

La palabra polimorfismo tiene su origen en las palabras griegas poli ( muchos ) y morfos
( formas ) y se utiliza para indicar que un mismo mensaje enviado a diferentes objetos
producirá muchas formas de respuesta.

Por ejemplo, si tenemos la clase base Figura y de ella derivan las clases Rectángulo y
Elipse. Suponiendo que las tres tienen declarado el método Area( ), entonces
podemos tener objetos de las clases derivadas ( Rectángulo y Elipse) referenciados
como si fueran de la clase base (Figura) y después enviarles mensajes para que
devuelvan su área.

El polimorfismo puede considerarse como la característica más potente de los lenguajes


orientados a objetos , después de su capacidad para soportar la abstracción.

El polimorfismo no sólo es importante para las clases derivadas, sino también para las
clases base. Cualquiera que utilice la clase base podría, de hecho, estar utilizando un
objeto de la clase derivada que se haya convertido en el tipo de clase base. Los
diseñadores de una clase base pueden anticipar qué aspectos de su clase base
cambiarán probablemente para un tipo derivado. Por ejemplo, es posible que una clase
base para automóviles contenga un comportamiento sujeto a cambios si el automóvil en
cuestión es un vehículo familiar o uno descapotable. Una clase base puede marcar esos
miembros de clase como virtuales, lo cual permite que las clases derivadas que
representan automóviles descapotables y vehículos familiares reemplacen ese
comportamiento.

Existe polimorfismo cuando interactúan las características de herencia y enlace


dinámico .

Enlace estático y enlace dinámico.


El enlace estatico ( denominado también enlace temprano ) consiste en la asignación
estática de tipos a todas las variables y expresiones en tiempo de compilación.

El enlace dinámico ( denominado también enlace tardío ) consiste en asignar los tipos a
las variables y expresiones en tiempo de ejecución.

4.13 Capítulo 4: Programación Orientada a Objetos


Clases Abstractas

Son clases de las que no es posible crear instancias; frecuentemente, están


implementadas sólo parcialmente o no están implementadas. Una clase abstracta es
aquella que forzosamente se ha de derivar si se desea que se puedan crear objetos de
la misma o acceder a sus miembros estáticos.

Cuando pensamos en una clase como un tipo, asumimos que los programas crearán
objetos de ese tipo. Sin embargo, hay casos en que es útil definir clases para las cuales
no se desea instanciar objetos. Tales clases son llamadas clases abstractas. Debido a
que normalmente son utilizadas como base en jerarquías de clases, nos referiremos a
ellas como clases base abstractas. Las clases abstractas no sirven para instanciar
objetos porque están incompletas, siendo sus clases derivadas las que deberán definir
las partes faltantes.

El propósito de una clase abstracta es proveer una clase base apropiada desde la cual
otras clases hereden.

Las clases desde las cuales se pueden instanciar objetos se llaman clases concretas.
Tales clases proveen implementaciones de cada método o propiedad que definen.

Las clases abstractas normalmente contienen uno o más métodos o propiedades


abstractas, las cuales no proveen implementación. Las clases derivadas deben
reemplazar los métodos abstractos heredados para permitir la instanciación de objetos.

Para definir una clase abstracta se utiliza la palabra clave abstract (que también sirve
para definir métodos y propiedades abstractos).

A continuación se lista un ejemplo de una clase abstracta con métodos abstractos:

El código del programa ClaseAbstracta1.cs la primera línea using


C=System.Console; Definimos a C como System.Console, por lo tanto para imprimir o
leer solo es necesario escribir C.WriteLine ó C. C.ReadLine.

El modificador override es necesario para ampliar o modificar la implementación


abstract o virtual de un método, propiedad, indizador o evento heredado. El método
override proporciona una nueva implementación de un miembro heredado de una
clase base. El método reemplazado por una declaración override se conoce como
método base reemplazado

4.14 Capítulo 4: Programación Orientada a Objetos


Ejecución:

El programa Polimorfismo1.cs tiene varios metodos Saluda() dependiendo del tipo


de mamifero del que se trate sera el saludo.

4.15 Capítulo 4: Programación Orientada a Objetos


Ejecución:

En este ejemplo se observa que es posible asignar referencias de clases derivadas


(Humano, Vaca, Perro) a referencias de clases base (Mamífero). Así, es válido escribir:
Mamifero m = new Humano( ) ;

Sin embargo, no se puede asignar una referencia de una clase base a una referencia de
una clase derivada, por lo que es erróneo escribir: Humano h = new Mamífero( ); en
primer lugar, porque Mamífero es la clase base y Humano es una clase derivada y, en
segundo lugar, porque Mamífero es una clase abstracta.

4.16 Capítulo 4: Programación Orientada a Objetos


Destructor.
En general, C# no requiere tanta administración de memoria como se necesita al
desarrollar con un lenguaje que no está diseñado para un motor en tiempo de ejecución
con recolección de elementos no utilizados. Esto es debido a que el recolector de
elementos no utilizados de .NET Framework administra implícitamente la asignación y
liberación de memoria para los objetos. Sin embargo, cuando la aplicación encapsule
recursos no administrados como ventanas, archivos y conexiones de red, debería
utilizar destructores para liberar dichos recursos. Cuando el objeto se marca para su
destrucción, el recolector de elementos no utilizados ejecuta el método Finalize.

La sintaxis para declarar un destructor es:

[atributos] ~ <identificador> ( )
{// Cuerpo del destructor }

Consideraciones:

 Una clase solamente puede tener un destructor.


 Los destructores no pueden heredarse o sobrecargarse.
 Los destructores no pueden invocarse, sino que son invocados
automáticamente.
 Un destructor no acepta modificadores ni parámetros. Por ejemplo, la siguiente
es una declaración de un destructor para la clase Carro

~ Carro()
{ // Instrucciones para limpiar}

El destructor llama implícitamente al método Finalize en la case base del objeto. Por
lo tanto, el código de destructor anterior se traduce implícitamente a:

protected override void Finalize()


{
try
{
// cleanup statements...
}
finally
{
base.Finalize();
}
}

En el siguiente ejemplo DestructoresHerencia.cs se crean tres clases que forman


una cadena de herencia. La clase Primero es la clase base, Segundo se deriva de
Primero y Tercero se deriva de Segundo. Las tres tienen destructores. En Main(), se
crea una instancia de la clase más derivada. Cuando ejecute el programa, observe que
se llama a los destructores de las tres clases automáticamente y en orden, desde la
más derivada hasta la menos derivada.

4.17 Capítulo 4: Programación Orientada a Objetos


Ejecución:

Encapsulación.

La encapsulación es un mecanismo que nos permite determinar qué miembros de los


tipos de datos pueden ser utilizados por otros programadores y cuáles no. Las
principales ventajas que ello aporta son:

Se facilita a los programadores que vaya a usar el tipo de dato (programadores clientes)
el aprendizaje de cómo trabajar con él, pues se le pueden ocultar todos los detalles
relativos a su implementación interna y sólo dejarle visibles aquellos que puedan usar
con seguridad. Además, así se les evita que cometan errores por manipular
inadecuadamente miembros que no deberían tocar.

4.18 Capítulo 4: Programación Orientada a Objetos


Cuando hablamos del cliente por ejemplo de una clase nos referimos al código que está
usando esa clase, es decir, instanciándola o invocando métodos de la misma,
independientemente de si este código forma parte del mismo programa o de otro
distinto, aun escrito en otro lenguaje.

Otra ventaja es que se facilita al creador del tipo la posterior modificación del mismo,
pues si los programadores clientes no pueden acceder a los miembros no visibles, sus
aplicaciones no se verán afectadas si éstos cambian o se eliminan. Gracias a esto es
posible crear inicialmente tipos de datos con un diseño sencillo aunque poco eficiente, y
si posteriormente es necesario modificarlos para aumentar su eficiencia, ello puede
hacerse sin afectar al código escrito en base a la no mejorada de tipo.

La encapsulación se consigue añadiendo modificadores de acceso en las


definiciones de miembros y tipos de datos. Estos modificadores nos sirven para
determinar el acceso al código, entendiéndose por acceder el hecho de usar su nombre
para cualquier cosa que no sea definirlo, como llamarlo si es una función, leer o escribir
su valor si es un atributo, crear objetos o heredar de él si es una clase, etc.

Por defecto se considera que los miembros de un tipo de dato sólo son accesibles
desde código situado dentro de la definición del mismo, aunque esto puede cambiarse
precediéndolos de uno los siguientes modificadores (estos ya se han explicado en el
tema Visibilidad de una clase y sus miembros, para recordar:

public: Puede ser accedido desde cualquier código, protected: Desde una clase sólo
puede accederse a miembros protected de objetos de esa misma clase o de subclases
suyas.

En resumen el encapsulamiento es la capacidad que tienen los objetos de ocultar su


código al cliente y proteger sus datos, ofreciendo única y exclusivamente una interfaz
que garantiza que el uso del objeto es el adecuado.

Analicemos el siguiente ejemplo Encapsulación1.cs:

4.19 Capítulo 4: Programación Orientada a Objetos


4.20 Capítulo 4: Programación Orientada a Objetos
Ejecución:

Veamos cómo se ha implementado la encapsulación en este código, en primero lugar


vemos que las variables que forman en estado de los objetos que serán instanciados a
partir de la clase están declarados como private. Esto significa que el cliente que use
este tipo de objeto no podrá acceder directamente a dichas variables.

Para acceder a las variables, es decir, a la información que está dentro de los objetos lo
realizamos mediante los métodos public que permitan acceder y modificar dichas
variables, esto es, el método nombre. Darse cuenta que hay dos métodos con el mismo
nombre y diferentes parámetros en la definición, esto es:

// Definición de métodos públicos (interfaz pública de la clase).


public void nombre(string nom1, string ape1, string ape2) {
nombre1 = nom1 ;
apellido1 = ape1 ;
apellido2 = ape2 ;
}

public string nombre() {


return nombre_completo() ;
}

Estos métodos conforman la interfaz pública que puede ser usada por el cliente. C#, y
en general cualquier lenguaje orientado a objetos debe de permitir la definición de
métodos con el mismo nombre y diferentes parámetros, ya que esta es la forma de
implementar otro pilar fundamental de la programación orientada a objetos, el
polimorfismo, que vimos anteriormente.

Hay otro método, declarado como private, que es un método de soporte, esto es, no
puede ser llamado por el cliente que use dicho método:

private string nombre_completo() {


return "Nombre: " + nombre1 + "\r\nPrimer apellido.: " + apellido1
+ "\r\nSegundo apellido.: " + apellido2 ;
}

En una cadena para ingresar un retorno de línea o enter debemos de ingresar: \r\n

El cliente es el código que se utiliza fuera de la clase, es decir, un objeto. Esto que
parece obvio tal vez no lo sea. Es decir, hay que tener muy claro que según está
diseñada la clase, nosotros solo podemos usar de ella el método "nombre" en sus dos
versiones, con parámetros y sin parámetros (en los objetos instanciados a partir de la
clase). En realidad son dos métodos, no olvidar esto.

4.21 Capítulo 4: Programación Orientada a Objetos


Recordemos Cuando una variable ó método va precedido de public se puede llamar
desde fuera de la clase a la que pertenece. Cuando es private la variable ó método
solo se puede llamar desde dentro de la clase, es decir, se puede usar en cualquier
lugar dentro de la definición de la clase, pero no se puede llamar externamente.

Evidentemente las variables de una clase se pueden definir como públicas, y se pueden
acceder directamente a ellas, pero no es recomendable si se quiere implementar el
concepto de encapsulación correctamente.

Veamos un segundo ejemplo de encapsulación Encapsulacion2.cs:

4.22 Capítulo 4: Programación Orientada a Objetos


Ejecución:

La ocultación del código es algo evidente: cuando se invoca el método Acelerar() del
objeto MiCoche, lo único que sabemos es que el coche acelerará, pero el cómo lo haga
es algo que no podremos ver desde el cliente. En cuanto a la protección de datos,
fijémonos también en un detalle del ejemplo: no podríamos modificar directamente el
valor de la propiedad Velocidad, dado que está definida como propiedad de sólo
lectura. La única forma de modificar su valor sería invocar los métodos Acelerar().
Esta importante característica asegura que los datos de los objetos pertenecientes a
esta clase se van a manejar del modo adecuado.

En el ejemplo esta parte de código define una propiedad:

public double Velocidad


{
get {return velocidad;}
}
Veamos en la siguiente sección en qué consiste.

4.23 Capítulo 4: Programación Orientada a Objetos


Concepto de propiedad

Una propiedad es una mezcla entre el concepto de atributo y el concepto de método.


Externamente es accedida como si de un atributo normal se tratase, pero internamente
es posible asociar código a ejecutar en cada asignación o lectura de su valor. Éste
código puede usarse para comprobar que no se asignen valores inválidos, para calcular
su valor sólo al solicitar su lectura, etc.

Una propiedad no almacena datos, sino sólo se utiliza como si los almacenase. En la
práctica lo que se suele hacer escribir como código a ejecutar cuando se le asigne un
valor, código que controle que ese valor sea correcto y que lo almacene en un atributo
privado si lo es; y como código a ejecutar cuando se lea su valor, código que devuelva
el valor almacenado en ese atributo público. Así se simula que se tiene un atributo
público sin los inconvenientes que estos presentan por no poderse controlar el acceso a
ellos.

Para definir una propiedad se usa la siguiente sintaxis:

< tipoPropiedad> <nombrePropiedad>


{
set
{
<códigoEscritura>
}

get
{
<códigoLectura>
}
}

Una propiedad así definida sería accedida como si de un atributo de tipo


<tipoPropiedad> se tratase, pero en cada lectura de su valor se ejecutaría el
<códigoLectura> y en cada escritura de un valor en ella se ejecutaría
<códigoEscritura>

Al escribir los bloques de código get y set hay que tener en cuenta que dentro del
código set se puede hacer referencia al valor que se solicita asignar a través de un
parámetro especial del mismo tipo de dato que la propiedad llamado value (luego
nosotros no podemos definir uno con ese nombre en <códigoEscritura>); y que
dentro del código get se ha de devolver siempre un objeto del tipo de dato de la
propiedad.

En realidad el orden en que aparezcan los bloques de código set y get es irrelevante.
Además, es posible definir propiedades que sólo tengan el bloque get (propiedades de
sólo lectura) o que sólo tengan el bloque set (propiedades de sólo escritura) Lo que no
es válido es definir propiedades que no incluyan ninguno de los dos bloques.

4.24 Capítulo 4: Programación Orientada a Objetos


Las propiedades participan del mecanismo de polimorfismo igual que los métodos,
siendo incluso posible definir propiedades cuyos bloques de código get o set sean
abstractos. Esto se haría prefijando el bloque apropiado con un modificador abstract y
sustituyendo la definición de su código por un punto y coma. Veamos el ejemplo
Propiedad1.cs

En este ejemplo se ve cómo se definen y redefinen propiedades abstractas. Al igual que


abstract y override, también es posible usar cualquiera de los modificadores
relativos a herencia y polimorfismo : virtual, new y sealed.

4.25 Capítulo 4: Programación Orientada a Objetos


Nótese que aunque en el ejemplo se ha optado por asociar un campo privado llamado
valor a la propiedad PropiedadEjemplo, en realidad nada obliga a que ello se haga y
es posible definir propiedades que no tenga campos asociados. Es decir, una propiedad
no se tiene porqué corresponder con un almacén de datos.

Veamos un último ejemplo Global1.cs que engloba las características principales de la


Programación Orientada a Objetos:

4.26 Capítulo 4: Programación Orientada a Objetos


El polimorfismo ofrece la posibilidad de que varios objetos que comparten la misma
interfaz, es decir, que están formados por los mismos miembros, se comporten de un
modo distinto unos de otro, no es necesario modificar el código de la clase original. Si
esta está bien diseñada, basta con derivar otra clase de la original y modificar el
comportamiento de los métodos necesarios, en este ejemplo el polimorfismo se utiliza
con el método Acelerar, la herencia se muestra en la creación de la clase class
AutomovilAvanzado:Automovil, y el encapsulamiento se da con los diferentes
niveles de acceso protected, private y public.

4.27 Capítulo 4: Programación Orientada a Objetos


Capítulo 5
Windows Forms
Uno de los principales objetivos de la educación debe ser ampliar las ventanas por las cuales vemos
al mundo

La caridad es un deber; la elección de la forma, un derecho.

Tabla de Contenido
Windows Forms .......................................................................................................................5.2
Creación de Proyectos .............................................................................................................5.4
El espacio de nombres System.Windows.Forms......................................................................5.6
Insertando controles dentro de la forma ...................................................................................5.7
Inserción de Código ...............................................................................................................5.10
Caja de Mensajes (MessageBox)...........................................................................................5.16
Caja de Selección ..................................................................................................................5.23
Visor de Imágenes y Enlaces .................................................................................................5.26
Web Browser y Creación de Menús .......................................................................................5.30
Formas que llaman a otras formas .........................................................................................5.33
Creación de Propiedades en una Clase .............................................................................5.36
Matrices en dataGridView...................................................................................................5.38
Creación de Menús ............................................................................................................5.40

5.1 Capítulo 5: Windows Forms


Windows Forms

Windows Forms es una de las dos tecnologías que se utiliza en Visual C# para crear
aplicaciones cliente inteligentes basadas en Windows que se ejecutan en .NET Framework.
Windows Forms es especialmente adecuado para escenarios de desarrollo rápido de
aplicaciones donde la prioridad principal no es una interfaz gráfica de usuario compleja. El
Diseñador de Windows Forms se utiliza para crear la interfaz de usuario, y permite obtener
acceso a otras características de diseño y ejecución, tales como las siguientes:

 Implementación ClickOnce.
 Uso avanzado de bases de datos mediante DataGridView (Control, formularios
Windows Forms).
 Barras de herramientas y otros elementos de interfaz de usuario que pueden tener el
aspecto y el comportamiento de Microsoft Windows XP, Microsoft Office o Microsoft
Internet Explorer.

En Visual C#, podemos utilizar el Diseñador de Windows Forms o el Diseñador de Windows


Presentation Foundation (WPF) para crear interfaces de usuario de forma rápida y cómoda.

Los tres pasos básicos para crear interfaces de usuario son:

1. Agregar los controles a la superficie de diseño.


2. Establecer las propiedades iniciales de los controles.
3. Escribir los controladores para los eventos especificados.

Agregar controles

En cualquiera de los diseñadores se utiliza el mouse para arrastrar controles, que son los
componentes con representación visual, como botones y cuadros de texto, hasta una superficie
de diseño

A medida que se trabaja visualmente, el Diseñador de Windows Forms traduce las acciones en
código fuente de C# y las escribe en un archivo de proyecto llamado nombre.designer.cs donde
nombre es el nombre asignado al formulario. De igual forma, WPF Designer traduce las
acciones de la superficie de diseño a código de lenguaje de marcado de aplicaciones
extensible (XAML) y lo escribe en un archivo de proyecto que se denomina Window.xaml.
Cuando se ejecuta la aplicación, ese código fuente (Windows Forms) o código XAML (WPF)
ajustará la posición y el tamaño de los elementos de la interfaz de usuario de modo que
aparezcan como en la superficie de diseño.

Establecer propiedades

Después de agregar un control a la superficie de diseño, podemos utilizar la ventana


Propiedades para establecer sus propiedades, como son el color de fondo y el texto
predeterminado.

5.2 Capítulo 5: Windows Forms


En el Diseñador de Windows Forms, los valores que especifique en la ventana Propiedades
son los valores iniciales que se asignarán a la propiedad cuando se cree el control en tiempo
de ejecución. En el Diseñador de WPF, los valores que especifique en la ventana Propiedades
se almacenan como atributos en el archivo XAML de la ventana.

En muchos casos, se puede tener acceso a estos valores o modificarlos mediante


programación en tiempo de ejecución; para ello, basta con obtener o establecer desde la
aplicación la propiedad para la instancia de la clase del control. La ventana Propiedades
resulta útil en tiempo de diseño porque permite examinar todas las propiedades, eventos y
métodos que admite un control.

Controlar eventos

Los programas con interfaces de usuario gráficas son principalmente controlados por eventos.
Estos programas esperan a que un usuario haga algo, como escribir texto en un cuadro de
texto, hacer clic en un botón o cambiar la selección de un cuadro de lista. Cuando esto sucede,
el control, que es simplemente una instancia de una clase de .NET Framework, envía un
evento a la aplicación. Tiene la opción de controlar un evento escribiendo un método especial
en la aplicación al que se llamará cuando se reciba el evento.

Podemos utilizar la ventana Propiedades para especificar qué eventos desea tratar en el
código. Si seleccionamos un control en el diseñador y hacemos clic con el icono Rayo en el
botón Eventos de la barra de herramientas de la ventana Propiedades para ver los eventos del
control. El icono siguiente muestra el botón de eventos.

Al agregar un controlador de evento desde la ventana Propiedades, el diseñador escribe


automáticamente el cuerpo del método vacío. Debemos escribir el código de manera que el
método haga algo útil. La mayoría de los controles generan muchos eventos, pero
normalmente una aplicación sólo tendrá que tratar algunos de ellos o incluso sólo uno.

5.3 Capítulo 5: Windows Forms


Creación de Proyectos

Para abrir Visual C# Express Edition 2008 ejecutamos el programa directamente o con los
acceso directos.

5.4 Capítulo 5: Windows Forms


Automáticamente nos aparece la siguiente pantalla:

El entorno de desarrollo de Visual C# podrá ser diferente al


mostrado en la pantalla superior para modificar el entorno nos
podemos ir al menú Ver y agregamos los elementos que
necesitemos, por ejemplo uno elementos imprescindible es el
Cuadro de Herramientas, podemos seleccionar para visualizarlo
como se muestra en la pantalla de la izquierda o también dar clic
en el botón de la barra de herramientas o con las teclas de acceso
rápido que serian Ctrl+W, X.

En el cuadro de herramientas
tenemos tres opciones desde
cerrar para desaparecer el
cuadro, ocultar automáticamente
o colocarla flotante, acoplable,
etc.

5.5 Capítulo 5: Windows Forms


El espacio de nombres System.Windows.Forms

El espacio de nombres (namespace) System.Windows.Forms contiene clases para crear


aplicaciones basadas en ventanas que toman ventaja completa de las características de una
interfaz de usuario disponibles en el sistema operativo Windows de Microsoft.

La siguiente tabla muestra las clases en este espacio de nombres agrupadas en categorías.

Categoría de la clase Detalles


La mayoría de las clases dentro de este espacio de
nombres derivan de la clase Control. La clase Control
provee la funcionalidad básica para todos los controles
Control, Control de que se despliegan en una forma. La clase Form representa
usuario y Forma una ventana en una aplicación. Esta incluye cajas de
dialogo, ventanas modales e Interfaces de Múltiple
Documento. También se pueden crear controles propios de
usuario derivándolos de la clase UserControl.
Las Formas contienen un conjunto muy rico de clases para
crear sus propias barras de herramientas y menús con
apariencia moderna y comportamiento. ToolStrip,
Menús y Toolbars
MenuStrip, ContextMenuStrip y StatusStrip se pueden usar
para crear barras de herramientas, barras de menú, menús
de contexto y barras de status respectivamente.
Este espacio de nombres provee una variedad de clases
control que se pueden usar para crear interfaces de
Controles
usuario como TextBox, ComboBox, Label, ListView, Button,
WebBrowser, HtmlDocument, MaskedTextBox y PropertyGrid.
Algunas clases ayudad a controlar la distribución de una
Layout superficie de despliegue como: FlowLayoutPanel,
TableLayoutPanel y SplitContainer.
Las formas Windows definen una arquitectura ideal para
ligarlas a fuentes de datos tales como bases de datos y
Data y Data Binding
archivos XML, estos controles son: DataGridView,
BindingNavigator, BindingSource
Además de controles este espacio de nombres provee otras
clases que no derivan de la clase Control pero que
proveen características visuales a una aplicación
Componentes
Windows. Tales clases como ToolTip y ErrorProvider
proveen información al usuario así también las clases
Help y HelpProvider.
Windows provee cajas de dialogo con propósitos especiales
como son OpenFileDialog, SaveFileDialog, FontDialog,
Cajas de Diálogos PageSetupDialog, PrintPreviewDialog y PrintDialog. Este
comunes espacio de nombres provee la clase MessageBox para
desplegar una caja de mensaje que puede desplegar y
obtener datos del usuario.
Las Formas contienen un conjunto muy rico de clases para
Menús y Toolbars crear sus propias barras de herramientas y menús con
apariencia moderna y comportamiento. ToolStrip,

5.6 Capítulo 5: Windows Forms


MenuStrip, ContextMenuStrip y StatusStrip se pueden usar
para crear barras de herramientas, barras de menú, menús
de contexto y barras de status respectivamente.

Hay algunas clases dentro de System.Windows.Forms que proveen soporte a las clases
mencionadas arriba. Ejemplos son: enumeraciones, clases argumento evento y delegados
usados por eventos dentro de controles y componentes.

Insertando controles dentro de la forma

Una ventana muy útil es la ventana de propiedades si no la tenemos disponible nos vamos al
menú Ver → Ventana Propiedades esta nos muestra la propiedad de cualquier control, por
ejemplo un botón, cuadro de texto, etiqueta.

Vamos a modificar las propiedades de la forma Form1 en primer lugar la seleccionamos y nos
vamos a la ventana de propiedades, aquí vemos en la parte superior el recuadro con el
siguiente texto: Form1 System.Windows.Forms.Form al final contiene una flecha hacia abajo
en ella podemos seleccionar los diferente elementos y modificar sus propiedades, en este
momento no tenemos ningún otro elemento solo la forma.

Seleccionamos la forma, haciendo clic sobre ella en la ventana Propiedades es posible


modificar las propiedades de la misma vamos a modificar el titulo de la ventana que por default
es Form1 a Multiplica para ello nos vamos a Apariencia → Text y escribimos
Multiplica como se muestra en la siguiente pantalla.

5.7 Capítulo 5: Windows Forms


Algunas propiedades tienen un botón a la izquierda con un signo + lo cual indica que estas
propiedades se componen de varias partes, por ejemplo en Font aparece el símbolo de mas
porque es posible cambiar el tipo de letra.

Podemos expandir en el cuadro de herramientas que


necesitemos, por ejemplo si expandimos la opción de
Controles comunes dando clic en el símbolo de más.

Las componentes están acomodadas por funcionalidad y en


forma alfabética.

Si deseamos insertar algún control a la forma simplemente lo


seleccionamos y lo arrastramos en el interior de la forma en la
posición que queramos, posteriormente podemos mover el
control dentro de la forma, cambiar las propiedades, posición
tamaño, nombre, color, etc. Vamos a insertar en la forma dos

etiquetas , tres cajas de texto y un botón


.

El objetivo de las etiquetas es proveer de los elementos


necesarios para ingresar dos números y efectuar la
multiplicación mostrando el resultado.

Por default Visual C# asigna los nombres a las etiquetas como label1, label2, button1,
textBox1, etc. Desde la ventana propiedades podemos modificar el nombre y las
características de la ventana. En la imagen siguiente se muestra el procedimiento a seguir para
cambiar las propiedades de cualquier elemento, en particular, la imagen se refiere al cambio
de propiedades del control button1.

Otra forma de ver las propiedades es seleccionar cualquier control damos clic con el botón
derecho en la opción Propiedades y automáticamente nos muestra las propiedades de dicho
control, esto se ilustra en la siguiente figura:

5.8 Capítulo 5: Windows Forms


Las figuras siguientes muestran ambas formas antes y después de ser modificadas.

5.9 Capítulo 5: Windows Forms


Inserción de Código

Antes de describir como insertar código


en nuestra aplicación es muy
importante identificar el nombre de cada
uno de los controles, en la imagen se
identifican cada uno de ellos, dichos
nombres los asigna automáticamente
Visual C# al insertar cada control, es
posible cambiar el nombre de cada uno
de ellos, al seleccionarlo y en la
ventana de Propiedades, apartado
Diseño campo (Name) modificar el
nombre , en nuestro ejemplo vamos a
dejar intactos cada nombre de los
controles utilizados esto facilita la
programación de nuestra aplicación
pues es más fácil identificar los
elementos. Un error común es confundir
esta propiedad con Text en el apartado
Apariencia cambiamos button1 por Multiplicar, esto debido a que inicialmente Visual C#
asigna el mismo nombre en ambas propiedades, pero uno es como se observa en la ventana
dentro de la forma y la propiedad (Name) en Diseño es como lo identifica Visual C# al
momento de programar.

5.10 Capítulo 5: Windows Forms


Para insertar código es importante identificar la utilidad de cada control insertado como se
describe en la siguiente tabla.

Control (Diseño) Control (Apariencia) Objetivo


Mostrar un texto que ayude al
label1 Operador 1 usuario a identificar que dato
debemos introducir.
textBox1 ---------- Recibir un número .
Mostrar un texto que ayude al
label2 Operador 2 usuario a identificar que dato
debemos introducir.
textBox2 ---------- Recibir otro número.
Dar clic en el botón para realizar
button1 Multiplicar la multiplicación de los datos
introducidos en textBox1 y textBox2
Mostrar el resultado de la
textBox3 ----------
multiplicación.

En la columna Control (Apariencia) aparece ---------- significa que no aplica, es decir


no se modificó la propiedad.

Si analizamos nuestros elementos, el control que efectuará la Multiplicación es button1 por lo


tanto para insertar código damos doble clic sobre él y nos trasladara de Form1.cs (Diseño)
que digamos es la parte gráfica a la ventana Form1.cs que básicamente sería el código de
nuestra aplicación.

El código que se inserta aparece encerrado en el rectángulo, vemos que el método se llama
button1_Click que nos indica que realizará cuando demos doble clic sobre el botón.

Veamos que realiza cada línea.

5.11 Capítulo 5: Windows Forms


En la línea 51 double ct1, ct2; declaramos dos variable de tipo doublé esto llamadas ct1 y
ct2 para hacer referencia a cuadro de texto 1 y 2, el tipo es para que podamos multiplicar
cualquier tipo de número y no solo enteros.

ct1 = Convert.ToDouble(textBox1.Text); línea 53 extrae la entrada del usuario de


textBox1 y lo convierte a doble esto debido a que por default la entradas las maneja como
cadena y el valor se lo asignamos a ct1.En la línea 54 es similar pero para el cuadro de texto
dos.

En textBox3 es donde mostramos el resultado de la multiplicación, para dar formato


escribimos {0:F2} el cero significa que es el primer argumento, la letra F que vamos a
imprimir un valor de tipo doble y el número 2 permite imprimir el resultado con dos decimales. Y
multiplicamos los valores ct1*ct2 que es el resultado que aparecerá en textBox3.

En la línea 56 String.Format La clase String dispone del método Format que nos permite
formatear una expresión.

Podemos copiar el código aquí:

Multiplica.cs
// código que debemos insertar en el método button1_Click

private void button1_Click(object sender, EventArgs e)


{
double ct1, ct2;
// extrae la entrada del usuario
ct1 = Convert.ToDouble(textBox1.Text);
ct2 = Convert.ToDouble(textBox2.Text);
// muestra el resultado
textBox3.Text =String.Format("{0:F2}", ct1*ct2);
}

Para ejecutar el programa presionamos la tecla F5 o en el menú Depurar damos clic en


Iniciar depuración.

5.12 Capítulo 5: Windows Forms


Una tercera opción es dar clic en el botón que aparece en la barra de herramientas.

La pantalla muestra un ejemplo de la ejecución del


programa. Observamos que efectivamente el resultado lo
muestra con dos decimales.

Un código más elaborado que mostraría exactamente


el mismo funcionamiento de nuestra aplicación sería:

Multiplica.cs
// código que debemos insertar en el método button1_Click

private void button1_Click(object sender, EventArgs e)


{
double ct1, ct2, m;
string r;
// extrae la entrada del usuario
ct1 = Convert.ToDouble(textBox1.Text);
ct2 = Convert.ToDouble(textBox2.Text);
m = ct1 * ct2;
r = (String.Format("{0:F2}", m));
textBox3.Text = r;// muestra el resultado

5.13 Capítulo 5: Windows Forms


Insertamos la variable string r y le asignamos el resultado antes de asignarla a
textBox3.Text, también declaramos otra variable de tipo doublé llamada m, este código tiene
más líneas que el anterior, pero podría ser más claro.

Vamos a insertar dos controles de tipo botón, el primero para limpiar los campos y el otro para
salir de la aplicación como se muestra en la siguiente figura:

Mostramos el código sombreado en color amarillo, para el botón 2, que nos sirve para limpiar
los campos de las tres cajas de texto, después de realizar un cálculo podemos limpiar el campo
con este botón.

private void button2_Click(object sender, EventArgs e)


{
textBox1.Text = "";
textBox2.Text = "";
textBox3.Text = "";
}

5.14 Capítulo 5: Windows Forms


Para salir de la aplicación simplemente escribimos Close();, veamos el código insertado:

private void button3_Click(object sender, EventArgs e)


{
Close();
}

Veamos ahora un segundo ejercicio, crearemos un convertidor de temperaturas de grados


Centígrados a grados Fahrenheit, y viceversa, el usuario tiene la opción de elegir en qué
sentido desea realizar la conversión, la siguiente figura muestra los controles insertados en la
forma.

Ejemplo de la ejecución:

Del lado izquierdo convierte de C a F y del lado derecho convierte de F a C

El código insertado para convertir de C a F es:

private void button1_Click(object sender, EventArgs e)


{
double gfarenheit, ct1;
ct1 = Convert.ToDouble(textBox1.Text);
gfarenheit = ct1 * 1.8 + 32.0;
textBox2.Text = String.Format("{0:F3}", gfarenheit);
}

El código insertado para convertir de F a C es:

5.15 Capítulo 5: Windows Forms


private void button2_Click(object sender, EventArgs e)
{
double gcentigrados, ct1;
ct1 = Convert.ToDouble(textBox1.Text);
gcentigrados = (ct1 - 32.0)/1.8;
textBox2.Text = String.Format("{0:F3}", gcentigrados);
}

El código para los botones de Limpiar y Salir, son identicos al del ejemplo Multiplica.

Caja de Mensajes (MessageBox)

Vamos a estudiar el método Show de la clase MessageBox. Dicho método es polimorfo y


puede mandarse llamar de 21 diferente maneras. La que veremos aquí tiene la forma:

DialogResult MessageBox.Show(string text, string caption,


MessageBoxButtons buttons, MessageBoxIcon icon);

La primera cadena (text), se despliega como mensaje en una caja de dialogo.

La segunda cadena (caption), se despliega como título de la caja de dialogo o ventana

buttons es un elemento de la enumeración MessageBoxButtons que puede tomar uno de seis


diferentes valores y que dependiendo de ello mostrará 1, 2 o 3 botones en la caja de dialogo:

OK
OKCancel
YesNo
YesNoCancel
RetryCancel
AbortRetryIgnore

icon es un elemento de la enumeración MessageBoxIcon que puede tomar uno de cuatro


diferentes valores y que dependiendo de ello mostrará el icono correspondiente:

Information
Exclamation
Question
Error

5.16 Capítulo 5: Windows Forms


Este método Show de MessageBox siempre nos regresará un resultado del tipo DialogResult y
éste dependerá del botón que oprimamos al cerrar el dialogo de Mensaje. DialogResult es
una enumeración que tiene los siguientes valores:

DialogResult.OK
DialogResult.Cancel
DialogResult.Yes
DialogResult.No
DialogResult.Ignore
DialogResult.Abort
DialogResult.Retry

Crearemos un nuevo proyecto al que llamaremos MessageBoxes. En la forma Form1


generada, depositaremos:

 2 Etiquetas (Label)
 2 Cajas de agrupamiento (GroupBox)
 1 Botón (Button)
 10 Botones de radio (RadioButton)

Nuestra forma quedaría de la siguiente manera:

5.17 Capítulo 5: Windows Forms


Cambiemos las propiedades según se muestra en la siguiente tabla, la propiedad Name de
cada elemento no se cambia:

Componente Propiedad Valor


Form1 Text Ejemplos MessageBox
label1 Text Elige el MessageBox para visualizarlo
Name label2
label2
Text == nada ==
button1 Text Visualizar
groupBox1 Text Tipo de botón
groupBox2 Text Tipo de icono
Text OK
radioButton1
Checked True
radioButton2 Text OK Cancel
radioButton3 Text Yes No
radioButton4 Text Yes No Cancel
radioButton5 Text Retry Cancel
radioButton6 Text Abort Retry Cancel
Text Information
radioButton7
Checked True
radioButton8 Text Exclamation
radioButton9 Text Question
radioButton10 Text Error

De tal manera que nuestra forma quedaría así:

5.18 Capítulo 5: Windows Forms


Ahora programemos el evento para que se genere un cambio en la sección Tipo de Botón del
lado izquierdo, teniendo seleccionado el radioButton1 con etiqueta OK, hagamos clic en el
botón que tiene un rayo en la ventana de propiedades (para seleccionar eventos) y
seleccionemos CheckedChange, a la derecha escribamos como nombre para el método que se
va a ejecutar cuando este evento se lleve a cabo, tipoDeBoton_CheckedChange, hagamos lo
mismo para los otros cinco radioButtons restantes seleccionando siempre el mismo método.

Lo que sigue es agregar una variable privada a la clase y lo hacemos antes del constructor:

private MessageBoxButtons tipoDeBoton = MessageBoxButtons.OK;

5.19 Capítulo 5: Windows Forms


Luego insertemos el siguiente código para el método tipoDeBoton_CheckedChanged

private void tipoDeBoton_CheckedChanged(object sender, EventArgs e)


{
if (sender == radioButton1)
tipoDeBoton = MessageBoxButtons.OK;
else if (sender == radioButton2)
tipoDeBoton = MessageBoxButtons.OKCancel;
else if (sender == radioButton3)
tipoDeBoton = MessageBoxButtons.YesNo;
else if (sender == radioButton4)
tipoDeBoton = MessageBoxButtons.YesNoCancel;
else if (sender == radioButton5)
tipoDeBoton = MessageBoxButtons.RetryCancel;
else
tipoDeBoton = MessageBoxButtons.AbortRetryIgnore;

En el código anterior se investiga cual de los radioButtons (mediante sender) cambió su


estatus de desactivado a activado y se pone la variable tipoDeBoton con uno de los 6 posibles
valores que tiene la enumeración MessageBoxButtons.

Ahora programemos el evento de que se genere un cambio en la selección de los botones de la


derecha es decir en Tipo de Icono, teniendo seleccionado el radioButton7 con etiqueta
Information, hagamos clic en el botón que tiene un rayo en la ventana de propiedades (para
seleccionar eventos) y seleccionemos CheckedChange, a la derecha escribamos como nombre
para el método que se va a ejecutar cuando este evento se lleve a cabo,
tipoDeIcono_CheckedChanged, hagamos lo mismo para los tres radioButtons restantes
seleccionando siempre el mismo método.

5.20 Capítulo 5: Windows Forms


Lo que sigue es agregar una variable privada a la clase y lo hacemos también antes del
constructor:

private MessageBoxIcon tipoDeIcono = MessageBoxIcon.Error;

Luego insertemos el siguiente código para el método tipoDeIcono_CheckedChanged

private void tipoDeIcono_CheckedChanged(object sender, EventArgs e)


{
if (sender == radioButton7) // display error icon
tipoDeIcono = MessageBoxIcon.Information;
else if (sender == radioButton8)
tipoDeIcono = MessageBoxIcon.Exclamation;
else if (sender == radioButton9)
tipoDeIcono = MessageBoxIcon.Question;
else // only one option left--display question mark
tipoDeIcono = MessageBoxIcon.Error;
}

Como en el primer método, se investiga cual de los radioButtons (mediante sender) cambió su
estatus de desactivado a activado y se pone la variable tipoDeIcono con uno de los cuatro
posibles valores que tiene la enumeración MessageBoxIcon.

Por último queremos programar el botón Mostrar para que al hacer clic sobre él se ejecute el
método button1_Click desplegando el MessageBox configurado con el valor que en su
momento tengan las variables tipoDeBoton y tipoDeIcono.

private void button1_Click(object sender, EventArgs e)


{
DialogResult result =
MessageBox.Show("Mensaje a desplegar",
"Título de la Ventana",

5.21 Capítulo 5: Windows Forms


tipoDeBoton,
tipoDeIcono);
switch (result)
{
case DialogResult.OK: label2.Text = "Seleccionó OK."; break;
case DialogResult.Cancel: label2.Text = "Seleccionó Cancel."; break;
case DialogResult.Yes: label2.Text = "Seleccionó Yes."; break;
case DialogResult.No: label2.Text = "Seleccionó No."; break;
case DialogResult.Ignore: label2.Text = "Seleccionó Ignore."; break;
case DialogResult.Abort: label2.Text = "Seleccionó Abort."; break;
case DialogResult.Retry: label2.Text = "Seleccionó Retry."; break;
}
}

El código fuente completo de nuestro proyecto puede consultarse en el apéndice 5: Caja de


Mensajes -- Form1.cs

A continuación dos ejecuciones de nuestro programa:

5.22 Capítulo 5: Windows Forms


Caja de Selección

Ahora crearemos un nuevo proyecto C# del tipo de Aplicación de Windows Forms, al que
llamaremos CajadeSeleccion.

A la forma principal Form1 agreguemos los siguientes controles:

4 Etiquetas (Label)
12 Cajas de selección (CheckBox)
2 Botones (Button)

En la etiqueta uno escribimos el texto UACM POO en C#, las otras tres etiquetas las
utilizaremos para colocar los títulos Estilo, Fuente, Tamaño, las doce cajas de selección
nos ayudaran a modificar el texto de la etiqueta uno en cuanto al tipo de letra, tamaño y estilo,
el botón Salir cierra la aplicación y el botón Limpiar, regresa al texto original sin aplicar
ningún formato.

En la siguiente figura observamos como quedaría el diseño de la forma:

A continuación, a los eventos CheckedChanged de cada una de las cajas de selección


agreguemos un método pulsando con el mouse a la derecha del evento que queremos
programar.

5.23 Capítulo 5: Windows Forms


Este sería el código del método para cambiar el texto de la etiqueta uno a negrita:

private void Negrita_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily,
this.label1.Font.Size, this.label1.Font.Style ^ FontStyle.Bold);
}

Repetimos el mismo paso para crear otros tres métodos para cambiar al estilo itálica, tachado o
subrayado, lo que harán estos métodos es cambiar la fuente de la etiqueta label1 para que el
estilo cambie a Bold o Italic o Strikeout o Underline

El principio que estamos usando aquí es el hecho de que para crear una Fuente hay que
hacerlo de la siguiente manera

new Font(FontFamily family, float emSize, FontStyle style);

donde FontFamily es una familia de fuentes como por ejemplo Arial o Consolas y
FontStyle puede ser Bold, Italic, Strikeout, Underline o la combinación de ellos, el
tamaño se pude especificar con un número por ejemplo 10, 12, 20.

Para cambiar el tipo de fuente de la etiqueta nuevamente al evento CheckedChanged de cada


una de las cuatro cajas de selección agreguemos un método pulsando con el mouse a la
derecha del evento que queremos y escribimos el siguiente código:

private void Consolas_CheckedChanged(object sender, EventArgs e)


{
FontFamily csl = new FontFamily("Consolas");
this.label1.Font = new Font(csl, this.label1.Font.Size,
this.label1.Font.Style);
}

5.24 Capítulo 5: Windows Forms


csl es el nuevo tipo de fuente que creamos puede llamarse como queramos respetando la
reglas de identificadores válidos, entre comillas en color rojo aparece "Consolas" aquí
debemos seleccionar un tipo de fuente válido podemos ver la ventana de propiedades cuando
cambiamos la fuente los tipos disponibles o también en el procesador de texto Word de Office
los tipos de fuentes, realizamos lo mismo para los otros tres tipos de fuentes.

Finalmente en la última columna con las cuatro cajas de selección cambiamos el tamaño del
texto de la etiqueta uno con un procedimiento similar a los dos anteriores primero configurando
el evento y después escribiendo en el método lo siguiente:

private void Ocho_CheckedChanged(object sender, EventArgs e)


{ this.label1.Font = new Font(this.label1.Font.FontFamily, 8,
this.label1.Font.Style);
}

Observemos que nuevamente aquí de los tres parámetros o argumentos solo modificamos el
tamaño.

En cuanto a los botones el botón salir solo agregamos el código: Close();

private void button1_Click(object sender, EventArgs e)


{
Close();
}

El botón limpiar regresa el texto de la etiqueta uno al formato original, por ejemplo si
cambiamos el tipo de letra a Broadway, Tachado y tamaño 20, al darle limpiar simplemente
regresamos al texto con el formato original para saber cuál era el formato original
seleccionamos la etiqueta uno y en propiedades vemos el tipo de letra y tamaño utilizado.

private void button2_Click(object sender, EventArgs e)


{
FontFamily mss = new FontFamily("Microsoft Sans Serif");
this.label1.Font = new Font(mss, 12, FontStyle.Regular);
}

Si observamos aquí para cambiar el estilo del texto utilizamos simplemente


FontStyle.Regular, por otro lado en las cajas de selección escribimos
this.label1.Font.Style ^ FontStyle.Bold, esto se debe a que si utilizamos la forma
más simple es decir FontStyle.Bold, solo lo efectuaría una vez y después ya no lo
cambiaría debido a que no especificamos a que control deseamos aplicar el cambio.

5.25 Capítulo 5: Windows Forms


El código fuente completo de nuestro proyecto puede consultarse en el apéndice 5: Cajade
Selección -- Form1.cs

Un ejemplo de la ejecución del programa sería el siguiente:

Visor de Imágenes y Enlaces

Este proyecto abarca dos secciones, en la primera se trata de un visor de imágenes, es una
aplicación muy simple que lee archivos gráficos, el botón Elegir Imagen en combinación con
el control openFileDialog nos permite seleccionar la ubicación de nuestra imagen, una vez
seleccionada la imagen se mostrara en el recuadro pictureBox1. La segunda parte son los
enlaces a tres elementos el primero abre la calculadora de Windows, la segunda abre una liga
a la página de la Universidad, por último abre el Explorador de Windows en el disco local C:\,
esto se logra mediante los controles linkLabel.

La siguiente figura muestra los controles necesarios para elaborar nuestro proyecto

5.26 Capítulo 5: Windows Forms


Noten que el control openFileDialog1 no aparece dentro de la forma si no en la parte inferior
de nuestro proyecto.,

Los controles necesarios para llevar a cabo el proyecto son:

1 Caja de Imagen (pictureBox)


1 Caja de dialogo para abrir un archivo (openFileDialog)
2 Botones (Button)
3 Etiquetas de Enlace (linkLabel)

Al botón 1 que dice Elegir Imagen al darle doble clic nos traslada al código e insertamos lo
siguiente:

private void button1_Click(object sender, EventArgs e)


{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{ // Carga la imagen dentro del cuadro picture box.
pictureBox1.Image= Image.FromFile(openFileDialog1.FileName);
// Muestra el nombre del archivo en el titulo de forma

5.27 Capítulo 5: Windows Forms


this.Text = string.Concat("Visor de Imagenes(" + openFileDialog1.FileName
+ ")"); }
}
Un ejemplo de la ejecución del proyecto con esta primera parte del Visor de Imágenes:

En la segunda parte del proyecto se refiere a los Enlaces, usamos el control linkLabel el cual
tiene la peculiaridad de poseer una liga (como las páginas Web) a directorios de nuestro
sistema de archivos, a direcciones electrónicas de sitios Web o FTP y también a aplicaciones
que se encuentren en el Registro de Windows.

Ya tenemos agregados los tres linkLabel, ahora necesitamos la programación de los eventos
de hacer click en el control, en los tres eventos utilizaremos la llamada del método:

System.Diagnostics.Process.Start(parametros);

En donde los parametros pueden ser:

o Una cadena de caracteres con el nombre de un directorio ejemplo. "C:\\Documents and


Settings\\users\\avalera"
o Una cadena de caracteres con el nombre de un programa Navegador de Internet y una
segunda cadena con una dirección electrónica ejemplo. "http://google.com" que se
quiere visitar

5.28 Capítulo 5: Windows Forms


o Una cadena de caracteres con el nombre de un programa que se quiere mandar
ejecutar

En cada una de las etiquetas de enlace insertamos el siguiente código:

private void linkLabel1_LinkClicked(object sender,


LinkLabelLinkClickedEventArgs e)
{
linkLabel1.LinkVisited = true;
System.Diagnostics.Process.Start("Calc");
}

private void linkLabel2_LinkClicked(object sender,


LinkLabelLinkClickedEventArgs e)
{
linkLabel2.LinkVisited = true;
System.Diagnostics.Process.Start("IExplore",
"http://www.uacm.edu.mx");
}

private void linkLabel3_LinkClicked(object sender,


LinkLabelLinkClickedEventArgs e)
{
linkLabel3.LinkVisited = true;
System.Diagnostics.Process.Start("C:\\");
}

Observemos que normalmente no cambiamos el nombre de los controles por ejemplo aquí
utilizamos el nombre por default linkLabel1, linkLabel2, linkLabel3, esto digamos que
es por “simplicidad”, aunque si quisiéramos que fuera mas intuitivo nuestro programa
podríamos llamar en lugar de linkLabel1, quizás calculadora, o en lugar de linkLabel2 el
nombre de uacm, etc.

La ejecución de esta segunda parte del proyecto abrirá las siguientes aplicaciones:

5.29 Capítulo 5: Windows Forms


Web Browser y Creación de Menús

En la siguiente aplicación vamos a crear un Web Browser dentro de la misma forma,


insertaremos algunas direcciones para seleccionar por cual navegar y mediante un menú nos
trasladaremos a la página principal, atrás o adelante, funciones básicas que cualquier
navegador tiene incorporadas, para lograr tal fin incorporaremos los siguientes controles:

1 Menú (menuStrip)
1 Caja del tipo combo (comboBox)
2 Botones (Button)
1 Navegador Web (webBrowser)

Noten que el control menuStrip1 no aparece dentro de la forma si no en la parte inferior de


nuestro proyecto, aquí por cuestiones de espacio se muestra del lado derecho.

Veamos los pasos a seguir para crear el proyecto en primer lugar


insertemos el control menuStrip, Cuando liberemos el control de
menú, veremos que crea un menú por defecto en la parte superior que
nos mostrara un cuadro que muestra Escriba Aquí, introducir el
nombre del menú; en este caso, Navegar. Cuando presionamos
entrar o enter, aparecen nuevos cuadros vacíos para crear otros
menús y elementos de menú. En el cuadro inferior, teclear Home. Presionar enter, y se
mostrarán más cuadros. Teclear Adelante. Presionar enter, y teclear Atras. Estos elementos
de menú constituyen nuestros controles básicos de navegación de sitios Web.

5.30 Capítulo 5: Windows Forms


Como segundo paso vamos agregar el comboBox y llenarlo, un ComboBox provee una lista
desplegable de opciones que el usuario puede seleccionar. En este programa, el ComboBox
contendrá una lista de nuestros sitios Web favoritos para tener un rápido acceso. Para crear la
lista de sitios, seleccionar el ComboBox y visualizar sus propiedades. Hacer clic en la columna
junto a la propiedad Items, y aparecerá Colección y adelante un cuadro con puntos
suspensivos hacer clic en ese botón para editar el contenido del ComboBox. Añadir tantas ligas
de sitios Web como se desee, presionando enter tras introducir cada una de ellas.

Insertamos dos botones uno que seleccionaría el link o enlace al cual queremos ir y el segundo
para salir del programa, luego vamos a insertar el control webBrowser y ajustarlo al tamaño
adecuado.

Ahora ya hemos finalizado la fase de diseño de nuestra aplicación, y hemos llegado al punto
donde necesitamos añadir algún código en C# para proporcionar la funcionalidad del programa.
Necesitamos añadir controladores para el botón y para cada opción de menú. Un controlador
es un método que se ejecuta cuando se activa un determinado control. Visual C# Express crea
controladores vacíos para nosotros automáticamente. Hacer doble clic sobre el botón, y
aparecerá el editor de código para nuestro proyecto. Veremos que el controlador para el evento
asociado al evento de mensaje que sucede cuando el usuario hace clic sobre un botón ha sido
creado por nosotros. Añadir código al método del controlador de modo que tenga una
apariencia similar al ejemplo siguiente.

private void button1_Click(object sender, EventArgs e)


{
webBrowser1.Navigate(comboBox1.SelectedItem.ToString());
}

5.31 Capítulo 5: Windows Forms


Este código toma el elemento del control ComboBox que está seleccionado, una cadena que
contiene una URL Web, y lo pasa al método de navegación del navegador Web. El método de
navegación carga y visualiza el contenido de una página Web en esa ubicación.

Vamos a añadir el código para las opciones del menú, (volver a la ventana de diseño o
diseñador presionar Shift + F7 y para ir al código insertar F7), hacer doble clic sobre cada
uno de los elementos de menú. Visual C# Express crea métodos de controladores para cada
uno. Editar estos métodos de modo que tengan una apariencia similar al código siguiente.

private void homeToolStripMenuItem_Click(object sender, EventArgs e)


{ // Opción del Menú Home o Página Principal
webBrowser1.GoHome();
}

private void adelanteToolStripMenuItem_Click(object sender, EventArgs


{ // Opción del Menú Adelante
webBrowser1.GoForward();
}

private void atrasToolStripMenuItem_Click(object sender, EventArgs e)


{ // Opción del Menú Atras
webBrowser1.GoBack();
}

La última tarea es añadir código de inicialización al método Form1. Este método es el


constructor para el objeto Form1 y se invoca cuando se crea el Windows Form. Es, por tanto, la
ubicación ideal para situar cualquier código que se requiera para cambiar los valores iniciales
de los controles u otras configuraciones. El siguiente código provocará que el control Web
Browser visualice la página de inicio por defecto en nuestro ordenador, y también establecerá
el valor inicial del ComboBox. Cambiar el método para que contenga el siguiente código:

public Form1()
{ InitializeComponent();
comboBox1.SelectedIndex = 0;
webBrowser1.GoHome();
}

El código fuente completo de nuestro proyecto puede consultarse en el apéndice 5:


WebBrowser_Menus -- Form1.cs

Un ejemplo de la ejecución del proyecto:

5.32 Capítulo 5: Windows Forms


Formas que llaman a otras formas

Vamos a crear tres Formas (Clases) Form1, Form2 y Form3, y la idea es que Form1 pueda
llamar mediante respectivos botones a Form2 o Form3. Tanto Form2 como Form3 son dos
Formas del tipo modal (mientras que no se cierren no puede accederse a otra parte del
programa).

Una vez que la aplicación quede terminada lucirá semejante a la que se muestra a
continuación:

5.33 Capítulo 5: Windows Forms


Una vez llena la forma de captura Form3, la información es pasada a Form1, en la forma 3
tenemos 5 campos a llenar, Calle, Colonia, Delegación, Código Postal y Teléfono, una vez
que llenamos estos datos y damos clic al botón OK, automáticamente los datos los copia a la
forma 1, a las etiquetas label2, label3, label4, label5 y label6, respectivamente.
Podemos dejar en blanco el campo Text de estas 5 etiquetas, para ilustra estos controles
aparecen en el proyecto. Este es un ejemplo de la ejecución:

5.34 Capítulo 5: Windows Forms


En la Forma 1 vamos a ingresar:

6 Etiquetas (Label)
1 Caja de texto (textBox)
2 Botones (Button)

En el Explorador de Soluciones haciendo clic derecho en el nombre del proyecto, vamos a


insertar la forma 2 y 3.

En la Forma 2 vamos a ingresar:

2 Etiquetas (Label)
1 Botón (Button)

En la Forma 3 vamos a ingresar:

6 Etiquetas (Label)
5 Caja de texto (textBox)
1 Botón (Button)

5.35 Capítulo 5: Windows Forms


Creación de Propiedades en una Clase
Cuando en una clase está declarado un campo (variable) privado por ejemplo Informacion
del tipo string (véase el siguiente segmento de código), la manera para acceder a él es
mediante métodos públicos de la clase o a través de la declaración de una propiedad
relacionada con él.

En C# la manera de declarar una propiedad info para darle un valor al campo Informacion
(set) o para poder leer el contenido de éste (get) es la siguiente:

private string Informacion;


public string info
{
set // para escritura
{
Informacion = value;
}

get // para lectura


{
return Informacion;
}
}

Para nuestra Clase Form3 creáremos 6 propiedades:

public string Nombre


{
set
{
label1.Text = value;
}
}
public string Calle
{
get
{
return textBox1.Text;
}
}
public string Colonia
{
get
{
return textBox2.Text;
}
}

5.36 Capítulo 5: Windows Forms


public string Delegación
{
get
{
return textBox3.Text;
}
}
public string CódigoPostal
{
get
{
return textBox4.Text;
}
}
public string Teléfono
{
get
{
return textBox5.Text;
}
}

private void button1_Click(object sender, EventArgs e)


{
Close();
}

El Método para los dos botones de Form1

A continuación se muestra el código que debemos ingresar a los dos métodos del botón
Ingresar Datos y Acerca de..., anteriormente creado para Form1.

private void button1_Click(object sender, EventArgs e)


{
Form2 acercaDe = new Form2();
acercaDe.ShowDialog();

private void button2_Click(object sender, EventArgs e)


{
Form3 data = new Form3();
data.Nombre = textBox1.Text;
data.ShowDialog();
label2.Text = "Calle: " + data.Calle;
label3.Text = "Colonia: " + data.Colonia;
label4.Text = "Delegación: " + data.Delegación;
label5.Text = "Código Postal " + data.CódigoPostal;

5.37 Capítulo 5: Windows Forms


label6.Text = "Código Postal " + data.Teléfono;
}

El código fuente completo de nuestro proyecto puede consultarse en el apéndice 5:


llamarFormas -- Form1.cs Form2.cs Form3.cs

Matrices en dataGridView
El control DataGridView proporciona una tabla personalizable para mostrar datos. La clase
DataGridView permite personalizar celdas, filas, columnas y bordes mediante propiedades.

El siguiente proyecto suma dos matrices cuadradas de NxN, consta de 3 dataGridViews en


primer lugar se le asignan columnas y filas según el tamaño que le asignemos a la matriz por
default, así como dos botones los cuales uno es para calcular el tamaño de la matriz y rellenar
los valores aleatorios dentro del grid, y el segundo botón nos sirve para calcular la suma de las
dos matrices. Podemos modificar los valores de nuestros grids, y volver a sumar, para obtener
la matriz resultante.

Controles utilizados:

4 Etiquetas (Label)
3 Grid (dataGridView)
2 Botones (Button)
1 Caja de texto (textBox)

El proyecto en vista del diseñador tendrá la siguiente apariencia:

Al botón Generar Matriz se le insertara el siguiente código:

5.38 Capítulo 5: Windows Forms


private void button1_Click(object sender, EventArgs e)
{
dataGridView1.Columns.Clear();
dataGridView2.Columns.Clear();
dataGridView3.Columns.Clear();
int tam = int.Parse(textBox1.Text);
int i = 1;
while (i <= tam)
{
DataGridViewColumn columna = new DataGridViewColumn(new DataGridViewTextBoxCell());
columna.Width = 25; //ancho
this.dataGridView1.Columns.Add(columna);
DataGridViewColumn columna2 = new DataGridViewColumn(new DataGridViewTextBoxCell());
columna2.Width = 25;
this.dataGridView2.Columns.Add(columna2);

DataGridViewColumn columna3 = new DataGridViewColumn(new DataGridViewTextBoxCell());


columna3.Width = 25;
this.dataGridView3.Columns.Add(columna3);
i++;
}
int[,] _matriz1 = new int[tam, tam]; // se declaran variables de tipo matriz
int[,] _matriz2 = new int[tam, tam];
int[,] _matriz3 = new int[tam, tam];
dataGridView1.Rows.Add(tam);
dataGridView2.Rows.Add(tam);
dataGridView3.Rows.Add(tam);
Random r = new Random();
// genera un dato de manera aleatoria, se utiliza para revolver los datos llena los datos de las casillas
vacias.
for (int f = 0; f < tam; f++)
{
for (int c = 0; c < tam; c++)
{
_matriz1[f, c] = r.Next(10); // valor inicial que agarra valores del 0 al 10
_matriz2[f, c] = r.Next(10);
_matriz3[f, c] = 0;
dataGridView1[f, c].Value = _matriz1[f, c]; // se agrega filas y colmnas
dataGridView2[f, c].Value = _matriz2[f, c];
dataGridView3[f, c].Value = _matriz3[f, c];
}
}
}

Y botón Sumar el código:


private void button2_Click(object sender, EventArgs e)

{
int tam = int.Parse(textBox1.Text);
int[,] _matriz1 = new int[tam, tam];
int[,] _matriz2 = new int[tam, tam];
int[,] _matriz3 = new int[tam, tam];
for (int f = 0; f < tam; f++) // filas
{
for (int c = 0; c < tam; c++) //columnas
{
_matriz1[f, c] = int.Parse(dataGridView1[f, c].Value.ToString()); // almacena
_matriz2[f, c] = int.Parse(dataGridView2[f, c].Value.ToString());
_matriz3[f, c] = _matriz1[f, c] + _matriz2[f, c];
dataGridView3.CurrentCell = dataGridView3[f, c];
dataGridView3.CurrentCell.Value = _matriz3[f, c];
}
}

5.39 Capítulo 5: Windows Forms


La clase DataGridViewTextBoxCell es un tipo especializado de DataGridViewCell utilizado
para mostrar una única cadena de información basada en texto modificable.

La clase DataGridViewColumn representa una columna lógica de un control DataGridView.


Podemos recuperar las columnas a través de la colección Columns del control.

Al contrario que DataGridViewRow, que contiene la colección real de celdas de un control


DataGridView, DataGridViewColumn se utiliza principalmente para ajustar la apariencia y
comportamiento de la interfaz de usuario de la columna, como el ancho de columna y el estilo
de celda.

DataGridView.Rows Es una propiedad que obtiene una colección que contiene todas las filas
del control DataGridView.

Del lado izquierdo se muestra la ejecución cuando damos una dimensión de 5 para nuestra
matriz cuadrada en esta parte cada elemento de la matriz resultante se inicializa en cero, del
lado derecho cuando damos clic en Suma obtenemos el resultado de cada elemento de la
matriz resultante.

Creación de Menús
El siguiente proyecto muestra la creación de menús, utilizamos tres etiquetas y mediante las
opciones del menú Formato y Fondo, cambiamos el color de fondo, el tipo y color de la fuente
o letra, mediante el menú Acerca de… mostramos información de contacto del autor del
proyecto y la opción Salir. Como parte complementaria y para no incluirla en un solo proyecto
agregamos el control dateTimePicker y el botón Fecha, esto simplemente muestra un
calendario seleccionamos una fecha y al dar clic en el botón nos muestra la fecha elegida y del
día actual, esto con ayuda de un MessageBox.Show.

5.40 Capítulo 5: Windows Forms


La estructura general del proyecto es la siguiente:

Controles utilizados:

3 Etiquetas (Label)
1 Menú (menuStrip)

1 DateTimePicker
1 Botón (Button)

Con ingresar un solo menuStrip se pueden derivar todos los menús que necesitemos, en las
siguientes imágenes se muestran cada una de las opciones del menú, es importante aclarar
que la opciones que aparecen como Ctrl+N, Ctrl+B, Ctrl+S, no se escriben si no son
accesos rápidos para trabajar con el proyecto por ejemplo con Ctrl+S, sale uno del proyecto,
en la siguiente pantalla se muestra como se configura esta propiedad.

5.41 Capítulo 5: Windows Forms


En las siguientes figuras se muestra a detalle cada una de las opciones del menú:

El código del botón fecha nos da la información de la fecha seleccionada y el día actual junto
con la hora, su código es:

private void button1_Click(object sender, EventArgs e)


{
// Muestra la fecha seleccionada:
MessageBox.Show("Has seleccionado la fecha: " +
dateTimePicker1.Value.Date);
// Muestra la fecha de hoy:
MessageBox.Show("Hoy es: " + DateTime.Now);
}

5.42 Capítulo 5: Windows Forms


Por razones de espacio el código de cada menú puede consultarse en el apéndice 5:
menuCalendario -- Form1.cs

Ejemplo de la ejecución del proyecto:

5.43 Capítulo 5: Windows Forms


Apéndice 1

Instalación de Microsoft Visual C#


2008 Express Edition

aÉ {tç Öâx xÅÑxétÜ á|xÅÑÜx ÑÉÜ Ät ÇÉv|™Ç ÑÜ|ÅxÜt wx Ätá vÉátá Öâx áx xáàâw|tÇ? á|ÇÉ ÑÉÜ
tÖâxÄÄÉ Öâx Ñâxwx ytv|Ä|àtÜ xÄ tÑÜxÇw|ét}xA
TÜ|áà™àxÄxá

XÄ {ÉÅuÜx xá tØÇ Ät vÉÅÑâàtwÉÜt Åöá xåàÜtÉÜw|ÇtÜ|t wx àÉwtá


]É{Ç YA ^xÇÇxwç

Tabla de Contenido

1. Microsoft Visual C# 2008 Express Edition with SP1 ......................................................................... A1.2


2. SharpDevelop 3.0............................................................................................................................................... A1.12

A1.1 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Los entornos de desarrollo integrado son importantes porque nos facilitan la tarea de
editar, compilar, depurar y ejecutar un proyecto, dado que desde la línea de comandos
resulta mas incomodo y complicado generarlos.

En esta documento se describen dos entornos de desarrollo que son gratuitos, ambos
son de gran utilidad para programar en C#, el alumno elegirá para programar el que le
parezca mas conveniente o ambos.

Instalación
Para la instalación requerimos de los siguiente archivos, los cuales se incluyen en el CD
etiquetado como C# dentro de la carpeta EDI

1. Microsoft Visual C# 2008 Express Edition with SP1

Nombre del archivo: vcssetup.exe Tamaño: 2.60 MB (instalador)


Disponible en Internet: http://www.microsoft.com/express/Downloads/#2008-Visual-CS

Se puede elegir el idioma, disponible el español.

Al ejecutar el programa de instalación esta es la primera pantalla que aparece:

Posteriormente se ejecutara el asistente para la instalación, el cual nos guiara durante


el proceso de instalación.

A1.2 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Posteriormente nos muestra un recuadro con los términos de la licencia, para continuar
es necesario activar la casilla: He leído y acepto los términos de la licencia.

A1.3 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Nos da la opción si deseamos agregar a nuestra instalación productos adicionales como
el paquete de base de datos: Microsoft SQL Server 2008 Express Edition.

A1.4 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Por default nos da la ruta en donde se instalara el programa:
C:\Program Files\Microsoft Visual Studio 9.0

En caso de preferir una ruta diferente de instalación es necesario dar clic en Examinar
y seleccionar la carpeta o directorio de nuestra preferencia.

En esta parte se mostrará cuales son los paquetes o productos que se descargaran e
instalarán, así como el tamaño de la descarga y el espacio requerido en disco.

Aquí es necesario que estemos conectados a Internet para continuar con la instalación.
Continuamos dando clic en Instalar

A1.5 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


La siguiente pantalla nos mostrara el progreso de la instalación así como los paquetes
que se van instalando, es importante mencionar que en esta parte dependiendo de la
velocidad de conexión a Internet este proceso puede durar entre 1 y 3 horas
aproximadamente.

A1.6 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Por último nos mostrara la pantalla que nos indica que la instalación esta completa. Al
finalizar la instalación nos pide registrarnos de no hacerlo el software solo estará
disponible por 30 días.

A1.7 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Si nos registramos nos darán una clave de registro con las instrucciones que debemos
de seguir para registrar el producto.

Inicializamos por primara vez nuestra aplicación


Inicio → Todos los programas → Microsoft Visual C# 2008 Express Edition

Una vez que inicializamos la aplicación nos vamos al menú Ayuda → Registrar
Producto.

A1.8 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Seguimos las instrucciones básicamente lo que necesitamos es tener una cuenta de
correo electrónico en Windows Live con el domino de hotmail.com ó live.com

Una vez obtenida la clave de registro copiamos y pegamos, la clave del registro y
damos clic en Registro Completo.

A1.9 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


A1.10 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition
Por último si deseamos comprobar que el producto ha sido registrado correctamente
nos vamos nuevamente al menú Ayuda → Registrar Producto, y nos deberá de
aparecer el siguiente mensaje.

Ligas electrónicas relacionadas:

Cómo bajar el instalador de Visual C# 2008 Express Edition


http://www.youtube.com/watch?v=OcTgthj4xCI&feature=related

A1.11 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Cómo instalar Visual C# 2008 Express Edition
http://www.youtube.com/watch?v=8JaeW0K8Hec

Cómo obtener una licencia por más de 30 días


http://www.youtube.com/watch?v=DxeodC2w76Y&feature=related

2. SharpDevelop 3.0

Otro entorno de desarrollo integrado importante para programar en C# es SharDevelop


versión 3.0 , tamaño 19.1 MB, lo pueden obtener en la siguiente liga electrónica:
http://www.icsharpcode.net/OpenSource/SD/Download/

El procedimiento y los pasos a seguir son similares a los explicados anteriormente para
instalar y probar Visual C# 2008 Express Edition. Se deja al alumno el instalar y probar
dicho entorno de desarrollo.

A1.12 Apéndice 1: Instalación de Microsoft Visual C# 2008 Express Edition


Apéndice 2

Guía de referencia del lenguaje C#

hÇt ÅxÅÉÜ|t x}xÜv|àtwt xá zâ•t Åöá ätÄ|Éát Öâx xÄ zxÇ|É ç Ät áxÇá|u|Ä|wtwA


]É{tÇÇ V{Ü|áàÉÑ{ YÜ|xwÜ|v{ äÉÇ fv{|ÄÄxÜ

_Éá Ä•Å|àxá wx Å| ÄxÇzât}x áÉÇ ÄÉá Ä•Å|àxá wx Å| ÅxÇàxA


_âwã|z j|ààzxÇáàx|Ç

Tabla de contenido
Tipo de datos enteros................................................................................................ A2.2
Tipo de datos de punto flotante ................................................................................. A2.2
Tipo de datos de caracteres ...................................................................................... A2.3
Tipo de datos lógicos ................................................................................................ A2.3
Constantes ................................................................................................................ A2.3
Aplicar formato a la tabla de resultados numéricos. .................................................. A2.3
Tipos primitivos y sus valores por default .................................................................. A2.4
Secuencias de escape .............................................................................................. A2.4
Variables ................................................................................................................... A2.5
Operadores ............................................................................................................... A2.5
Operadores aritméticos ............................................................................................. A2.5
Operadores relacionales ........................................................................................... A2.5
Operadores lógicos ................................................................................................... A2.6
Tabla completa de operadores .................................................................................. A2.6
Modificadores de acceso ........................................................................................... A2.6
Precedencia de operadores ...................................................................................... A2.7
Clase System.Array................................................................................................... A2.7
Clase System.String .................................................................................................. A2.9
Excepciones más comunes. ...................................................................................... A2.9
Estructuras de Control ............................................................................................. A2.10

A2.1 Apéndice 2: Guía de referencia del lenguaje C#


C♯ contiene dos categorías generales de tipos de datos integrados: tipos de valor y
tipos de referencia. El término tipo de valor indica que esos tipos contienen
directamente sus valores.

C♯ define ocho tipos de enteros, a saber:

Tipo de datos enteros


Tipo Bits Rango Significado
byte 8 De 0 a 255 Entero sin signo de 8 bits
sbyte 8 De -128 a 127 Entero con signo de 8 bits
short 16 De -32.768 a 32.767 Entero corto
ushort 16 De 0 a 65.535 Entero corto sin signo
int 32 De -2.147.483.648 a Entero medio
2.147.483.647
uint 32 De 0 a 4.294.967.295 Entero medio sin signo
long 64 De - Entero largo
9.223.372.036.854.775.808 a
9.223.372.036.854.775.807
ulong 64 De 0 a Entero largo sin signo
18.446.744.073.709.551.615

Tipo de datos de punto flotante

Los tipos de punto flotante pueden representar números con componentes fraccionales.
Existen dos clases de tipos de punto flotante; float y double. El tipo double es el
más utilizado porque muchas funciones matemáticas de la biblioteca de clases de C♯
usan valores double. Quizá, el tipo flotante más interesante de C♯ es decimal, dirigido
al uso de cálculos monetarios. La aritmética de punto flotante normal está sujeta a una
variedad de errores de redondeo cuando se aplica a valores decimales. El tipo decimal
elimina estos errores y puede representar hasta 28 lugares decimales.

Tipo Ancho Rango Significado


Bits

float 32 De 1.5E-45 a 3.4E+38 Punto flotante corto

double 64 De 5E-324 a 1.7E+308 Punto flotante largo

decimal 128 De 1E-28 a 7.9E+28 Punto flotante monetario

Los caracteres en C♯ no son cantidades de 8 bits como en otros muchos lenguajes de


programación. Por el contrario, C♯ usa un tipo de caracteres de 16 bits llamado Unicode
al cual se le llama char. No existen conversiones automáticas de tipo entero a char.

A2.2 Apéndice 2: Guía de referencia del lenguaje C#


Tipo de datos de caracteres
Tipo Bits Rango Significado
char 16 De 0 a 65,535 (código Unicode) Carácter

Tipo de datos lógicos


Tipo Bits Rango Significado
bool 1 true or false, no se usa 1 ó 0 ya true or false
que no hay conversión definida

No existe una conversión definida entre bool y los valores enteros (1 no se convierte a
verdadero ni 0 se convierte a falso).

Constantes

Las constantes en C♯ se denominan literales. Todas las constantes tienen un tipo de


dato, en caso de ser una constante entera se usa la de menor tamaño que pueda
alojarla, empezando por int. En caso de punto flotante se considera como un double.
Sin embargo se puede especificar explícitamente el tipo de dato que una constante
deberá usar, por medio de los sufijos:

Sufijo Tipo de dato Ejemplo


L Long 12L
UL Ulong 68687UL
F Float 10,19F
M Decimal 9,95M

En ocasiones, resulta más sencillo usar un sistema numérico basado en 16 en lugar de


10, para tal caso C♯ permite especificar constantes enteras en formato hexadecimal y
se hace empezando con 0x. Por ejemplo: 0xFF equivale a 255 en decimal.

Aplicar formato a la tabla de resultados numéricos.

Se puede dar formato a los resultados numéricos mediante el método String.Format o


a través del método Console.Write, el cual llama a String.Format. El formato se
determina mediante las cadenas de formato. La tabla siguiente contiene las cadenas de
formato estándar admitidas. La cadena de formato tiene la forma siguiente: Axx,, donde
A es el especificador de formato y xx es el especificador de precisión. El especificador
de formato controla el tipo de formato aplicado al valor numérico, mientras que el
especificador de precisión controla el número de dígitos significativos o posiciones
decimales del resultado.

Siempre empezamos de cero es decir si tenemos 3 datos que deseamos imprimir


deberemos escribir {0} {1} {2} notemos que aquí no especificamos ningún formato
por default se aplica el General, si deseamos por ejemplo imprimir el dato dos en
formato de moneda entonces escribiremos {1:C} no importa si la letra C se escribe en
mayúsculas o minúsculas, el resultado de la impresión será el mismo.

A2.3 Apéndice 2: Guía de referencia del lenguaje C#


Carácter Descripción Ejemplos Resultados
C o c Moneda Console.Write("{0:C}", 2.5); $2.50
Console.Write("{0:C}", -2.5); -$2.50
D o d Decimal Console.Write("{0:D5}", 25); 00025
E o e Científico Console.Write("{0:E}", 250000); 2,500000E+005
F o f Punto fijo Console.Write("{0:F2}", 25); 25.00
Console.Write("{0:F0}", 25); 25
G o g General Console.Write("{0:G}", 2.5); 2.5
N o n Número Console.Write("{0:N}", 2500000); 2.500.000,00
X o x Hexadecimal Console.Write("{0:X}", 250); FA
Console.Write("{0:X}", 0xffff); FFFF

Tipos primitivos y sus valores por default

Tipo Valor por default


Numeric (int, long, etc.) 0
bool false
char '\0' (null)
enum 0
reference null

Secuencias de escape

C♯ tiene caracteres denominados secuencias de escape para facilitar la escritura con


el teclado de símbolos que carecen de representación visual. Estos son:

Secuencia de escape Descripción


\a Alerta (timbre)
\b Retroceso
\f Avance de página
\n Nueva línea
\r Retorno de carro
\t Tabulador horizontal
\v Tabulador vertical
\0 Nulo
\' Comilla sencilla
\" Comilla doble
\\ Diagonal invertida

A2.4 Apéndice 2: Guía de referencia del lenguaje C#


Variables

Toda variable se debe declarar antes de ser utilizada. La forma en que se declara una
variable en C♯ es la siguiente:

tipo nombre_variable;

Para asignar un valor a una variable:

nombre_variable = valor

Además de realizarse dentro de una asignación, las conversiones de tipos también


tienen lugar dentro de una expresión, pues en cada operación ambos operandos deben
de ser del mismo tipo. Si la conversión es del tipo implícito se efectúa el siguiente
algoritmo en dicho orden:

1. Si un operando es decimal, el otro operando se transforma a decimal.


2. Si un operando es double, el otro operando se transforma a double.
3. Si un operando es float, el otro operando se transforma a float.
4. Si un operando es ulong, el otro operando se transforma a ulong.
5. Si un operando es long, el otro operando se transforma a long.
6. Si un operando es uint, y si el otro operando es de tipo sbyte, short o int,
los dos se transforman a long.
7. Si un operando es uint, el otro operando se transforma a uint.
8. Si ninguno de los casos anteriores, los dos operandos se transforman a int.

Operadores

C♯ tiene cuatro clases generales de operadores: aritméticos, a nivel de bit,


relacionales y lógicos.

Operadores aritméticos
Operador Significado
+ Suma
- Resta
* Producto
/ División
% Módulo (residuo entero)
++ Incremento
-- Decremento

Operadores relacionales
Operador Significado
== Igual que
!= Distinto que
> Mayor que
< Menor que

A2.5 Apéndice 2: Guía de referencia del lenguaje C#


>= Mayor o igual que
<= Menor o igual que

Operadores lógicos
Operador Significado
^ XOR y de nivel de bits
|| OR de cortocircuito
&& AND de cortocircuito
! NOT

Los operadores aritméticos funcionan igual que en C y C++.


El resultado de los operadores relacionales y lógicos es un valor bool.
Los operadores de cortocircuito evalúan el segundo operando solo cuando es
necesario.
Los operadores a nivel de bit no se pueden aplicar a tipos bool, float, double o
decimal.

Tabla completa de operadores


Categorías Operadores
Aritméticos + - * / %
Lógicos (booleanos y bit a bit) & | ^ ! ~ && || true false
Concatenación de cadenas +
Incremento y decremento ++ --
Desplazamiento << >>
Relacionales == != < > <= >=
Asignación = += -= *= /= %= &= |= ^= <<= >>=
Acceso a miembros .
Indización []
Conversión de tipos Explícita ()
Condicional ?:
Concatenación y eliminación de + -
delegados
Creación de objetos new
Información de tipos is sizeof typeof
Control de excepciones de checked unchecked
desbordamiento
Direccionamiento indirecto y * -> [] &
dirección

Modificadores de acceso
Modificador Descripción
Significa que el miembro es accesible desde fuera de la clase
public que lo define y de la jerarquía de las clases derivadas.
Accesible desde cualquier parte del mismo proyecto, desde otros
A2.6 Apéndice 2: Guía de referencia del lenguaje C#
proyectos que hagan referencia al proyecto, y desde un
ensamblado generado a partir del proyecto.
El miembro no es visible desde fuera de la clase y se puede
protected acceder a él solo desde clases derivadas o dentro de la misma
clase.
No se puede acceder al miembro desde fuera del ámbito de la
clase que lo define. Por lo tanto, ni siquiera las clases
private
derivadas tienen acceso a estos miembros. Es lo considerado por
defecto.
El miembro es visible soló desde la unidad de compilación
internal
actual. El modificador internal crea un híbrido de acceso
public y protected dependiendo de donde resida el código.
Es decir sólo puede ser accedido desde código perteneciente al
ensamblado en que se ha definido.
protected Sólo puede ser accedido desde código perteneciente al
internal ensamblado en que se ha definido o desde clases que deriven de
la clase donde se ha definido.

Precedencia de operadores
En todos los lenguajes los distintos operadores tienen una precedencia en una
expresión, o sea, un orden de prioridad para ser tratados por el compilador cuando
analiza una línea con múltiples operadores.

Tipo de operador Operadores


Primario (a), a.b, f(a), a[i], a++, a--, new, typeof,
sizeof, checked, unchecked
Unitario +,-, !, ~, ++a, --a, (cast)a
Multiplicativo *, /, %
Aditivo +, -
De desplazamiento <<, >>
Relacional <, >, <=, >=, is
De igualdad ==
AND a nivel de bits &
XOR a nivel de bits ^
OR nivel de bits |
AND condicional &&
OR condicional ||
Condicional ?:
De asignación =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=

Clase System.Array

Método o Propiedad Descripción


IsFixedSize Propiedad que indica si el arreglo es de tamaño
fijo

A2.7 Apéndice 2: Guía de referencia del lenguaje C#


Length Propiedad que retorna el tamaño del arreglo
Rank Propiedad que retorna el número de dimensiones del
arreglo
Clear( ) Establece el valor de un rango de elementos de un
arreglo en 0
Copy( ) Copia una sección de un arreglo a otro arreglo
CopyTo( ) Copia todos los elementos de un arreglo a otro
IndexOf() Retorna el índice de la primera ocurrencia de un
valor en un arreglo unidimensional
LastIndexOf( ) Retorna el índice de la última ocurrencia de un
valor en un arreglo unidimensional
Reverse() Invierte el orden de los elementos en un arreglo
unidimensional
Sort ( ) Ordena los elementos (que deben implementar
IComparable) de un arreglo unidimensional usando el
algoritmo Quicksort
GetLength() Regresa el número de elementos de la dimensión
especificada de un arreglo.
GetLowerBound() Obtiene el índice del primer elemento del arreglo o
límite inferior de la dimensión especificada de un
array
GetUpperBound() Proporciona el índice del último elemento del
arreglo o límite superior de la dimensión
especificada de un array
Exists() Determina si el arreglo especificado contiene
elementos que coinciden con las condiciones
definidas.
Find() Busca un elemento que coincida con las condiciones
definidas y devuelve la primera aparición en todo
el arreglo.
FindAll() Encuentra todos los elementos del arreglo que
cumplen con la condición.
FindIndex() Regresa el índice del primer elemento que cumple
con la condición.
FindLast() Regresa el último elemento que cumple con la
condición.
FindLastIndex() Regresa el índice del último elemento que cumple
con la condición.
Remove() Elimina el primer elemento que se pasa como
parámetro.
RemoveAt() Elimina el elemento de la posición especificada
RemoveRange() Elimina un rango de elementos
RemoveAll() Elimina todos los elementos que cumplen con la
condición

A2.8 Apéndice 2: Guía de referencia del lenguaje C#


Clase System.String

Método Descripción

static string Devuelve una copia de str.


Copy(string str)
int CompareTo(string Devuelve menor que cero si la cadena que llama
str) es menor que str, mayor que cero si la cadena
que llama es mayor que str, y cero si las
cadenas son iguales.
int IndexOf(string Busca en la cadena que llama la subcadena
str) especificada por str.
Devuelve el índice de la primera coincidencia,
o -1 en caso de error.
int Busca en la cadena que llama la subcadena
LastIndexOf(string especificada por str. Devuelve el índice de la
str) última coincidencia, o -1 en caso de error.
string ToLower Devuelve una versión en minúsculas de la
cadena que llama.
string ToUpper Devuelve una versión en mayúsculas de la
cadena que llama.

Excepciones más comunes.


En el espacio de nombres System de la BCL hay predefinidas múltiples excepciones
derivadas de System.Exception que se corresponden con los errores más comunes
que pueden surgir durante la ejecución de una aplicación. En la siguiente tabla se listan
algunas:

Tipo de excepción Causa que produce la excepción


FormatException Se produce cuando el formato de un argumento no
cumple las especificaciones de los parámetros del
método invocado.
DivideByZeroException Cuando se divide entre cero
IndexOutOfRangeException Se genera cuando se intenta tener acceso a un
elemento de un arreglo con un índice que está fuera
de los límites del arreglo.
OverflowException Desbordamiento dentro de contexto donde se ha de
comprobar los desbordamientos (expresión constante,
instrucción checked, operación checked u opción del
compilador /checked)
ArgumentException Pasado argumento no válido (base de excepciones de
argumentos)

A2.9 Apéndice 2: Guía de referencia del lenguaje C#


ArgumentNullException Pasado argumento nulo
ArgumentOutOfRangeException Pasado argumento fuera de rango
ArrayTypeMistmatchException Asignación a tabla de elemento que no es de su tipo
COMException Excepción de objeto COM
InvalidCastException Conversión explícita entre tipos no válida
InvalidOperationException Operación inválida en estado actual del objeto
InteropException Base de excepciones producidas en comunicación con
código inseguro
NullReferenceException Acceso a miembro de objeto que vale null
OutOfMemoryException Falta de memoria para crear un objeto con new
SEHException Excepción SHE del API Win32
StackOverflowException Desbordamiento de la pila, generalmente debido a un
excesivo número de llamadas recurrentes.
TypeInizializationException Ha ocurrido alguna excepción al inicializar los
campos estáticos o el constructor estático de un
tipo. En InnerException se indica cuál es.

Estructuras de Control
La instrucción if-else es básicamente igual que en C, C++ y Java.

La diferencia de la instrucción switch con la versión de C, C++ y Java es que todo


cuerpo perteneciente a un case debe de toparse con un break o un goto antes de
toparse con otro case, a menos que dicho cuerpo esté vacío.

La instrucción for es básicamente igual que en C, C++ y Java.

La instrucción while es básicamente igual que en C, C++ y Java.

La instrucción do-while es básicamente igual que en C, C++ y Java.

La instrucción foreach realiza un ciclo a través de los elementos de una colección


(grupo de objetos). El formato de esta instrucción es: foreach(tipo variable in
coleccion) instruccion;. En este ciclo se recorre la colección y la variable recibe un
respectivo elemento de dicha colección en cada iteración.

Al igual que en C y C++, la instrucción break permite forzar la salida de un ciclo


omitiendo el código restante en el cuerpo del ciclo.

Al igual que en C y C++, la instrucción continue permite forzar la repetición temprana


de un ciclo omitiendo el código restante en el cuerpo del ciclo.

La instrucción return es básicamente igual que en C, C++. Se utiliza para devolver un


valor y salir de un método.

La instrucción goto se sigue utilizando en C♯ a pesar de toda la polémica que esto


conlleva.

A2.10 Apéndice 2: Guía de referencia del lenguaje C#


Apéndice 3

Código Fuente de los ejercicios del Capítulo 3:


Métodos, Arreglos y Estructuras

Tabla de Contenido
Metodo.cs ....................................................................................................................................................................................... A3.2
Sobrecarga1.cs ............................................................................................................................................................................ A3.3
Sobrecarga2.cs ............................................................................................................................................................................ A3.4
Sobrecarga3.cs ............................................................................................................................................................................ A3.5
Valor1.cs ......................................................................................................................................................................................... A3.6
Referencia1.cs.............................................................................................................................................................................. A3.7
Arreglo1.cs .................................................................................................................................................................................... A3.8
Histograma.cs .............................................................................................................................................................................. A3.9
Ordenar.cs....................................................................................................................................................................................A3.10
MetodosArray.cs ......................................................................................................................................................................A3.12
Estadistica1.cs ...........................................................................................................................................................................A3.14
Estadistica2.cs ...........................................................................................................................................................................A3.15
Estadistica3.cs ...........................................................................................................................................................................A3.17
Foreach1.cs .................................................................................................................................................................................A3.19
Matriz1.cs.....................................................................................................................................................................................A3.20
Matriz2.cs.....................................................................................................................................................................................A3.21
Matriz3.cs.....................................................................................................................................................................................A3.22
Estructura1.cs ............................................................................................................................................................................A3.24
Estructura2.cs ............................................................................................................................................................................A3.25
Estructura3.cs ............................................................................................................................................................................A3.27

A3.1 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Metodo.cs
/* Nombre del programa: Metodo.cs
Programa que muestra la creación y el llamado de métodos en una misma
clase
Programa con el método definido en la misma clase Program y
simplemente con la instrucción new Program().MisDatos(); se llama al
método en el Main(); el método debe estar definido dentro de una
clase en el ejemplo esta definido abajo del Main() podría ir en la
parte superior del Main, pero en ambos casos dentro de la clase
Program, el resultado es el mismo*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace metodo_MisDatos
{
class Program
{
static void Main(string[] args)
{
new Program().MisDatos();
}
public void MisDatos() //método MisDatos()
{
Console.WriteLine("UACM IZTAPAPALAPA");
Console.WriteLine("PROGRAMACION ORIENTADA A OBJETOS EN C#");
Console.WriteLine("Armando Valera Paulino");
Console.WriteLine("mail: avalera@hotmail.com");
Console.WriteLine(DateTime.Now);
Console.WriteLine("\n");
Console.ReadLine();
}
}
}

Ejecución:

A3.2 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Sobrecarga1.cs
/* Nombre del programa: Sobrecarga1.cs
Programa que muestra la sobrecarga de métodos con el mismo número de
argumentos pero de diferente tipo: int, long, doble */

using System;
using System.Collections.Generic;
using System.Text;
namespace SobrecargaMetodos
{
public class Principal
{
private int Triple(int val)
{ return 3 * val; }

private long Triple(long val)


{ return 3 * val; }

private double Triple(double val)


{ return 3 * val; }

public void SobreCarga()


{
int x = 3;
int y = Triple(x);
System.Console.WriteLine("x={0} y={1}", x, y);

long lx = 5;
long ly = Triple(lx);
System.Console.WriteLine("lx={0} ly={1}", lx, ly);

double dx = 2.5;
double dy = Triple(dx);
System.Console.WriteLine("dx={0} dy={1}", dx, dy);
}
static void Main()
{
Principal p = new Principal();
p.SobreCarga();
System.Console.ReadLine();
}
}
}

Ejecución:

A3.3 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Sobrecarga2.cs
/* Nombre del programa: Sobrecarga2.cs
Programa que muestra la sobrecarga de métodos con dos argumentos,
pero de diferente tipo: char, int, doble */
using System;
using System.Collections.Generic;
using System.Text;

namespace SobrecargaMetodos
{
public class Principal
{
static void Main()
{
Principal p = new Principal();
Console.WriteLine("El número mayor es: {0}", p.mayor(3,4));
Console.WriteLine("El número mayor es: {0}", p.mayor(2.4,5.1));
Console.WriteLine("La letra mayor es: {0}", p.mayor('v','z'));
System.Console.ReadLine();
}

#region
int mayor(int a, int b) {
if(a > b) return a; else return b; }

char mayor(char a, char b) {


if(a > b) return a; else return b; }

double mayor(double a, double b) {


if(a > b) return a; else return b; }
#endregion

}
}

Ejecución:

A3.4 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Sobrecarga3.cs
/* Nombre del programa: Sobrecarga3.cs
Programa que muestra la sobrecarga de métodos con diferente
número de argumentos, pero del mismo tipo*/

using System;
public class Principal
{
static void Main()
{
Principal p = new Principal();

Console.WriteLine("El número mayor es: {0}", p.mayor(3,4));


Console.WriteLine("El número mayor es: {0}",
p.mayor(p.mayor(22,76),59));
Console.WriteLine("La número mayor es: {0}",
p.mayor(p.mayor(10,45),p.mayor(90,88)));
System.Console.ReadLine();
}

#region
int mayor(int a, int b) {
if(a > b) return a; else return b; }

int mayor(int a, int b, int c) {


return mayor(mayor(a, b), c); }

int mayor(int a, int b, int c, int d) {


return mayor(mayor(a, b), mayor(c, d)); }
#endregion
}

Ejecución:

A3.5 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Valor1.cs
/* Nombre del programa: Valor1.cs
Programa que muestra el paso de parámetros por valor */

using System;

class porValor
{
static void Main()
{
int n = 5;
Console.WriteLine("En valor antes de llamar al método: {0}", n);

Cuadrado(n); // Pasando la variable por valor


Console.WriteLine("El valor después de llamar al método: {0}", n);
Console.ReadLine();
}

static void Cuadrado(int x)


// El parámetro x es pasado por valor
// Cambios a x no afectan el valor original de x
{
x *= x;
Console.WriteLine("El valor dentro del método: {0}", x);
}

Ejecución:

A3.6 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Referencia1.cs
/* Nombre del programa: Referencia1.cs
Programa que muestra el paso de parámetros por referencia */
using System;

class porValor
{
static void Main()
{
int n = 5;
Console.WriteLine("En valor antes de llamar al método: {0}", n);

Cuadrado(ref n); // Pasando la variable por valor


Console.WriteLine("El valor después de llamar al método: {0}", n);
Console.ReadLine();
}

static void Cuadrado(ref int x)


// El parámetro x es pasado por referencia
// Los cambios a x afectarán el valor original de x.
{
x *= x;
Console.WriteLine("El valor dentro del método: {0}", x);
}

Ejecución:

A3.7 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Arreglo1.cs
/*Programa Arreglo1.cs
* Muestra la declaración e inicializanción de un arreglo
unidimensional así como la propiedad Random para asigna números
aleatorios a un arreglo*/

using System;
class Arreglo1
{
static void Main( string[] args )
{
int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] b = new int[10];
int total = 0;
//Suma los elementos del arreglo a y se los asigna a total
for ( int i = 0; i<a.Length; i++)
total += a[ i ];
Console.WriteLine( "Suma de todos los elementos del arreglo a: "
+ total);

//Asigna valores aleatoriamente entre 1 y 99 al arreglo b,


//e imprime sus elementos
Random objeto = new Random();
Console.WriteLine("\nImprime todos los elementos de arreglo b:");
for ( int i = 0; i<10; i++)
{b[i]=objeto.Next(1,99);
Console.WriteLine(b[i]);}

Console.ReadLine();

} // fin de Main
} // Arreglo1

Ejecución:

A3.8 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Histograma.cs
/*Nombre del programa: Histrograma.cs
Crea un histograma en base a barras de asteriscos a partir de unos datos*/

using System;
class Histograma
{
// metodo Main
static void Main( string[] args )
{
int[] x = { 17, 4, 16, 9, 10, 7, 13, 6, 19, 2 };
string salida = "Elemento\tValor\tHistograma\n";
// construir salida
for ( int i = 0; i < x.Length; i++ )
{
salida += "\n" + i + "\t\t" + x[ i ] + "\t";
for ( int j = 1; j <= x[ i ]; j++ ) // imprimir una barra
salida += "*";
}
Console.WriteLine( salida);
Console.ReadLine( );
} // fin Main
} // fin de la clase Histograma

Ejecución:

A3.9 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Ordenar.cs
/*Nombre del programa: Ordenar.cs
* Muestra el uso de Array.Sort para ordenar un arreglo*/
using System;
class Ordenar
{
static void Main(string[] args)
{
int[] valores = {12,5,9,19,4,8,11,3};
Array.Sort(valores);

for(int i=0; i<valores.Length; i++)


{
Console.Write( valores[i]+ " ");
}
Console.ReadLine();
} //fin del Main()
}//fin de la clase Ordenar

/* foreach(int i in valores)
{
Console.Write(i + " ");
}

A3.10 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


*/

Ejecución:

A3.11 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


MetodosArray.cs
/*Nombre del programa: MetodosArray.cs
* Muestra el uso de varios métodos para manipular los arreglos*/

using System;
class ManipulacionArreglos
{
static void Main(string[] args)
{
int[] a= {12,5,9,19,4,8,11,5,3};
int [] b= new int[a.Length];
int [] c= new int[a.Length];

Console.WriteLine("Imprime los elementos del arreglo b:");


Array.Copy(a,b,a.Length);
for(int i=0; i<b.Length; i++)
{ Console.Write( b[i]+ " ");}

Console.WriteLine("\n\nImprime los elementos del arreglo c:");


Array.Reverse(a);
Array.Copy(a,c,a.Length);
for(int i=0; i<b.Length; i++)
{ Console.Write( c[i]+ " ");}

int pos1=Array.IndexOf(c,5);
int pos2=Array.LastIndexOf(c,5);

Console.WriteLine("\n\nBusca el número 5 en el arreglo a:");


Console.WriteLine("El primer 5 se encuentra en la posición: {0}", pos1);
Console.WriteLine("El último 5 se encuentra en la posición:" + pos2);

Console.WriteLine("\nLa dimensión del del arreglo a es:" + a.Rank);


Console.WriteLine("\n¿Es de tamaño fijo el arreglo a?" + a.IsFixedSize);

Console.WriteLine("\nEstablece 5 elementos del arreglo a en cero");


Array.Clear(a,2,5);//apartir del elemento 2 coloca 5 elementos en cero
//Array.Clear(a,0,a.Length); para establecer todos los elementos en cero
for(int i=0; i<a.Length; i++)
{ Console.Write( a[i]+ " ");}

Console.ReadLine();
} //fin del Main()
}//fin de la clase ManipulacionArreglos

Ejecución:

A3.12 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


A3.13 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3
Estadistica1.cs
/*Nombre del programa:Estadistica1.cs
* apartir de un arreglo de calificaciones de los estudiantes calcula la
frecuencia de cada calificación de todos los estudiantes. * */

using System;
class Estudiantes
{ //método principal Main()
static void Main( string[] args )
{
int[] calificaciones = { 9, 2, 5, 3, 4, 8, 2, 9, 7, 8, 10, 1,
6, 3, 8, 6, 4, 10, 3, 8, 2, 7, 7, 5, 7, 7, 8, 6, 7,
5, 7, 7, 5, 6, 7, 5, 6, 4, 8, 6, 7, 10, 5, 10};

int[] frecuencia = new int[11];


string salida = "";

// incrementar la frecuecia de para cada respuesta


for ( int j = 0; j < calificaciones.Length; j++ )
++frecuencia[calificaciones[j]];

salida += "Puntaje\t Frecuencia\n";

// resultados
for ( int puntaje = 1; puntaje < frecuencia.Length; puntaje++ )
salida += puntaje + "\t\t" + frecuencia[ puntaje ] + "\n";

Console.WriteLine( salida);
Console.ReadLine();

} // fin Main
} // fin de la clase EncuestaEstudiantes

Ejecución:

A3.14 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Estadistica2.cs
/*Nombre del programa:Estadistica2.cs
* apartir de un arreglo de calificaciones de los estudiantes calcula
* la frecuencia de cada calificación de todos los estudiantes.
* Imprime el numero total de estudiantes y determina que calificación
* se repite mas veces*/

using System;
class Estudiantes
{
// metodo Main
static void Main( string[] args )
{
int[] calificaciones = { 9, 2, 5, 3, 4, 8, 2, 9, 7, 8, 10, 1,
6, 3, 8, 6, 4, 10, 3, 8, 2, 7, 7, 5, 7, 7, 8, 6, 7,
5, 7, 7, 5, 6, 7, 5, 6, 4, 8, 6, 7, 10, 5, 10};

int[] frecuencia = new int[11];


string salida = "";

// incrementar la frecuecia de para cada respuesta


for ( int j = 0; j < calificaciones.Length; j++ )
++frecuencia[calificaciones[j]];

salida += "Puntaje\t Frecuencia\n";

// resultados
for ( int puntaje = 1; puntaje < frecuencia.Length; puntaje++ )
salida += puntaje + "\t\t" + frecuencia[ puntaje ] + "\n";

Console.WriteLine( salida);

Console.WriteLine( "Numero total de estudiantes: " +


calificaciones.Length);

int indice=0; indice=maximo(frecuencia, indice);


Console.WriteLine( "La calificación que se repite mas es: " +indice);
Console.WriteLine( "La cual se repite: " +frecuencia[indice] + "
veces");

Console.ReadLine();

} // fin Main

public static int maximo(int []a, int z)


{

A3.15 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


int max=0;
for(int i=1; i<a.Length; i++)
if (max<a[i])
{max=a[i]; z=i;}

return z;
}
} // fin de la clase EncuestaEstudiantes

Ejecución:

A3.16 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Estadistica3.cs
/*Nombre del programa:Estadistica3.cs
* apartir de un arreglo de calificaciones de los estudiantes calcula la
frecuencia de cada calificación de todos los estudiantes. Imprime el
número total de estudiantes y determina que calificación se repite más
veces utiliza Array.IndexOf*/

using System;
class Estudiantes
{
public static int maximo(int []a)
{
int max=0;
for(int i=1; i<a.Length; i++)
if (max<a[i])
max=a[i];
return max;
}

// metodo Main
static void Main( string[] args )
{

int[] calificaciones = { 9, 2, 5, 3, 4, 8, 2, 9, 7, 8, 10, 1,


6, 3, 8, 6, 4, 10, 3, 8, 2, 7, 7, 5, 7, 7, 8, 6, 7,
5, 7, 7, 5, 6, 7, 5, 6, 4, 8, 6, 7, 10, 5, 10};

int[] frecuencia = new int[11];


string salida = "";

// incrementar la frecuecia de para cada respuesta


for ( int j = 0; j < calificaciones.Length; j++ )
++frecuencia[calificaciones[j]];

salida += "Puntaje\t Frecuencia\n";

// resultados
for ( int puntaje = 1; puntaje < frecuencia.Length; puntaje++ )
salida += puntaje + "\t\t" + frecuencia[ puntaje ] + "\n";

Console.WriteLine( salida);

Console.WriteLine( "Numero total de estudiantes: " +


calificaciones.Length);

Console.WriteLine( "La calificación que se repite mas es: "+


Array.IndexOf(frecuencia,maximo(frecuencia)));
Console.WriteLine( "La cual se repite: " + maximo(frecuencia) + "

A3.17 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


veces");

Console.ReadLine();
} // fin Main
} // fin de la clase EncuestaEstudiantes

Ejecución:

A3.18 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Foreach1.cs
/*Nombre del programa:Foreach1.cs
* Programa que utiliza GetLowerBound y GetUpperBound dentro de un ciclo
* for para recorrer los elementos del arreglo, por último se imprime el
* el arreglo utilizando foreach
*/
using System;
class Ciclos
{
// metodo Main
static void Main( string[] args )
{ int[] calificaciones = { 9, 2, 5, 3 };

Console.WriteLine("Impresión del arreglo con for");


for (int i=0; i<calificaciones.Length; i++)
Console.WriteLine(calificaciones[i]);

Console.WriteLine("\nImpresión del arreglo con for y


GetLowerBoud,GetUpperBound");
for (int j=calificaciones.GetLowerBound(0);
j<=calificaciones.GetUpperBound(0);j++)
Console.WriteLine(calificaciones[j]);

Console.WriteLine("\nImpresión del arreglo utilizando foreach");


foreach (int k in calificaciones)
Console.WriteLine(k);

Console.ReadLine();
} // fin Main
} // fin de la clase Ciclos

Ejecución:

A3.19 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Matriz1.cs
/*Matriz1.cs:
El programa captura e imprime seis materias que cursa un alumno en un
semestre*/
using System;
class Bidimensional
{
static void Main()
{
string [ , ] materias = new string[3,2] ;

//Ciclo doble for anidado para capturar el nombre de las materias


Console.WriteLine( "Captura el nombre de seis materias que deseas inscribir:");
for(int i=0 ; i < 3 ; i++ ) // Controla la fila.
for(int j=0 ; j < 2 ; j++ ) // Controla la columna.
materias[ i , j ] = Console.ReadLine( );

// Imprime el nombre de las materias


Console.WriteLine( "\nVerifica que el nombre de las materias sea correcto:");
for (int i=0 ; i < 3 ; i++ ) // Controla la fila.
for(int j=0 ; j < 2 ; j++ ) // Controla la columna.
Console.WriteLine( materias[ i , j ] );

Console.ReadLine();
}
}

Ejecución:

A3.20 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Matriz2.cs
/* Nombre del programa: Matriz2.cs
* Declara e inicializa un arreglo de cuatro filas y tres columnas
* posteriormente imprime cada elemento del arreglo rectangular*/

using System;
public class Matrices
{
static void Main( )
{
const int filas = 4;
const int columnas = 3;

// Declara e inicializa un arreglo de 4x3


int[,] rectangular ={ {10,20,30}, {40,50,60}, {-4,-5,-6}, {1,2,3}};

for (int i = 0; i < filas; i++)


{ for (int j = 0; j < columnas; j++)
Console.WriteLine("Elemento[{0},{1}] = {2}", i, j, rectangular[i, j]);
Console.ReadLine();
}
}
}

Ejecución:

A3.21 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Matriz3.cs
/*Nombre del programa: Matriz3.c
* Suma el contenido de dos matrices y despliega el resultado*/

using System;
class SumaMatrices
{ public static void Main( )

{ int f, c;
Console.Write("Dame el numero de filas de la matriz:" );
f= Convert.ToInt32(Console.ReadLine( ));
Console.Write("Dame el numero de columnas de la matriz:" );
c= Convert.ToInt32(Console.ReadLine( ));

int [ , ] A = new int [f,c] ; int [ , ] B = new int [f,c] ;


int [ , ] R = new int [f,c] ;

int i, j ;
Console.WriteLine("\nTeclea los valores de la matria A: " );
for( i = 0 ; i < f ; i++ )
for( j = 0 ; j < c ; j++)
{Console.Write("A[{0},{1}]=", i,j);
A[i,j] = Convert.ToInt32(Console.ReadLine( ));}

Console.WriteLine("\nTeclea los valores de la matria B: " );


for( i = 0 ; i < f ; i++ )
for( j = 0 ; j < c ; j++)
{Console.Write("B[{0},{1}]=", i,j);
B[ i , j ] = Convert.ToInt32(Console.ReadLine( ));}

// Suma e Imprime la matriz resultante.


Console.WriteLine("\nLa suma de la matriz Resultante A+B es:");
for( i = 0 ; i < f ; i++ )
{ for( j = 0 ; j < c ; j++)
{ R[ i , j ] = A[ i , j ] + B[ i , j ];
Console.Write(" " + R[ i , j ] ) ; }
Console.WriteLine( ) ;
Console.ReadLine( ) ; }
}
}

A3.22 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Ejecución:

A3.23 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Estructura1.cs
//Nombre del programa: Estructua1.cs
//Declaración y acceso a una estructura
using System;

struct Entero
{
private int val;

public int Valor


{
get { return val; }
set { val = value; }
}

public int Leer()


{
return int.Parse(Console.ReadLine());
}
}

class Program
{
static void Main()
{
Entero Natural = new Entero();

Console.Write("Ingresa un número natural: ");


// Accesando a la propiedad de la estructura
Natural.Valor =
// Llamando al método de la estructura.
Natural.Leer();

Console.WriteLine("El valor ingresado fue: {0}", Natural.Valor);


Console.ReadLine();
}
}

Ejecución:

A3.24 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Estructura2.cs
//Nombre del programa: Estructura2.cs
//Calcula el área y perímetro de un rectángulo utilizando estructuras

using System;
public struct Real
{
private double val;
public double Valor
{ get { return val; }
set { val = value; }
}

public double Leer()


{
return double.Parse(Console.ReadLine());
}
}

public struct Rectangulo


{
Real alt; Real anc;

public Real Alto


{ get { return alt; }
set { alt = value; }
}

public Real Ancho


{get { return anc; }
set { anc = value; }
}

public void CrearRectangulo()


{
Real rec = new Real();

Console.WriteLine("Teclea las dimensiones del Rectángulo");


Console.Write("Ingresa la Altura: ");
alt.Valor = rec.Leer();
Console.Write("Ingresa el Ancho: ");
anc.Valor = rec.Leer();
}
}

public class Program


{

A3.25 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


static void Main()
{
var Rect = new Rectangulo();

Rect.CrearRectangulo();
Console.WriteLine();

Console.WriteLine("Características del Rectángulo:");


Console.WriteLine("Alto: {0}", Rect.Alto.Valor);
Console.WriteLine("Ancho: {0}", Rect.Ancho.Valor);
Console.WriteLine("Perímetro: {0}",
(Rect.Alto.Valor + Rect.Ancho.Valor) * 2);
Console.WriteLine("Área: {0}",
Rect.Alto.Valor * Rect.Ancho.Valor);
Console.ReadLine();
}
}

Ejecución:

A3.26 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Estructura3.cs
//Nombre del programa: Estructura3.cs
//Comparación entre clases y estructuras
using System;

public struct Localizacion


{ public int X { get; set; }
public int Y { get; set; }

public override string ToString( )


{
return (String.Format("{0}, {1}", X, Y));
}
}

public class Principal


{
public void MiFunc(Localizacion loc)
{
loc.X = 20; loc.Y = 10;
Console.WriteLine("En MiFunc loc: {0}", loc);
}

static void Main( )


{Localizacion loc1 = new Localizacion( );
loc1.X = 44;
loc1.Y = 72;
Console.WriteLine("Loc1 Localización: {0}", loc1);

Principal p = new Principal( );


p.MiFunc(loc1);
Console.WriteLine("Loc1 Localización: {0}", loc1);
Console.ReadLine();
}
}

Ejecución:

A3.27 Apéndice 3: Código Fuente de los ejercicios del Capítulo 3


Apéndice 4

Código Fuente de los ejercicios del Capítulo 4:


Programación Orientada a Objetos

Tabla de Contenido
Clase1.cs ................................................................................................................................................................................ A4.2
Constructor1.cs .................................................................................................................................................................. A4.3
Constructor2.cs .................................................................................................................................................................. A4.4
Constructor3.cs .................................................................................................................................................................. A4.5
Herencia1.cs......................................................................................................................................................................... A4.6
Herencia2.cs......................................................................................................................................................................... A4.8
ClaseAbstracta1.cs ............................................................................................................................................................ A4.9
Polimorfismo1.cs ............................................................................................................................................................ A4.10
DestructoresHerencia.cs.............................................................................................................................................. A4.11
Encapsulacion1.cs .......................................................................................................................................................... A4.12
Encapsulacion2.cs .......................................................................................................................................................... A4.13
Propiedad1.cs................................................................................................................................................................... A4.15
Global1.cs ........................................................................................................................................................................... A4.16

A4.1 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Clase1.cs
/* Nombre del programa: Clase1.cs
Programa ejemplifica la creación de clases */
#region Usando Directivas
using System;
using System.Collections.Generic;
using System.Text;
#endregion

namespace Clase1
{
public class Hola
{
// Aqui podriamos definir variables privadas
// ........

// Método Publico
public void Saludo( )
{
Console.WriteLine("Hola todo mundo!" );
}
}

public class Principal


{
static void Main( )
{
Hola h = new Hola( );
h.Saludo( );
Console.ReadLine();
}
}
}

Ejecución:

A4.2 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Constructor1.cs
/* Nombre del programa: Constructor1.cs
Programa que muestra la creación y la invocación de un constructor*/
class Constructor1
{
Constructor1(int x)
{
System.Console.Write("Creando objeto Constructor1 con x={0}",x);
}
public static void Main()
{
Constructor1 c = new Constructor1(44);
System.Console.ReadLine();
}
}

Ejecución:

A4.3 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Constructor2.cs
/* Nombre del programa: Constructor2.cs
Programa que muestra la creación y la invocación de un constructor y
un método*/
using System;
namespace Constructores
{
class MainClass
{
public static void Main(string[] args)
{
Console.WriteLine("Hola...!");
Ejemplo1 e1=new Ejemplo1();
e1.datos();
Console.ReadLine();
}
}
}

public class Ejemplo1


{
public Ejemplo1()
{
Console.WriteLine("NOTEN QUE EL CONSTRUCTOR SE EJECUTA POR
DEFAULT");
Console.WriteLine("SOLO ES NECESARIO DECLARAR EN EL MAIN UNA
INSTANCIA");
Console.WriteLine("U OBJETO DE LA CLASE Ejemplo1");
}

public void datos()


{
Console.WriteLine("\n\nUACM Nada Humano me es ajeno...");
Console.WriteLine("Armando Valera Paulino");
Console.WriteLine(DateTime.Now);
}
}

Ejecución:

A4.4 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Constructor3.cs
/* Nombre del programa: Constructor3.cs
Programa que muestra la creación e invocación de dos constructores,
el primero por default y el segundo con un argumento*/

using System;
public class Prueba
{

public Prueba()
{
Console.WriteLine("Constructor por default");
Console.WriteLine("Armando Valera Paulino");
Console.WriteLine(DateTime.Now);
}

public Prueba(int x)
{
Console.WriteLine("\n\nConstructor con un argumento");
Console.Write("Creado objeto Prueba con x={0}",x);
}
}
//observese que a los dos contructores se les da la palabra public
//para que pueda ser accesible, si no se especifica como private
//automaticamente
class Principal
{
public static void Main()
{
Prueba prb1 = new Prueba(); //se invoca al constructor por default
Prueba prb2 = new Prueba(44);//se invoca al constructor con un
argumento
Console.ReadLine();
}
}

Ejecución:

A4.5 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Herencia1.cs
/* Nombre del programa: Herencia1.cs
Este ejemplo muestra el uso de propiedades de instancia, estáticas y
de sólo lectura. Lee el nombre del empleado escrito mediante el
teclado, incrementa el número de empleados numeroEmpleados en una
unidad y muestra el nombre del empleado y su número correspondiente
*/

using System;

class Persona
{
public string Nombre;
// Campo de cada objeto Persona que almacena su nombre
public int Edad;
// Campo de cada objeto Persona que almacena su edad
public string CURP;
// Campo de cada objeto Persona que almacena su CURP

void Cumpleaños()
// Incrementa en uno de edad del objeto Persona
{
Edad++;
}

public Persona (string nombre, int edad, string curp) // Constructor


de Persona
{
Nombre = nombre;
Edad = edad;
CURP = curp;
}

class Trabajador: Persona


{
public int Sueldo;
// Campo de cada objeto Trabajador que almacena cuánto gana

Trabajador(string nombre, int edad, string curp, int sueldo):


base(nombre, edad, curp)
{ // Inicializamos cada Trabajador en base al constructor de
Persona
Sueldo = sueldo;
}

public static void Main()


{

A4.6 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Trabajador t = new Trabajador("Valera Paulino Armando", 35,
"VAPA720910D44HPLLLR07", 17899);
Console.WriteLine ("Nombre="+t.Nombre);
Console.WriteLine ("Edad="+t.Edad);
Console.WriteLine ("CURP="+t.CURP);
Console.WriteLine ("Sueldo="+t.Sueldo);
Console.ReadLine();
}
}

Ejecución:

A4.7 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Herencia2.cs
/* Nombre del programa: Herencia2.cs
Este ejemplo muestra el uso de la clase base y derivada para aplicar
herencia */
using System;

public class Principal


{
static void Main(string[] args)
{
// Creamos un objeto de la clase derivada
ClaseDerivada MiClase = new ClaseDerivada();
// e invocamos a los dos métodos
Console.WriteLine("{0},{1}",MiClase.Saludo(), MiClase.Cubo(4));
Console.ReadLine();
}
}

// Esta clase tiene como base a Object


public class ClaseBase
{
// cuenta con un método que devuelve una cadena
public string Saludo()
{
return "UACM POO";
}
}

// Esta clase está derivada de la anterior


public class ClaseDerivada : ClaseBase
{
// y añade un método para elevar al cubo un número
public int Cubo(int z)
{
return z*z*z;
}
}

Ejecución:

A4.8 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


ClaseAbstracta1.cs
/* Nombre del programa: ClaseAbstracta1.cs
Programa que utiliza clases abstractas, utilizando la propiedad
override */

using System;
using C=System.Console;

public abstract class Figura


{
protected int x, y ;
// Declaración de 2 métodos abstractos.
public abstract double Perimetro( ) ;
public abstract double Area( ) ;

class Rectangulo : Figura


{
double b, a ;
public Rectangulo(int m, int n, double s,double t)
{ x=m; y=n;b = s ;a = t ; }

// Implementación de un método abstracto.


public override double Area( )
{ return b *a ; }

//Implementación de un método abstracto.


public override double Perimetro( )
{ return 2*(b +a) ; }
}

class Principal
{
static void Main()
{
Rectangulo r=new Rectangulo(5,10,20,60);
C.WriteLine("El área del rectángulo de 20x60 es : " + r.Area( ));
C.ReadLine();
}

Ejecución:

A4.9 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Polimorfismo1.cs
/*Polimorfismo1.cs
Ejemplifica el polimorfismo, utilizando clases abstractas */

using C=System.Console;

public abstract class Mamifero


{
public abstract void saluda();
}

class Humano : Mamifero


{public override void saluda()
{ C.WriteLine("Hola !");}
}

class Vaca : Mamifero


{ public override void saluda()
{ C.WriteLine("Muuu !");}
}

class Perro : Mamifero


{ public override void saluda()
{ C.WriteLine("Guau !");}
}

public class Principal


{
public static void Main()
{ Mamifero m=new Humano(); m.saluda();
Vaca v=new Vaca(); v.saluda();
Perro p=new Perro(); p.saluda();
Humano h=new Humano(); h.saluda();
C.ReadLine();
}
} // Fin clase Principal

Ejecución:

A4.10 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


DestructoresHerencia.cs
/* Nombre del programa DestructoresHerencia.cs
Maneja tres destructores de clases encadenadas.*/

using System;
using C = System.Console;

class Primero
{
~ Primero( )
{
C.WriteLine("Se invocó al destructor Primero...");
}
}

class Segundo : Primero


{
~ Segundo( )
{ C.WriteLine("Se invocó al destructor Segundo..."); }
}

class Tercero : Segundo


{
~ Tercero( )
{ C.WriteLine("Se invocó al destructor Tercero..."); }
}

public class Principal


{
public static void Main( )
{
Tercero t = new Tercero ( );
}
}

Ejecución:

A4.11 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Encapsulacion1.cs
/*Encapsulacion1.cs
Programa que ilustra el concepto de encapsulación*/
using System;
using C = System.Console;

class NombreC {
// Definición de variables de instancia.
private string nombre1 ;
private string apellido1 ;
private string apellido2 ;

// Definición de métodos públicos (interfaz pública de la clase).


public void nombre(string nom1, string ape1, string ape2) {
nombre1 = nom1 ;
apellido1 = ape1 ;
apellido2 = ape2 ;
}

public string nombre() {


return nombre_completo() ;
}

// Definición de métodos de soporte.


private string nombre_completo() {
return "Nombre: " + nombre1 + "\r\nPrimer apellido.: " +
apellido1 + "\r\nSegundo apellido.: " + apellido2 ;
}
}
class Principal {
// Procedimiento principal.
public static void Main() {
// Definimos un objetoNombre a partir de la clase NombreC
NombreC objetoNombre;

// Creamos el objeto a partir de la clase NombreC


objetoNombre = new NombreC() ;

// Usamos el método para asignar nombre de cliente.


objetoNombre.nombre("Armando ","Valera","Paulino") ;

// Usamos el método para mostrar el nombre completo.


C.WriteLine(objetoNombre.nombre()) ;
C.ReadLine() ;
}
}

A4.12 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Ejecución:

Encapsulacion2.cs
/*Encapsulacion2.cs
Programa que ilustra el concepto de encapsulación*/

using System;
using C=System.Console;

class Automovil
{
private double velocidad=40;
private string Marca;
private string Modelo;
private string Color;

public void Coche(string marca, string modelo, string color)


{ Marca=marca;
Modelo=modelo;
Color=color;
}

public string Coche() {


return "Marca: " + Marca + "\r\nModelo.: " + Modelo +
"\r\nColor: " + Color ;
}

public double Velocidad


{
get {return velocidad;}
}

public void Acelerar(double cantidad)


{ // Aquí se le dice al motor que aumente las revoluciones
pertinentes, y...
C.WriteLine("Incrementando la velocidad en {0} km/h",
cantidad);
velocidad += cantidad;
}
}

A4.13 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


class Principal
{
public static void Main()
{ Automovil MiCoche=new Automovil();
MiCoche.Coche("Chevrolet", "Optra", "Azul");
C.WriteLine("Los datos de mi coche son:");
C.WriteLine(MiCoche.Coche());
C.WriteLine("La velocidad inicial es de {0}
km/h",MiCoche.Velocidad);
MiCoche.Acelerar(70);
C.WriteLine("La velocidad final es de {0}
km/h",MiCoche.Velocidad);
C.ReadLine();
}
}

Ejecución:

A4.14 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Propiedad1.cs
//Nombre del programa: Propiedad1.cs
using System;

abstract class A
{
public abstract int PropiedadEjemplo
{
set;
get;
}
}

class B:A
{
private int valor=44;

public override int PropiedadEjemplo


{
get
{
Console.WriteLine("Leído {0} de PropiedadEjemplo", valor);
return --valor;
}
set
{
valor = value;
Console.WriteLine("Escrito {0} en PropiedadEjemplo", valor);
}
}
}

class Principal
{
public static void Main()
{ B MiB=new B();
Console.WriteLine("El valor de retorno en get es
{0}",MiB.PropiedadEjemplo);
Console.ReadLine();
}
}

Ejecución:

A4.15 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Global1.cs
/*Global1.cs
* Engloba las características esenciales de la Programación
* Orientada a Objetos */

using System;
using C=System.Console;

class Automovil
{
protected double velocidad=50;
private string Marca;
private string Modelo;
private string Color;

public Automovil(string marca, string modelo, string color)


{ Marca=marca;
Modelo=modelo;
Color=color;
}

public string Datos() {


return DatosAutomovil() ;
}

// Definición de métodos de soporte.


private string DatosAutomovil() {
return "Marca: " + Marca + "\r\nModelo.: " + Modelo +
"\r\nColor: " + Color ;
}

public double Velocidad


{
get {return velocidad;}
}

public virtual void Acelerar(double cantidad)


{ // Aquí se le dice al motor que aumente las revoluciones
pertinentes, y...
C.WriteLine("Incrementando la velocidad en {0} km/h",
cantidad);
velocidad += cantidad;
}
}

class AutomovilAvanzado:Automovil
{
public AutomovilAvanzado(string marca, string modelo, string
color):base(marca, modelo, color) {}

A4.16 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


public override void Acelerar(double cantidad)
{
// Aquí se escribe el nuevo mecanismo de aceleración
Console.WriteLine("Accionando el mecanismo avanzado de
aceleración");
Console.WriteLine("Incrementandoo la velocidad en {0} km/h",
cantidad);
velocidad += cantidad;
}
}

class Principal
{
public static void Main()
{ AutomovilAvanzado MiCoche=new
AutomovilAvanzado("Nissan","Sentra","Plata");
C.WriteLine("Los datos de mi coche son:");
C.WriteLine(MiCoche.Datos());
C.WriteLine("La velocidad inicial es de {0} km/h
\n",MiCoche.Velocidad);
MiCoche.Acelerar(90);
C.WriteLine("\nLa velocidad final es de {0}
km/h",MiCoche.Velocidad);
C.ReadLine();
}
}

Ejecución:

A4.17 Apéndice 4: Código fuente de los ejercicios del Capítulo 4


Apéndice 5

Código Fuente de los ejercicios del Capítulo 5:


Windows Forms

Tabla de Contenido
Caja de Mensajes.cs ........................................................................................................................................................... A5.2
CajadeSelección.cs ............................................................................................................................................................. A5.4
VisorImagenes_Enlaces.cs.............................................................................................................................................. A5.6
WebBrowser_Menu.cs ..................................................................................................................................................... A5.7
llamarFormas1.cs .............................................................................................................................................................. A5.8
llamarFormas2.cs .............................................................................................................................................................. A5.9
llamarFormas3.cs .............................................................................................................................................................. A5.9
menuCalendario.cs......................................................................................................................................................... A5.11

A5.1 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


Caja de Mensajes.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CajadeMensajes
{
public partial class Form1 : Form
{

private MessageBoxButtons tipoDeBoton = MessageBoxButtons.OK;


private MessageBoxIcon tipoDeIcono = MessageBoxIcon.Error;

public Form1()
{
InitializeComponent();
}

private void tipoDeBoton_CheckedChanged(object sender, EventArgs e)


{
if (sender == radioButton1)
tipoDeBoton = MessageBoxButtons.OK;
else if (sender == radioButton2)
tipoDeBoton = MessageBoxButtons.OKCancel;
else if (sender == radioButton3)
tipoDeBoton = MessageBoxButtons.YesNo;
else if (sender == radioButton4)
tipoDeBoton = MessageBoxButtons.YesNoCancel;
else if (sender == radioButton5)
tipoDeBoton = MessageBoxButtons.RetryCancel;
else
tipoDeBoton = MessageBoxButtons.AbortRetryIgnore;
}

private void tipoDeIcono_CheckedChanged(object sender, EventArgs e)


{
if (sender == radioButton7) // display error icon
tipoDeIcono = MessageBoxIcon.Information;
else if (sender == radioButton8)
tipoDeIcono = MessageBoxIcon.Exclamation;
else if (sender == radioButton9)
tipoDeIcono = MessageBoxIcon.Question;
else // only one option left--display question mark
tipoDeIcono = MessageBoxIcon.Error;
}

private void groupBox1_Enter(object sender, EventArgs e)


{
}

private void Form1_Load(object sender, EventArgs e)


{

A5.2 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


}

private void groupBox1_Enter_1(object sender, EventArgs e)


{

private void label2_Click(object sender, EventArgs e)


{

private void button1_Click(object sender, EventArgs e)


{
DialogResult result =
MessageBox.Show("Mensaje a desplegar",
"Título de la Ventana",
tipoDeBoton,
tipoDeIcono);
switch (result)
{
case DialogResult.OK: label2.Text = "Seleccionó OK."; break;
case DialogResult.Cancel: label2.Text = "Seleccionó Cancel."; break;
case DialogResult.Yes: label2.Text = "Seleccionó Yes."; break;
case DialogResult.No: label2.Text = "Seleccionó No."; break;
case DialogResult.Ignore: label2.Text = "Seleccionó Ignore."; break;
case DialogResult.Abort: label2.Text = "Seleccionó Abort."; break;
case DialogResult.Retry: label2.Text = "Seleccionó Retry."; break;
}

private void groupBox2_Enter(object sender, EventArgs e)


{

}
}

A5.3 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


CajadeSelección.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CajadeSeleccion
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{

}
//CAMBIOS DE ESTILO
private void Negrita_CheckedChanged(object sender, EventArgs e)
{
this.label1.Font = new Font(this.label1.Font.FontFamily,
this.label1.Font.Size, FontStyle.Bold);
}

private void Italica_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily,
this.label1.Font.Size, this.label1.Font.Style ^ FontStyle.Italic);
}

private void Tachado_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily,
this.label1.Font.Size, this.label1.Font.Style ^ FontStyle.Strikeout);
}

private void Subrayado_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily,
this.label1.Font.Size, this.label1.Font.Style ^ FontStyle.Underline);
}

//CAMBIOS DE TIPO DE FUENTE


private void Consolas_CheckedChanged(object sender, EventArgs e)
{
FontFamily csl = new FontFamily("Consolas");
this.label1.Font = new Font(csl, this.label1.Font.Size,
this.label1.Font.Style);
}

private void Colonna_CheckedChanged(object sender, EventArgs e)


{
FontFamily cln = new FontFamily("Colonna MT");
this.label1.Font = new Font(cln, this.label1.Font.Size,
this.label1.Font.Style);

A5.4 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


}

private void Verdana_CheckedChanged(object sender, EventArgs e)


{
FontFamily vdn = new FontFamily("Verdana");
this.label1.Font = new Font(vdn, this.label1.Font.Size,
this.label1.Font.Style);
}

private void Broadway_CheckedChanged(object sender, EventArgs e)


{
FontFamily bwy = new FontFamily("Broadway");
this.label1.Font = new Font(bwy, this.label1.Font.Size,
this.label1.Font.Style);
}

//CAMBIOS DELTAMAÑO DE LA FUENTE


private void Ocho_CheckedChanged(object sender, EventArgs e)
{
this.label1.Font = new Font(this.label1.Font.FontFamily, 8,
this.label1.Font.Style);
}

private void Doce_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily, 12,
this.label1.Font.Style);
}

private void Dieciseis_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily, 16,
this.label1.Font.Style);
}

private void Veinte_CheckedChanged(object sender, EventArgs e)


{
this.label1.Font = new Font(this.label1.Font.FontFamily, 20,
this.label1.Font.Style);
}
//BOTONES SALIR Y LIMPIAR
private void button1_Click(object sender, EventArgs e)
{
Close();
}

private void button2_Click(object sender, EventArgs e)


{
FontFamily mss = new FontFamily("Microsoft Sans Serif");
this.label1.Font = new Font(mss, 12, FontStyle.Regular);
}

}
}

A5.5 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


VisorImagenes_Enlaces.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace VisordeImagenes
{ public partial class Form1 : Form
{
public Form1()
{ InitializeComponent(); }

private void Form1_Load(object sender, EventArgs e)


{ }

private void button1_Click(object sender, EventArgs e)


{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{// Carga la imagen dentro del cuadro picture box.
pictureBox1.Image= Image.FromFile(openFileDialog1.FileName);
// Muestra el nombre del archivo en el titulo de forma
this.Text = string.Concat("Visor de Imagenes(" +
openFileDialog1.FileName + ")");
}
}

private void button2_Click(object sender, EventArgs e)


{ Close(); }

private void linkLabel1_LinkClicked(object sender,


LinkLabelLinkClickedEventArgs e)
{
linkLabel1.LinkVisited = true;
System.Diagnostics.Process.Start("Calc");
}

private void linkLabel2_LinkClicked(object sender,


LinkLabelLinkClickedEventArgs e)
{
linkLabel2.LinkVisited = true;
System.Diagnostics.Process.Start("IExplore", "http://www.uacm.edu.mx");

private void linkLabel3_LinkClicked(object sender,


LinkLabelLinkClickedEventArgs e)
{
linkLabel3.LinkVisited = true;
System.Diagnostics.Process.Start("C:\\");
}
}
}

A5.6 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


WebBrowser_Menu.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1.SelectedIndex = 0;
webBrowser1.GoHome();
}

private void button1_Click(object sender, EventArgs e)


{
webBrowser1.Navigate(comboBox1.SelectedItem.ToString());
}

private void homeToolStripMenuItem_Click(object sender, EventArgs e)


{ // Opción del Menú Home o Página Principal
webBrowser1.GoHome();
}

private void adelanteToolStripMenuItem_Click(object sender, EventArgs e)


{ // Opción del Menú Adelante
webBrowser1.GoForward();
}

private void atrasToolStripMenuItem_Click(object sender, EventArgs e)


{ // Opción del Menú Atras
webBrowser1.GoBack();
}

private void button2_Click(object sender, EventArgs e)


{
Close();
}
}
}

A5.7 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


llamarFormas1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace llamarFormas
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
Form2 acercaDe = new Form2();
acercaDe.ShowDialog();

private void button2_Click(object sender, EventArgs e)


{
Form3 data = new Form3();
data.Nombre = textBox1.Text;
data.ShowDialog();
label2.Text = "Calle: " + data.Calle;
label3.Text = "Colonia: " + data.Colonia;
label4.Text = "Delegación: " + data.Delegación;
label5.Text = "Código Postal " + data.CódigoPostal;
label6.Text = "Código Postal " + data.Teléfono;
}

}
}

A5.8 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


llamarFormas2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace llamarFormas
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
Close();
}
}
}

llamarFormas3.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace llamarFormas
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}

public string Nombre


{
set
{
label1.Text = value;
}
}
public string Calle
{
get

A5.9 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


{
return textBox1.Text;
}
}
public string Colonia
{
get
{
return textBox2.Text;
}
}
public string Delegación
{
get
{
return textBox3.Text;
}
}
public string CódigoPostal
{
get
{
return textBox4.Text;
}
}
public string Teléfono
{
get
{
return textBox5.Text;
}
}

private void button1_Click(object sender, EventArgs e)


{
Close();
}

}
}

A5.10 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


menuCalendario.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace menuCalendario
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)


{
// Muestra la fecha seleccionada:
MessageBox.Show("Has seleccionado la fecha: " +
dateTimePicker1.Value.Date);
// Muestra la fecha de hoy:
MessageBox.Show("Hoy es: " + DateTime.Now);
}

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)


{

private void Form1_Load(object sender, EventArgs e)


{

private void label1_Click(object sender, EventArgs e)


{

private void label2_Click(object sender, EventArgs e)


{

private void label3_Click(object sender, EventArgs e)


{

private void forToolStripMenuItem_Click(object sender, EventArgs e)


{

private void BorrarColor()

A5.11 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


{
negrToolStripMenuItem.Checked = false;
axToolStripMenuItem.Checked = false;
rToolStripMenuItem.Checked = false;
vToolStripMenuItem.Checked = false;
}

private void negrToolStripMenuItem_Click(object sender, EventArgs e)


{
BorrarColor();
label1.ForeColor = Color.Black;
label2.ForeColor = Color.Black;
label3.ForeColor = Color.Black;
negrToolStripMenuItem.Checked = true;

private void axToolStripMenuItem_Click(object sender, EventArgs e)


{
BorrarColor();
label1.ForeColor = Color.Blue;
label2.ForeColor = Color.Blue;
label3.ForeColor = Color.Blue;
axToolStripMenuItem.Checked = true;

private void rToolStripMenuItem_Click(object sender, EventArgs e)


{

BorrarColor();
label1.ForeColor = Color.Red;
label2.ForeColor = Color.Red;
label3.ForeColor = Color.Red;
rToolStripMenuItem.Checked = true;
}

private void vToolStripMenuItem_Click(object sender, EventArgs e)


{
BorrarColor();
label1.ForeColor = Color.Green;
label2.ForeColor = Color.Green;
label3.ForeColor = Color.Green;
vToolStripMenuItem.Checked = true;

private void BorrarFuente()


{
tToolStripMenuItem.Checked = false;
tToolStripMenuItem1.Checked = false;
cToolStripMenuItem1.Checked = false;
}

private void cToolStripMenuItem1_Click(object sender, EventArgs e)


{
BorrarFuente();
cToolStripMenuItem1.Checked = true;
label1.Font = new Font("Comic Sans MS", 14, label1.Font.Style);
label2.Font = new Font("Comic Sans MS", 14, label2.Font.Style);
label3.Font = new Font("Comic Sans MS", 14, label3.Font.Style);

A5.12 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


}

private void tToolStripMenuItem_Click(object sender, EventArgs e)


{
BorrarFuente();
tToolStripMenuItem.Checked = true;
label1.Font = new Font("Times New Roman", 14, label1.Font.Style);
label2.Font = new Font("Times New Roman", 14, label2.Font.Style);
label3.Font = new Font("Times New Roman", 14, label3.Font.Style);
}

private void tToolStripMenuItem1_Click(object sender, EventArgs e)


{
BorrarFuente();
tToolStripMenuItem1.Checked = true;
label1.Font = new Font("Tahoma", 14, label1.Font.Style);
label2.Font = new Font("Tahoma", 14, label2.Font.Style);
label3.Font = new Font("Tahoma", 14, label3.Font.Style);
}

private void nToolStripMenuItem_Click(object sender, EventArgs e)


{
nToolStripMenuItem.Checked = !nToolStripMenuItem.Checked;
label1.Font = new Font(label1.Font.FontFamily, 14, label1.Font.Style ^
FontStyle.Bold);
label2.Font = new Font(label2.Font.FontFamily, 14, label2.Font.Style ^
FontStyle.Bold);
label3.Font = new Font(label3.Font.FontFamily, 14, label3.Font.Style ^
FontStyle.Bold);
}

private void cToolStripMenuItem2_Click(object sender, EventArgs e)


{
cToolStripMenuItem2.Checked = !cToolStripMenuItem2.Checked;
label1.Font = new Font(label1.Font.FontFamily, 14, label1.Font.Style ^
FontStyle.Italic);
label2.Font = new Font(label2.Font.FontFamily, 14, label2.Font.Style ^
FontStyle.Italic);
label3.Font = new Font(label3.Font.FontFamily, 14, label3.Font.Style ^
FontStyle.Italic);
}

private void sToolStripMenuItem_Click(object sender, EventArgs e)


{
sToolStripMenuItem.Checked = !sToolStripMenuItem.Checked;
label1.Font = new Font(label1.Font.FontFamily, 14, label1.Font.Style ^
FontStyle.Underline);
label2.Font = new Font(label2.Font.FontFamily, 14, label2.Font.Style ^
FontStyle.Underline);
label3.Font = new Font(label3.Font.FontFamily, 14, label3.Font.Style ^
FontStyle.Underline);
}

private void nToolStripMenuItem1_Click(object sender, EventArgs e)


{
BackColor = System.Drawing.Color.Orange; //para color backcolor
}

private void bToolStripMenuItem_Click(object sender, EventArgs e)

A5.13 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


{
BackColor = System.Drawing.Color.Beige;
}

private void mToolStripMenuItem_Click(object sender, EventArgs e)


{
BackColor = System.Drawing.Color.Purple;
}

private void aToolStripMenuItem_Click(object sender, EventArgs e)


{
BackColor = System.Drawing.Color.Yellow;
}

private void rToolStripMenuItem1_Click(object sender, EventArgs e)


{
BackColor = System.Drawing.Color.Pink;
}

private void bToolStripMenuItem1_Click(object sender, EventArgs e)


{
// BackColor = System.Drawing.Color.White;
BackColor = Color.Orange;
WaitSeconds(2.2);
BackColor = Color.Fuchsia;
WaitSeconds(2.2);
BackColor = Color.Beige;
WaitSeconds(2.2);
BackColor = Color.Green;
WaitSeconds(2.2);
BackColor = Color.Gold;
//System.Threading.Thread.Sleep(1000);
//Thread.Sleep(1000);
}

//para cambiar el color de fondo


//cada 2.2 segungos
private static void WaitSeconds(double nSecs)
{
// Esperar los segundos indicados
// Crear la cadena para convertir en TimeSpan
string s = "0.00:00:" + nSecs.ToString().Replace(",", ".");
TimeSpan ts = TimeSpan.Parse(s);
// A¤adirle la diferencia a la hora actual
DateTime t1 = DateTime.Now.Add(ts);
// Esta asignaci¢n solo es necesaria
// si la comprobaci¢n se hace al principio del bucle
DateTime t2 = DateTime.Now;
// Mientras no haya pasado el tiempo indicado
while (t2 < t1)
{
// Un respiro para el sitema
System.Windows.Forms.Application.DoEvents();
// Asignar la hora actual
t2 = DateTime.Now;
}
}

private void saToolStripMenuItem_Click(object sender, EventArgs e)

A5.14 Apéndice 5: Código fuente de los ejercicios del Capítulo 5


{
Close();
}

private void iToolStripMenuItem_Click(object sender, EventArgs e)


{
MessageBox.Show("avalera@hotmail.com");
}

}
}

//Otra manera diferente, para cambiar el color con FromArgb


private void azulToolStripMenuItem_Click(object sender, EventArgs e)
{
BorrarColor();
label1.ForeColor = Color.FromArgb(255,0,0); //Valor debe estar entre 0 y 255
label2.ForeColor = Color.FromArgb(0,255,0);
label3.ForeColor = Color.FromArgb(0,0,255);
label4.ForeColor = Color.Black;
label5.ForeColor = Color.Black;
label6.ForeColor = Color.Black;
azulToolStripMenuItem.Checked = true;
}

A5.15 Apéndice 5: Código fuente de los ejercicios del Capítulo 5

También podría gustarte