100% encontró este documento útil (3 votos)
372 vistas25 páginas

Apunte Programación en C#

Este documento presenta apuntes sobre C#. Explica conceptos como variables y tipos de datos básicos, instrucciones como if, switch, while y for, funciones, arrays, cadenas, registros, listas, pilas, colas y ficheros. Describe cómo trabajar con estos elementos en C# para desarrollar aplicaciones.

Cargado por

Michael Vreys
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
100% encontró este documento útil (3 votos)
372 vistas25 páginas

Apunte Programación en C#

Este documento presenta apuntes sobre C#. Explica conceptos como variables y tipos de datos básicos, instrucciones como if, switch, while y for, funciones, arrays, cadenas, registros, listas, pilas, colas y ficheros. Describe cómo trabajar con estos elementos en C# para desarrollar aplicaciones.

Cargado por

Michael Vreys
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 25

Apuntes

de C#
Apuntes de C# 2

Apuntes de C#

Contenido
Variables y Tipos de Datos ............................................................................................................ 3
Tipos de datos básicos .................................................................................................................. 3
Instrucciones ................................................................................................................................. 4
Concepto de instrucción ........................................................................................................... 4
Instrucciones básicas................................................................................................................. 4
Definiciones de variables locales........................................................................................... 4
Asignaciones .......................................................................................................................... 5
Instrucciones condicionales ...................................................................................................... 5
Instrucción if .......................................................................................................................... 5
Instrucción switch ................................................................................................................. 5
Instrucciones iterativas ............................................................................................................. 6
Instrucción while ................................................................................................................... 6
Instrucción do...while ............................................................................................................ 6
Instrucción for ....................................................................................................................... 7
Instrucción foreach................................................................................................................ 7
Funciones ...................................................................................................................................... 8
Concepto de función ................................................................................................................. 8
Definición de funciones ............................................................................................................. 8
Llamada a funciones.................................................................................................................. 9
Tipos de parámetros. Sintaxis de definición ............................................................................. 9
Parámetros de entrada ......................................................................................................... 9
Parámetros por referencia .................................................................................................. 10
Arrays .......................................................................................................................................... 10
Arrays multidimensionales ...................................................................................................... 12
La clase System.Array .............................................................................................................. 13
Cadenas de texto......................................................................................................................... 13
Registros (Structs) ....................................................................................................................... 15
Listas, Pilas y Colas ...................................................................................................................... 16
Ficheros ....................................................................................................................................... 17
Ficheros de texto ..................................................................................................................... 18
Escritura en ficheros de texto ............................................................................................. 18
Lectura en ficheros de texto ............................................................................................... 19
Ficheros binarios ..................................................................................................................... 19
Escritura en ficheros binarios .............................................................................................. 19
Lectura en ficheros binarios ................................................................................................ 21
Programación Orientada a Objetos............................................................................................. 22
Clases y Objetos ...................................................................................................................... 22
Conceptos fundamentales ...................................................................................................... 22
Control de Acceso a métodos y atributos ............................................................................... 23
Definición de una Clase en C# ................................................................................................. 23
Constructores .......................................................................................................................... 24
Propiedades............................................................................................................................. 25
Variables y Tipos de Datos 3

Variables y Tipos de Datos

Una variable puede verse simplemente como un almacén de objetos de un determinado


tipo al que se le da un cierto nombre. Por tanto, para definir una variable sólo hay que
decir cuál será el nombre que se le dará y cuál será el tipo de datos que podrá
almacenar, lo que se hace con la la siguiente sintaxis:

<tipoVariable> <nombreVariable>;

C# también proporciona una sintaxis más sencilla con la que podremos asignar un valor
a una variable en el mismo momento se define. Para ello se la ha de definir usando esta
otra notación:

<tipoVariable> <nombreVariable> = <valorInicial>;

Tipos de datos básicos

Los tipos de datos básicos son ciertos tipos de datos tan comúnmente utilizados en la
escritura de aplicaciones que en C# se ha incluido una sintaxis especial para tratarlos.

System.Int32 a = 2;

Dado lo frecuente que es el uso de este tipo también se ha predefinido en C# el alias int
para el mismo, por lo que la definición de variable anterior queda así de compacta:

int a = 2;

System.Int32 no es el único tipo de dato básico incluido en C#. En el espacio de


nombres System se han incluido todos estos:

Tipo Descripción Bits Rango de valores Alias


SByte Bytes con signo 8 -128 – 127 sbyte
Byte Bytes sin signo 8 0 – 255 byte
Int16 Enteros cortos con signo 16 [-32.768, 32.767] short
UInt16 Enteros cortos sin signo 16 [0, 65.535] ushort
Int32 Enteros normales 32 [-2.147.483.648, 2.147.483.647] int
UInt32 Enteros normales sin signo 32 [0, 4.294.967.295] uint
Int64 Enteros largos 64 [-9.223.372.036.854.775.808, long
9.223.372.036.854.775.807]
UInt64 Enteros largos sin signo 64 [0-18.446.744.073.709.551.615] ulong
Single Reales con 7 dígitos de 32 [1,5×10-45 - 3,4×1038] float
precisión
Double Reales de 15-16 dígitos de 64 [5,0×10-324 - 1,7×10308] double
precisión
Decimal Reales de 28-29 dígitos de 128 [1,0×10-28 - 7,9×1028] decimal
precisión
Boolean Valores lógicos 32 true, false bool
Char Caracteres Unicode 16 [„\u0000‟, „\uFFFF‟] char
String Cadenas de caracteres Variable El permitido por la memoria string
Object Cualquier objeto Variable Cualquier objeto object
Instrucciones 4

El valor que por defecto se da a los campos de tipos básicos consiste en poner a cero
toda el área de memoria que ocupen. Esto se traduce en que los campos de tipos básicos
numéricos se inicializan por defecto con el valor 0, los de tipo bool lo hacen con false,
los de tipo char con ‘\u0000’, y los de tipo string y object con null.

Instrucciones

Concepto de instrucción
Toda acción que se pueda realizar en el cuerpo de un método, como definir variables
locales, llamar a métodos, asignaciones y muchas cosas más que veremos a lo largo de
este tema, son instrucciones.
Las instrucciones se agrupan formando bloques de instrucciones, que son listas de
instrucciones encerradas entre llaves que se ejecutan una tras otra. Es decir, la sintaxis
que se sigue para definir un bloque de instrucciones es:
{
<listaInstrucciones>
}

Toda variable que se defina dentro de un bloque de instrucciones sólo existirá dentro de
dicho bloque. Tras él será inaccesible y podrá ser destruida por el recolector de basura.
Por ejemplo, este código no es válido:
public void f();
{
{ int b; }
b = 1; // ERROR: b no existe fuera del bloque donde se declaró.
}

Los bloques de instrucciones pueden anidarse, aunque si dentro de un bloque interno


definimos una variable con el mismo nombre que otra definida en un bloque externo se
considerará que se ha producido un error, ya que no se podrá determinar a cuál de las
dos se estará haciendo referencia cada vez que se utilice su nombre en el bloque interno.

Instrucciones básicas
Definiciones de variables locales
Las variables locales son variables que se definen en el cuerpo de los métodos y sólo
son accesibles desde dichos cuerpos. La sintaxis para definirlas es la siguiente:

<modificadores> <tipoVariable> <nombreVariable> = <valor>;

También pueden definirse varias variables en una misma instrucción separando sus
pares nombre-valor mediante comas. Por ejemplo:
int a=5, b, c=-1;
Instrucciones 5

Asignaciones
Una asignación es simplemente una instrucción mediante la que se indica un valor a
almacenar en un dato. La sintaxis usada para ello es:
<destino> = <origen>;

Instrucciones condicionales
Las instrucciones condicionales son instrucciones que permiten ejecutar bloques de
instrucciones sólo si se da una determinada condición. En los siguientes subapartados de
este epígrafe se describen cuáles son las instrucciones condicionales disponibles en C#
Instrucción if
La instrucción if permite ejecutar ciertas instrucciones sólo si se da una determinada
condición. Su sintaxis de uso es la sintaxis:
if (<condición>)
<instruccionesIf>
else
<instruccionesElse>

El significado de esta instrucción es el siguiente: se evalúa la expresión <condición>, que


ha de devolver un valor lógico. Si es cierta (devuelve true) se ejecutan las
<instruccionesIf>, y si es falsa (false) se ejecutan las <instruccionesElse> La rama else es
opcional, y si se omite y la condición es falsa se seguiría ejecutando a partir de la
instrucción siguiente al if. En realidad, tanto <instruccionesIf> como <instruccionesElse>
pueden ser una única instrucción o un bloque de instrucciones.

Instrucción switch
La instrucción switch permite ejecutar unos u otros bloques de instrucciones según el
valor de una cierta expresión. Su estructura es:
switch (<expresión>)
{
case <valor1>: <bloque1>
break;
case <valor2>: <bloque2>
break;
...
default: <bloqueDefault>
break;
}

El significado de esta instrucción es el siguiente: se evalúa <expresión>. Si su valor es


<valor1> se ejecuta el <bloque1>, si es <valor2> se ejecuta <bloque2>, y así para el resto de
valores especificados. Si no es igual a ninguno de esos valores y se incluye la rama
default, se ejecuta el <bloqueDefault>; pero si no se incluye se pasa directamente a
ejecutar la instrucción siguiente al switch.

Los valores indicados en cada rama del switch han de ser expresiones constantes que
produzcan valores de algún tipo básico entero, de una enumeración, de tipo char o de
tipo string. Además, no puede haber más de una rama con el mismo valor. En realidad,
aunque todas las ramas de un switch son opcionales siempre se ha de incluir al menos
Instrucciones 6

una. Además, la rama default no tiene porqué aparecer la última si se usa, aunque es
recomendable que lo haga para facilitar la legibilidad del código.

Instrucciones iterativas
Las instrucciones iterativas son instrucciones que permiten ejecutar repetidas veces
una instrucción o un bloque de instrucciones mientras se cumpla una condición. Es
decir, permiten definir bucles donde ciertas instrucciones se ejecuten varias veces. A
continuación se describen cuáles son las instrucciones de este tipo incluidas en C#.

Instrucción while
La instrucción while permite ejecutar un bloque de instrucciones mientras se dé una
cierta instrucción. Su sintaxis de uso es:
while (<condición>)
<instrucciones>

Su significado es el siguiente: Se evalúa la <condición> indicada, que ha de producir un


valor lógico. Si es cierta (valor lógico true) se ejecutan las <instrucciones> y se repite el
proceso de evaluación de <condición> y ejecución de <instrucciones> hasta que deje de
serlo. Cuando sea falsa (false) se pasará a ejecutar la instrucción siguiente al while. En
realidad <instrucciones> puede ser una única instrucción o un bloque de instrucciones.

Por otro lado, dentro de las <instrucciones> de un while pueden usarse dos instrucciones
especiales:
break;: Indica que se ha de abortar la ejecución del bucle y continuarse
ejecutando por la instrucción siguiente al while.
continue;: Indica que se ha de abortar la ejecución de las <instrucciones> y
reevaluarse la <condición> del bucle, volviéndose a ejecutar la <instrucciones> si
es cierta o pasándose a ejecutar la instrucción siguiente al while si es falsa.

Instrucción do...while
La instrucción do...while es una variante del while que se usa así:
do
<instrucciones>
while(<condición>);

La única diferencia del significado de do...while respecto al de while es que en vez de


evaluar primero la condición y ejecutar <instrucciones> sólo si es cierta, do...while
primero ejecuta las <instrucciones> y luego mira la <condición> para ver si se ha de repetir
la ejecución de las mismas. Por lo demás ambas instrucciones son iguales, e incluso
también puede incluirse break; y continue; entre las <instrucciones> del do...while. do ...
while está especialmente destinado para los casos en los que haya que ejecutar las
<instrucciones> al menos una vez aún cuando la condición sea falsa desde el principio.,
Instrucciones 7

Instrucción for
La instrucción for es una variante de while que permite reducir el código necesario para
escribir los tipos de bucles más comúnmente usados en programación. Su sintaxis es:
for (<inicialización>; <condición>; <modificación>)
<instrucciones>

El significado de esta instrucción es el siguiente: se ejecutan las instrucciones de


<inicialización>, que suelen usarse para definir e inicializar variables que luego se usarán
en <instrucciones>. Luego se evalúa <condición>, y si es falsa se continúa ejecutando por
la instrucción siguiente al for; mientras que si es cierta se ejecutan las <instrucciones>
indicadas, luego se ejecutan las instrucciones de <modificación> -que como su nombre
indica suelen usarse para modificar los valores de variables que se usen en
<instrucciones>- y luego se reevalúa <condición> repitiéndose el proceso hasta que ésta
última deje de ser cierta.

En <inicialización> puede en realidad incluirse cualquier número de instrucciones que no


tienen porqué ser relativas a inicializar variables o modificarlas, aunque lo anterior sea
su uso más habitual. En caso de ser varias se han de separar mediante comas (,), ya que
el carácter de punto y coma (;) habitualmente usado para estos menesteres se usa en el
for para separar los bloques de <inicialización>, <condición> y <modificación> Además, la
instrucción nula no se puede usar en este caso y tampoco pueden combinarse
definiciones de variables con instrucciones de otros tipos.
Con <modificación> pasa algo similar, ya que puede incluirse código que nada tenga que
ver con modificaciones pero en este caso no se pueden incluir definiciones de variables.
Como en el resto de instrucciones hasta ahora vistas, en <instrucciones> puede ser tanto
una única instrucción como un bloque de instrucciones. Además, las variables que se
definan en <inicialización> serán visibles sólo dentro de esas <instrucciones>

Al igual que con while, dentro de las <instrucciones> del for también pueden incluirse
instrucciones continue; y break; que puedan alterar el funcionamiento normal del bucle.

Instrucción foreach
La instrucción foreach es una variante del for pensada especialmente para compactar la
escritura de códigos donde se realice algún tratamiento a todos los elementos de una
colección, que suele un uso muy habitual de for en los lenguajes de programación que lo
incluyen. La sintaxis que se sigue a la hora de escribir esta instrucción foreach es:
foreach (<tipoElemento> <elemento> in <colección>)
<instrucciones>

El significado de esta instrucción es muy sencillo: se ejecutan <instrucciones> para cada


uno de los elementos de la <colección> indicada. <elemento> es una variable de sólo
lectura de tipo <tipoElemento> que almacenará en cada momento el elemento de la
colección que se esté procesando y que podrá ser accedida desde <instrucciones>.

El tipo System.Array implementa la interfaz System.Collectiones.IEnumerator, por lo


que todas las tablas podrán ser usadas recorridas con foreach. Si la tabla a recorrer es
multidimensional, sus elementos se recorrerán en orden como muestra este ejemplo:
int[,] tabla = { {1,2}, {3,4} };
Funciones 8

foreach (int elemento in tabla)


Console.WriteLine(elemento);

La salida por pantalla del fragmento de código anterior será:


1
2
3
4

Funciones
Concepto de función
Una función es un conjunto de instrucciones a las que se les da un determinado nombre
de tal manera que sea posible ejecutarlas en cualquier momento sin tenerlas que
reescribir sino usando sólo su nombre. A estas instrucciones se les denomina cuerpo de
la función, y a su ejecución a través de su nombre se le denomina llamada a la función.

La ejecución de las instrucciones de una función 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 funciones que no devuelvan ninguno.

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

Al conjunto formado por el nombre de una función y el número y tipo de sus


parámetros se le conoce como signatura de la función. La signatura de una función es
lo que verdaderamente la identifica, de modo que es posible definir en un mismo tipo
varias funciones con idéntico nombre siempre y cuando tengan distintos parámetros.
Cuando esto ocurre se dice que la función que tiene ese nombre está sobrecargada.

Definición de funciones
Para definir una función 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> <nombreFunción>(<parámetros>)
{
<cuerpo>
}

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

Aunque es posible escribir funciones que no tomen parámetros, si una función los toma
se ha de indicar en <parámetros> cuál es el nombre y tipo de cada uno de ellos,
Funciones 9

separándolos con comas si son más de uno y siguiendo la sintaxis que más adelante se
explica.

El <cuerpo> de la función también es opcional, pero si la función retorna algún tipo de


objeto entonces ha de incluir al menos una instrucción return que indique cuál es el
objeto a devolver.

A continuación se muestra un ejemplo de cómo definir un método de nombre Saluda


cuyo cuerpo consista en escribir en la consola el mensaje “Hola Mundo” y que devuelva
un objeto int de valor 1:
int Saluda()
{
Console.WriteLine(“Hola Mundo”);
return 1;
}

Llamada a funciones
La forma en que se puede llamar a una función depende del tipo de función de la que se
trate.
<nombreMétodo>(<valoresParámetros>)

Tipos de parámetros. Sintaxis de definición


La forma en que se define cada parámetro de una función depende del tipo de parámetro
del que se trate. En C# se admiten cuatro tipos de parámetros: parámetros de entrada,
parámetros de salida, parámetros por referencia y parámetros de número indefinido.

Parámetros de entrada
Un parámetro de entrada recibe una copia del valor que almacenaría una variable del
tipo del objeto que se le pase. Por tanto, si el objeto es de un tipo valor se le pasará una
copia del objeto y cualquier modificación que se haga al parámetro dentro del cuerpo
del la función no afectará al objeto original sino a su copia; mientras que si el objeto es
de un tipo referencia entonces se le pasará una copia de la referencia al mismo y
cualquier modificación que se haga al parámetro dentro de la función también afectará
al objeto original ya que en realidad el parámetro referencia a ese mismo objeto
original. Para definir un parámetro de entrada basta indicar cuál el nombre que se le
desea dar y el cuál es tipo de dato que podrá almacenar. Para ello se sigue la siguiente
sintaxis:
<tipoParámetro> <nombreParámetro>

Por ejemplo, el siguiente código define una función llamada Suma que toma dos
parámetros de entrada de tipo int llamados par1 y par2 y devuelve un int con su suma:
int Suma(int par1, int par2)
{
return par1+par2;
}
Arrays 10

Como se ve, se usa la instrucción return para indicar cuál es el valor que ha de devolver
la función. Este valor es el resultado de ejecutar la expresión par1+par2; es decir, es la
suma de los valores pasados a sus parámetros par1 y par2 al llamarla.
En las llamadas a funciones se expresan los valores que se deseen dar a este tipo de
parámetros indicando simplemente el valor deseado. Por ejemplo, para llamar a la
función anterior con los valores 2 y 5 se haría <objeto>.Suma(2,5), lo que devolvería el
valor 7.

Parámetros por referencia


Un parámetro por referencia se diferencia de uno de entrada en que todo cambio que
se le realice en el código de la función a la que pertenece afectará al objeto que se le
pase al llamar a dicha función tanto si éste es de un tipo valor como si es de un tipo
referencia. Esto se debe a que lo que a estos parámetros se les pasa es siempre una
referencia al valor que almacenaría una variable del tipo del objeto que se les pase.
Será obligatorio pasarle una variable inicializada ya que no se garantiza su inicialización
en el método.
Los parámetros de salida se definen de forma parecida a los parámetros de entrada pero
se les ha de añadir la palabra reservada ref. O sea, se definen así:
ref <tipoParámetro> <nombreParámetro>

Al llamar a un método que tome parámetros de este tipo también se ha preceder el valor
especificado para estos parámetros del modificador out. Por ejemplo:
Suma(x, ref z)

Arrays

Un array unidimensional es un tipo especial de variable que es capaz de almacenar en


su interior y de manera ordenada uno o varios datos de un determinado tipo. Para
declarar variables de este tipo especial se usa la siguiente sintaxis:

<tipoDatos>[] <nombreArray>;

Por ejemplo, un array que pueda almacenar objetos de tipo int se declara así:
int[] array;

Con esto la array creada no almacenaría ningún objeto, sino que valdría null. Si se desea
que verdaderamente almacene objetos hay que indicar cuál es el número de objetos que
podrá almacenar, lo que puede hacerse usando la siguiente sintaxis al declararla:
<tipoDatos>[] <nombreArray> = new <tipoDatos>[<númeroDatos>];

Por ejemplo, un array que pueda almacenar 100 objetos de tipo int se declara así:
int[] array = new int[100];
Arrays 11

Aunque también sería posible definir el tamaño del array de forma separada a su
declaración de este modo:
int[] array;
array = new int[100];

Con esta última sintaxis es posible cambiar dinámicamente el número de elementos de


una variable array sin más que irle asignando nuevos arrays. Ello no significa que un
array se pueda redimensionar conservando los elementos que tuviese antes del cambio
de tamaño, sino que ocurre todo lo contrario: cuando a una variable array se le asigna un
array de otro tamaño, sus elementos antiguos son sobreescritos por los nuevos. Si se
crea un array con la sintaxis hasta ahora explicada todos sus elementos tendrían el valor
por defecto de su tipo de dato. Si queremos darles otros valores al declarar el array,
hemos de indicarlos entre llaves usando esta sintaxis:

<tipoDatos>[] <nombreArray> = new <tipoDatos>[] {<valores>};

Ha de especificarse tantos <valores> como número de elementos se desee que tenga el


array, y si son más de uno se han de separar entre sí mediante comas (,) Nótese que
ahora no es necesario indicar el número de elementos de el array (aunque puede hacerse
si se desea), pues el compilador puede deducirlo del número de valores especificados.
Por ejemplo, para declarar un array de cuatro elementos de tipo int con valores 5,1,4,0
se podría hacer lo siguiente:
int[] array = new int[] {5,1,4,0};

Incluso se puede compactar aún más la sintaxis declarando el array así:


int[] array = {5,1,4,0};

También podemos crear arrays cuyo tamaño se pueda establecer dinámicamente a partir
del valor de cualquier expresión que produzca un valor de tipo entero. Por ejemplo, para
crear un array cuyo tamaño sea el valor indicado por una variable de tipo int (luego su
valor será de tipo entero) se haría:
int i = 5;
...
int[] arrayDinamico = new int[i];

A la hora de acceder a los elementos almacenados en un array basta indicar entre


corchetes, y a continuación de la referencia a la misma, la posición que ocupe en el
array el elemento al que acceder. Cuando se haga hay que tener en cuenta que en C# los
arrays se indexan desde 0, lo que significa que el primer elemento del array ocupará su
posición 0, el segundo ocupará la posición 1, y así sucesivamente para el resto de
elementos. Por ejemplo, aunque es más ineficiente, el array declarada en el último
fragmento de código de ejemplo también podría haberse definido así:

int[] array = new int[4];


array[0] = 5;
array[1]++;
// Por defecto se inicializó a 0, luego ahora el valor de array[1]
// pasa a ser 1
array[2] = array[0] – array[1];
// array[2] pasa a valer 4, pues 5-4 = 1
Arrays 12

// El contenido de la array será {5,1,4,0}, pues array[3] se


// inicializó por defecto a 0.

Hay que tener cuidado a la hora de acceder a los elementos del array ya que si se
especifica una posición superior al número de elementos que pueda almacenar el array
se producirá una excepción de tipo System.OutOfBoundsException.

Para evitar este tipo de excepciones puede consultar el valor del campo de sólo lectura
Length que está asociado a todo array y contiene el número de elementos de la misma.
Por ejemplo, para asignar un 7 al último elemento del array anterior se haría:
array[array.Length – 1] = 7;
// Se resta 1 porque array.Length devuelve 4 pero el último
// elemento de la array es array[3]

Arrays multidimensionales
Un array multidimensional es un array cuyos elementos se encuentran organizando
una estructura de varias dimensiones. Para definir este tipo de arrays se usa una sintaxis
similar a la usada para declarar arrays unidimensionales pero separando las diferentes
dimensiones mediante comas (,). Por ejemplo, un array multidimensional de elementos
de tipo int que conste de 12 elementos puede tener sus elementos distribuidos en dos
dimensiones formando una estructura 3x4 similar a una matriz de la forma:

1 2 3 4
5 6 7 8
9 10 11 12

Este array se podría declarar así:

int[,] arrayMultidimensional = new int[3,4] {{1,2,3,4}, {5,6,7,8},


{9,10,11,12}};

En realidad no es necesario indicar el número de elementos de cada dimensión del array


ya que pueden deducirse de los valores explícitamente indicados entre llaves, por lo que
la definición anterior es similar a esta:

int[,] arrayMultidimensional = new int[,] {{1,2,3,4}, {5,6,7,8},


{9,10,11,12}};

Incluso puede reducirse aún más la sintaxis necesaria quedando tan sólo:

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

Si no queremos indicar explícitamente los elementos del array al declararlo, podemos


obviarlos pero aún así indicar el tamaño de cada dimensión del array (a los elementos se
les daría el valor por defecto de su tipo de dato) así:

int[,] arrayMultidimensional = new int[3,4];

También podemos no especificar ni siquiera el número de elementos del array de esta


forma (arrayMultidimensional contendría ahora null):
Cadenas de texto 13

int[,] arrayMultidimensional;

Aunque los ejemplos de arrays multidimensionales hasta ahora mostrados son de arrays
de dos dimensiones, en general también es posible crear arrays de cualquier número de
dimensiones. Por ejemplo, un array que almacene 24 elementos de tipo int y valor 0 en
una estructura tridimensional 3x4x2 se declararía así:

int[,,] arrayMultidimensional = new int[3,4,2];

El acceso a los elementos de un array multidimensional es muy sencillo: sólo hay que
indicar los índices de la posición que ocupe en la estructura multidimensional el
elemento al que se desee acceder. Por ejemplo, para incrementar en una unidad el
elemento que ocupe la posición (1,3,2) del array anterior se haría (se indiza desde 0):

arrayMultidimensional[0,2,1]++;

La clase System.Array
En realidad, todos los arrays que definamos, sea cual sea el tipo de elementos que
contengan, son objetos que derivan de System.Array. Es decir, van a disponer de todos
los miembros que se han definido para esta clase, entre los que son destacables:

Length: Campo de sólo lectura que informa del número total de elementos que
contiene el array. Si el array tiene más de una dimensión o nivel de anidación
indica el número de elementos de todas sus dimensiones y niveles. Por ejemplo:
int[] array = {1,2,3,4};
int[][] array2 = {new int[] {1,2}, new int[] {3,4,5}};
int[,] array3 = {{1,2},{3,4,5,6}};
Console.WriteLine(array.Length); //Imprime 4
Console.WriteLine(array2.Length); //Imprime 5
Console.WriteLine(array3.Length); //Imprime 6

int GetLength(int dimensión): Método que devuelve el número de elementos de


la dimensión especificada. Las dimensiones se indican empezando a contar
desde cero, por lo que si quiere obtenerse el número de elementos de la primera
dimensión habrá que usar GetLength(0), si se quiere obtener los de la segunda
habrá que usar GetLength(1), etc. Por ejemplo:
int[,] array = {{1,2}, {3,4,5,6}};
Console.WriteLine(array.GetLength(0)); // Imprime 2
Console.WriteLine(<garray.GetLength(1)); // Imprime 4

Cadenas de texto

Una cadena de texto no es más que una secuencia de caracteres Unicode. En C# se


representan mediante objetos del tipo tipo de dato llamado string, que no es más que un
alias del tipo System.String incluido en la BCL.
Las cadenas de texto suelen crearse a partir literales de cadena o de otras cadenas
previamente creadas. Ejemplos de ambos casos se muestran a continuación:
Cadenas de texto 14

string cadena1 = “José Antonio”;


string cadena2 = cadena;

En el primer caso se ha creado un objeto string que representa a la cadena formada por
la secuencia de caracteres José Antonio indicada literalmente (nótese que las comillas
dobles entre las que se encierran los literales de cadena no forman parte del contenido
de la cadena que representan sino que sólo se usan como delimitadores de la misma). En
el segundo caso la variable cadena2 creada se genera a partir de la variable cadena1 ya
existente, por lo que ambas variables apuntarán al mismo objeto en memoria.

Al igual que el significado del operador == ha sido especialmente modificado para


trabajar con cadenas, lo mismo ocurre con el operador binario +. En este caso, cuando se
aplica entre dos cadenas o una cadena y un carácter lo que hace es devolver una nueva
cadena con el resultado de concatenar sus operandos. Así por ejemplo, en el siguiente
código las dos variables creadas almacenarán la cadena “Hola Mundo”:
public static void Main()
{
string cadena = “Hola” + “ Mundo”;
string cadena2 = “Hola Mund” + „o‟;
}

Por otro lado, el acceso a las cadenas se hace de manera similar a como si de tablas de
caracteres se tratase: su “campo” Length almacenará el número de caracteres que la
forman y para acceder a sus elementos se utiliza el operador []. Por ejemplo, el siguiente
código muestra por pantalla cada carácter de la cadena Hola en una línea diferente:
public static void Main()
{
string cadena = “Hola”;
Console.WriteLine(cadena[0]);
Console.WriteLine(cadena[1]);
Console.WriteLine(cadena[2]);
Console.WriteLine(cadena[3]);
}

Sin embargo, hay que señalar una diferencia importante respecto a la forma en que se
accede a las tablas: las cadenas son inmutables, lo que significa que no es posible
modificar los caracteres que las forman.

Aparte de los métodos ya vistos, en la clase System.String se definen muchos otros


métodos aplicables a cualquier cadena y que permiten manipularla. Los principales son:

int IndexOf(string subcadena): Indica cuál es el índice de la primera aparición de


la subcadena indicada dentro de la cadena sobre la que se aplica. La búsqueda de
dicha subcadena se realiza desde el principio de la cadena, pero es posible
indicar en un segundo parámetro opcional de tipo int cuál es el índice de la
misma a partir del que se desea empezar a buscar. Del mismo modo, la búsqueda
acaba al llegar al final de la cadena sobre la que se busca, pero pasando un tercer
parámetro opcional de tipo int es posible indicar algún índice anterior donde
terminarla.
Nótese que es un método muy útil para saber si una cadena contiene o no alguna
subcadena determinada, pues sólo si no la encuentra devuelve un –1.
Registros (Structs) 15

int LastIndexOf(string subcadena): Funciona de forma similar a IndexOf() sólo


que devuelve la posición de la última aparición de la subcadena buscada en lugar
de devolver la de la primera.

string Insert(int posición, string subcadena): Devuelve la cadena resultante de


insertar la subcadena indicada en la posición especificada de la cadena sobre la
que se aplica.

string Remove(int posición, int número): Devuelve la cadena resultante de


eliminar el número de caracteres indicado que hubiese en la cadena sobre al que
se aplica a partir de la posición especificada.

string Replace(string aSustituir, string sustitua): Devuelve la cadena resultante


de sustituir en la cadena sobre la que se aplica toda aparación de la cadena a
Sustituir indicada por la cadena sustituta especificada como segundo parámetro.
string Substring(int posición, int número): Devuelve la subcadena de la cadena
sobre la que se aplica que comienza en la posición indicada y tiene el número de
caracteres especificados. Si no se indica dicho número se devuelve la subcadena
que va desde la posición indicada hasta el final de la cadena.

string ToUpper() y string ToLower(): Devuelven, respectivamente, la cadena que


resulte de convertir a mayúsculas o minúsculas la cadena sobre la que se aplican.

Registros (Structs)
Un registro, que en los lenguajes C y C# se denomina struct, es un tipo de dato
estructurado formado por la unión de varios elementos bajo una misma estructura. Estos
elementos pueden ser, o bien tipos de datos básicos (entero, real, carácter,...), o bien
otras estructuras de datos. A cada uno de esos elementos se le llama campo.
Un registro se diferencia de un array en que éste es una colección de datos iguales, es
decir, todos del mismo tipo, mientras que en una estructura los elementos que la
componen, aunque podrían serlo, no tiene porque ser del mismo tipo.

En C#, los registros se definen de la siguiente forma:

struct ficha_alumno
{
public string nombre;
public int edad;
public decimal nota;
}

Con esto habríamos definido el tipo de dato ficha_alumno que nos permitirá crear
variables con esa estructura. Para definir variables de ese tipo, simplemente hacemos:

ficha_alumno f;
Listas, Pilas y Colas 16

Y para acceder al contenido del registro:

f.nombre = “Hola”;
f.edad = 23;
f.nota = 5.3M;

Console.WriteLine(f.nombre);

Listas, Pilas y Colas


Una lista es una colección que nos permite guardar elementos del mismo tipo, de la
misma forma que hace un array. Al contrario que en los arrays, las listas no tienen un
tamaño definido, sino que van creciendo a medida que se les añade elementos nuevos.

Para definir una lista, usaremos la sintaxis:

List<<tipoDatos>> <nombreLista>;

Ej.: List<int> lista;

Además de definirla, deberemos crearla para poderla usar, lo que haremos con:

<nombreLista> = new List<<tipoDatos>>();

Ej.: lista = new List<int>();

Normalmente haremos ambas cosas en una sola línea:

List<int> lista = new List<int>();

Las listas se usan de manera similar a los arrays, con unas cuantas diferencias:

Las listas no tienen un tamaño definido, por lo que a la hora de crearlas no hay
que especificar el tamaño.

Para añadir un nuevo dato a la lista, usaremos la función Add(), que nos añade
un elemento en la última posición. Así, iremos añadiendo todos los valores que
necesitemos.

lista.Add(25);

En un array, teníamos que primero reservar el tamaño que necesitáramos y


luego ir modificando los valores de cada posición.

Para saber cuántos elementos hay en una lista, usaremos la función Count. En
un array usábamos Length que nos devolvía el tamaño que habíamos
reservado.
Ficheros 17

Console.WriteLine(lista.Count);

Salvo estas diferencias, una lista se puede usar básicamente de la misma forma que se
usa un array. No obstante, las listas disponen de funciones específicas que nos
permiten realizar las operaciones más comunes. A continuación, se enumeran las más
importantes:

void Add(<tipo dato> valor): Añade un valor a la lista en la última posición. El


valor tiene que ser del mismo tipo del que hayamos definido la lista (esto es, en
una lista de enteros sólo podemos almacenar enteros).

void Insert(int indice, <tipo dato> valor):


Inserta un valor en la lista en la posición
especificada. La posición 0 se corresponde con el inicio de la lista (se
introduciría el elemento al principio), mientras que la posición lista.Count se
corresponde a la última posición (similar a usar Add).

int IndexOf(<tipo dato> valor): Nos devuelve la posición del elemento, si existe.
Si el elemento no existe, nos devolverá -1.

bool Exists(<tipo dato> valor): Nos devuelve true si el valor existe dentro de la
lista y false en caso contrario.

void Clear(): Elimina todos los elementos de la lista y nos la deja preparada para
volver a introducir datos.

void RemoveAt(int posicion): Elimina el elemento que se encuentra en la


posición especificada. Recordemos que la primera posición es la 0 y la última
será la Count-1.

bool Remove(<tipo dato> valor): Elimina la primera vez que aparece el valor
dentro de la lista. Nos devolverá true si ha encontrado y borrado el valor y false
si el valor no se ha encontrado dentro de la lista.

int RemoveAll(<tipo dato> valor): Elimina todas las veces que aparece el valor
dentro de la lista. Nos devolverá un entero que se corresponderá al número de
elementos que han sido eliminados.

void AddRange(<colección> colección): Copia dentro de la lista todos los


elementos de la colección. Esta colección puede ser otra lista, un array, etc.

Otras funciones interesantes incluidas son: Average (media aritmética), Max,


Mix, Reverse (invierte el orden de los elementos), Sort (ordena) y Sum.

Ficheros
Ficheros 18

Los ficheros nos permiten guardar y recuperar información desde los dispositivos de
almacenamiento. Básicamente, hay dos tipos de ficheros: ficheros de texto y ficheros
binarios. Ambos funcionan de manera similar, pero en los ficheros de texto sólo
podemos guardar cadenas de caracteres mientras que en los ficheros binarios podemos
guardar todo tipo de datos. En C#, usaremos unas herramientas denominada streams
que nos permitirán acceder de manera cómoda a la información que se encuentra
almacenada en los ficheros.

El proceso para utilizar un archivo consta de tres pasos: apertura del fichero, lectura y
escritura de datos, y cerrado del fichero. En C#, utilizaremos diferentes instrucciones
para los ficheros de texto y los ficheros binarios, y también diferentes opciones según
queramos leer o escribir en el fichero.

Ficheros de texto

Los ficheros de texto contienen única y exclusivamente cadenas de texto, organizadas


en líneas. Su uso en C# es muy similar al uso de la Consola, usando funciones ya
conocidas como ReadLine y WriteLine.

Escritura en ficheros de texto

Para escribir texto en un fichero, primero abriremos el fichero en modo escritura:

StreamWriter <nombre> = new StreamWriter(<nombre del fichero>);


Dos opciones adicionales nos permiten elegir si queremos sobreescribir el fichero en
caso de que exista o preferimos continuarlo y el tipo de codificación que queremos.

StreamWriter <nombre> = new StreamWriter(<nombre>, <continuar>,


<tipo de codificación>);

En la opción continuar pondremos true si queremos continuar el archivo en caso de


que exista (si no existe, da igual) y false si queremos crear el archivo desde cero en caso
de que exista. En la opción tipo de codificación podremos elegir entre varios tipos de
codificación para ficheros de texto comunes, como pueden ser ASCII, ANSI, UTF, etc.
Para nuestros ejercicios en Windows, usaremos: Encoding.Default. Un ejemplo de
cómo abrir un fichero podría ser:

StreamWriter sw = new StreamWriter("texto.txt", false,


Encoding.Default);

Una vez abierto, podremos escribir texto en él. La función a utilizar será Write si
queremos escribir sin que salte a la línea siguiente y WriteLine si queremos que nos
salte (lo más usual).
sw.WriteLine(“Hola”);

Cuando hayamos terminado de escribir todo el fichero, deberemos cerrarlo para que se
guarden completamente los datos en el disco.

sw.Close();
Ficheros 19

Lectura en ficheros de texto

Para leer texto desde un fichero, primero abriremos el fichero en modo lectura:

StreamReader <nombre> = new StreamReader(<nombre del fichero>);

Adicionalmente, podemos especificar el tipo de codificación:

StreamReader <nombre> = new StreamReader(<nombre del fichero>,


<tipo de codificación>);

Un ejemplo de cómo abrir un fichero para lectura sería:

StreamReader sr = new StreamReader("texto.txt", Encoding.Default);

Para leer datos del fichero, normalmente lo haremos por líneas mediante la función
ReadLine.

string linea = sr.ReadLine();


Si conocemos el número de líneas que contiene el fichero, podemos hacer un bucle for
para irlas leyendo, pero si no lo conocemos, tendremos que usar una función especial
que nos avisa cuando hemos llegado al final del fichero. Esta función es EndOfStream
que será true si se ha llegado al final del fichero y false si aún no se ha llegado. Lo que
haremos, pues, es un bucle mientras no se cumpla esa condición.

while(!sr.EndofStream)
{
string cadena = sr.ReadLine();
...
}

No se os olvide cerrar el fichero después de haberlo utilizado.

Ficheros binarios

Aunque en un fichero de texto se pueden guardar datos como números enteros,


números reales, etc. (se guardan como texto y se leen con la función Parse
correspondiente), es mucho mejor usar para ello los ficheros binarios.

Escritura en ficheros binarios

Para escribir en un fichero binario, deberemos abrir el fichero en modo escritura.

FileStream fs = new FileStream(<nombre del fichero>, <modo de apertura>);


BinaryWriter bw = new BinaryWriter(fs);

Al contrario que en los ficheros de texto, los ficheros binarios disponen de muchas
opciones de apertura, dependiendo de que queramos crear un fichero nuevo,
modificarlo, añadir datos, etc. Las diferentes opciones son:
Ficheros 20

FileMode.Append: Nos permite añadir datos al final del fichero. Si el fichero


no existe, se produce un error.
FileMode.Create: Nos crea un fichero nuevo o sobreescribe un fichero ya
existente.
FileMode.CreateNew: Nos crea un fichero nuevo. Si el fichero ya existe, da
error.
FileMode.Open: Nos abre un fichero ya existente. Si el fichero no existe, se
produce un error.
FileMode.OpenOrCreate: Nos abre el fichero si ya existe o crea un nuevo si no
existe.
FileMode.Truncate: Nos sobreescribe un fichero ya existente. Si no existe, da
un error.
Ficheros 21

Las opciones que usaremos normalmente serán Create para escribir datos en un fichero
(o Append si queremos añadir más datos) y Open para leer datos del fichero.

FileStream fs = new FileStream("datos.bin", FileMode.Create);


BinaryWriter bw = new BinaryWriter(fs);

Una vez abierto, podremos escribir datos en él. Sólo utilizaremos una función para
escribir datos, que es la orden Write. Esta función tiene varias versiones que se
seleccionan automáticamente dependiendo del tipo de dato que le pasemos. Así,
podremos usar la orden Write para escribir un entero, un real, una cadena, etc.
int n = 100;
bw.Write(n);

Cuando hayamos terminado de escribir todo el fichero, deberemos cerrarlo para que se
guarden completamente los datos en el disco.

bw.Close();

Lectura en ficheros binarios

Para leer datos desde un fichero binario, primero abriremos el fichero en modo lectura:

FileStream fs = new FileStream(<nombre del fichero>, <modo de apertura>);


BinaryReader br = new BinaryReader(fs);

Como ya hemos mencionado, el modo más normal para leer ficheros es Open.

FileStream fs2 = new FileStream("datos.bin", FileMode.Open);


BinaryReader br = new BinaryReader(fs);

Leer datos desde un fichero binario es mucho más complicado que escribirlos o que
hacerlo en un fichero de texto. Para leer un dato desde un fichero binario, tendremos
que conocer el tipo del dato y usar la función correspondiente para cada tipo de dato.

br.ReadInt32(): Lee un int


br.ReadSingle(): Lee un float
br.ReadDouble(): Lee un double
br.ReadChar(): Lee un char
br.ReadBoolean(): Lee un bool
br.ReadString(): Lee una cadena
br.ReadDecimal(): Lee un decimal

Por ejemplo, para leer un entero:


int n = br.ReadInt32();

Si conocemos el número de datos que contiene el fichero, podemos hacer un bucle for
para irlos leyendo, pero si no lo conocemos, tendremos que usar una función especial
que nos avisa cuando hemos llegado al final del fichero. Para ficheros binarios es ditinta
que para ficheros de texto. En este caso se llama PeekChar y se usa de la siguiente
forma:
Programación Orientada a Objetos 22

while(br.PeekChar() != -1)
{
int n = br.ReadInt32();
...
}

Como de costumbre, no os olvidéis de cerrar el fichero.

Programación Orientada a Objetos


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.

Clases y Objetos
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.

Un objeto, por su parte, es el resultado de instanciar una clase. En este sentido, es


similar al concepto de variable.

Las clases y objetos se componen de diferentes miembros, que podrán ser:


- Atributos: se corresponden con los datos que guarda un objeto en un
determinado momento. Son similares a las variables pero se encuentran dentro
de un objeto. Un atributo puede ser de cualquier tipo de datos, incluyendo otros
objetos (incluso de la misma clase).
- Métodos: son un conjunto de instrucciones a las que se les asocia un nombre de
modo que si se desea ejecutarlas basta referenciarlas a través de dicho nombre.
Son equivalentes a las funciones pero dentro de un objeto. Dentro de estos
métodos es posible acceder con total libertad a la información almacenada en los
atributos pertenecientes a la clase dentro de la que el método se ha definido.
- Constructores: son un tipo de métodos especial que nos permiten inicializar
cada objeto.
- Propiedades: son similares a los métodos en el sentido de que contienen
instrucciones que se van a ejecutar, pero a la hora de usarlas en un programa se
comportan de manera parecida a los atributos, es decir, podemos leer datos y
escribir datos de ellas como si fueran variables. Sirven para encapsular la
información contenida en los atributos del objeto.

Conceptos fundamentales
La programación orientada a objetos introduce nuevos conceptos, que superan y
amplían conceptos antiguos ya conocidos. Entre ellos destacan los siguientes:
Programación Orientada a Objetos 23

Encapsulamiento: Significa reunir a todos los elementos que pueden


considerarse pertenecientes a una misma entidad, al mismo nivel de abstracción.
Esto permite aumentar la cohesión de los componentes del sistema.
Principio de ocultación: Cada objeto está aislado del exterior, es un módulo
natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica
cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las
propiedades de un objeto contra su modificación por quien no tenga derecho a
acceder a ellas, solamente los propios métodos internos del objeto pueden
acceder a su estado. Esto asegura que otros objetos no pueden cambiar el estado
interno de un objeto de maneras inesperadas, eliminando efectos secundarios e
interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso
directo a los datos internos del objeto de una manera controlada y limitando el
grado de abstracción. La aplicación entera se reduce a un agregado o
rompecabezas de objetos.
Polimorfismo: básicamente, consiste en que pueden existir dos o más métodos
con el mismo nombre dentro de una clase siempre y cuando tengan:
a) Diferente número de parámetros.
b) El mismo número de parámetros pero de pertenecientes a diferentes
tipos de datos.
A la hora de ejecutar el método, el compilador elegirá el más apropiado de entre
los que tienen el mismo nombre.
Herencia: las clases no están aisladas, sino que se relacionan entre sí, formando
una jerarquía de clasificación. Los objetos heredan las propiedades y el
comportamiento de todas las clases a las que pertenecen. La herencia organiza y
facilita el polimorfismo y el encapsulamiento permitiendo a los objetos ser
definidos y creados como tipos especializados de objetos preexistentes. Estos
pueden compartir (y extender) su comportamiento sin tener que volver a
implementarlo. Esto suele hacerse habitualmente agrupando los objetos en
clases y estas en árboles que reflejan un comportamiento común. Cuando un
objeto hereda de más de una clase se dice que hay herencia múltiple.

Control de Acceso a métodos y atributos


Para proteger el acceso a los diferentes atributos y también a los métodos, se definen
varios niveles de acceso que se asignaran a dichos atributos y métodos. Los niveles de
acceso son los siguientes:
- public: el acceso no está restringido. Todo el mundo puede acceder a los
métodos y atributos con total libertad.
- private: el acceso está restringido a la propia clase donde se define el método o
atributo, es decir, sólo se podrá acceder a un atributo o a un método desde los
propios métodos de la misma clase.
- protected: el acceso está limitado a la propia clase y a las clases que heredan de
ésta. Se usa combinado con la herencia.

Definición de una Clase en C#


La sintaxis básica para definir una clase es la que a continuación se muestra:
class <nombreClase>
{
Programación Orientada a Objetos 24

<miembros>
}

Dentro de la clase, definiremos los diferentes atributos, métodos y propiedades. Para


definir un atributo, usaremos la sintaxis:

<nivel_de_acceso> <tipo_de_dato> <nombre_del_atributo>;

Por ejemplo, si queremos definir un atributo privado de tipo entero y otro público de
tipo cadena, escribiremos:

private int entero;


public string cadena;

Si no especificamos el nivel de acceso, se sobreentiende que el atributo o método será


privado.
Para definir un método:

<nivel_de_acceso> <tipoDevuelto> <nombreMétodo> (<parametros>)


{
<instrucciones>
}

Por ejemplo:

public void InsertaValor(int dato)


{
...
}

Para acceder a un atributo o a un método de una objeto, usaremos el operador “.”:

objeto.cadena = “hola”;
objeto.InsertaValor(3);

Constructores
Los constructores inicializan el estado de un objeto a la hora de crearlo. Se definen de
manera similar a los métodos, sólo que no devuelven ningún valor (en teoría devuelven
un objeto de la misma clase, pero no hace falta indicarlo ni devolverlo con un return) y
tienen que tener el mismo nombre que la clase. Así, para definir un constructor para la
clase “prueba”, escribiremos:

public Prueba(int dato)


{
...
}

Gracias al polimorfismo, podemos definir varios constructores con diferentes


parámetros.
Para crear un nuevo objeto, deberemos llamar al constructor con el comando especial
new.

Prueba p = new Prueba(6);


Programación Orientada a Objetos 25

Los constructores se utilizan, generalmente, para darle valores iniciales a los atributos
del objeto. Al menos se debe crear un constructor por defecto (sin parámetros).

Propiedades
Las propiedades nos permiten acceder de manera controlada a los atributos de una clase.
Para ello, cuentan con dos métodos especiales, denominados set y get que hacen la
función de escribir un valor y leer un valor, respectivamente. Una propiedad se puede
definir como de sólo-lectura si sólo escribimos la cláusula get.
La sintaxis usada para definir una propiedad es la siguiente:

<nivel_de_acceso> <tipo> <nombre>


{
get
{
<instrucciones>
}

set
{
<instrucciones>
}
}

Por ejemplo, para definir una propiedad Dato, de tipo entero:

public int Dato


{
...
}

El tipo será normalmente el mismo que el del atributo, aunque a veces podemos hacer
una propiedad de tipo cadena, por ejemplo, para un atributo de tipo entero que nos
permite representar el valor de otra forma.

En la cláusula get, tendremos que devolver el valor adecuado usando return, de manera
similar a como lo haríamos en una función.

public int Dato


{
get
{
return variable;
}
}

En la cláusula set, usaremos una pseudo-variable especial denominada value en la que


nos llega el valor que se le pasa a la propiedad.

public int Dato


{
set
{
variable = value;

También podría gustarte