Integración de Sistemas
Curso 2009 - 2010 1
El lenguaje de programación C#
Integración de SistemasParte II. Diseño e implementación de aplicaciones Web con .NET
Indice
� Introducción
� Compilador C#
� Namespaces
� Sistema de tipos unificado
� Tipos predefinidos
� Clases
� Estructuras (struct)
� Enumeraciones
� Interfaces
� Operadores
� Entrada / Salida por Consola
� Sentencias
� Colecciones
� Generics
� Anexo I. Documentación XML en .NET
Integración de Sistemas
Curso 2009 - 2010 2
Introducción
� C# es un lenguage OO usado para desarrollar aplicaciones en la plataforma .NET
� Diseñado por Microsoft para combinar la potencia de C/C++, Java y la productividad de Visual Basic
� El objetivo de C# (y de la plataforma .NET) es reducir el tiempo de desarrollo
� Permitiendo a los desarrolladores invertir su tiempo trabajando en la lógica de negocio en lugar de detalles de programación de bajo nivel
Introducción
� En C# todo es un objeto
� Todo hereda de System.Object
� Es posible declarar un tipo primitivo (long) y trabajar con él de forma eficiente. Además, es posible asignarlo a un objeto y entonces será tratado como tal
� Incluye mecanismos transparentes de boxing y unboxing (se ilustra más adelante)
� Los tipos primitivos sólo se tratan como objetos cuando la situación lo requiere, mientras tanto pueden aplicárseles optimizaciones específicas
Integración de Sistemas
Curso 2009 - 2010 3
IntroducciónHola Mundo
1. using System;
2. namespace Es.UDC.DotNet.CSharpTutorial
3. {
4. /*
5. * Class HelloWorld
6. * Description: simple C# example
7. */
8. class HelloWorld
9. {
10. #region Test code. Uncomment for testing
11. // entry point
12. public static void Main()
13. {
14. Console.WriteLine("Hello World!");
15. Console.ReadLine();
16. }
17. #endregion
18. }
19. }
IntroducciónHola Mundo
� La línea "using System;" significa que accederemos a miembros del namespace System
� Static es un modificador que indica que se trata de un método de clase
� Main() es lo que es denomina el punto de entrada de la aplicación
� Necesita del modificador static para evitar que para llamarlo haya que crear algún objeto de la clase donde se haya definido.
� C# es sensible a las mayúsculas
� Los métodos y nombres de clases siguen sitáxis PascalCase (e.g., FindByUserIdentifier(…))
� Los atributos siguen sitáxis camelCase (e.g., firstName)
Integración de Sistemas
Curso 2009 - 2010 4
Introducción
� Sólo se admite herencia simple
� Se admite implementación de múltiples interfaces
� public class ClaseBase { … }
� public interface IInterfaz { … }
� public class ClaseDerivada : ClaseBase, IInterfaz { … }
� Para evitar que una clase se pueda extender se indica con: sealed
� Los métodos, por defecto, no pueden redefinirse (son sealed).
� Para poder redefinir un método
� Definirlo como virtual
� En la redefinición del método indicar override
IntroducciónLa clase System.Object
� Todos los tipos heredan de System.Object
� public virtual bool Equals(object o)
� public virtual int GetHashCode()
� public virtual string ToString()
� protected object MemberWiseClone()
� public System.Type GetType()
� protected virtual void Finalize()
� public static bool Equals(object o1, object o2)
� protected static bool ReferenceEquals(object o1, object o2)
Integración de Sistemas
Curso 2009 - 2010 5
Compilador C#
� Los archivos C# tienen extensión .cs
� Ubicación Compilador C#
� C:\windows\Microsoft.NET\Framework\vn.n.nnn\csc.exe
� Sintaxis
� csc [opciones] fich1.cs [, fich2.cs]
� Opciones
� /out:ficheroSalida
� /t:winexe
� /t:library
� /r:librería.dll
� Por defecto se referencia a mscorlib.dll.
� /main:clase
⇒ Todo esto se puede hacer desde el Visual Studio
Namespaces
� Declaración:
namespace <NombreEspacio>
{
<Definición clases>
}
� Anidación de namespaces válida
� NmbEspacio1.NmbEspacio2.NmbEspacio3;
� Referencia a namespaces externos
� using
� Alias: evitar conflictos entre namespaces
� using <alias> = <NombreCompletoClase>;
Integración de Sistemas
Curso 2009 - 2010 6
Namespaces
¿A qué namespace pertenece?
using SC = System.Collections;
using SIO = System.IO;
static void Main(string[] args)
{
string username;
string filename
SC.ArrayList namesCollection;
filename = SIO.Path.Combine( ... );
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
static void Main(string[] args)
{
string username;
ArrayList namesCollection;
Sistema de Tipos UnificadoTipos valor y referencia
� Valor
� Primitivos int i;
� Enumeraciones enum State { Off, On }
� Estructuras struct Point { int x, y; }
� Referencia
� Raíz object
� String string
� Clases class Foo : Bar, IFoo {...}
� Interfaces interface IFoo : IBar {...}
� Arrays string[] a = new string[10];
Integración de Sistemas
Curso 2009 - 2010 7
Sistema de Tipos UnificadoBoxing & Unboxing
� Los tipos valor (struct, enum, int…) pueden ser convertidos en tipos referencia (y viceversa) de forma automática mediante Boxing (y Unboxing)
� Boxing: � Encapsulación de tipo valor en tipo referencia
� Ej: la siguiente sentencia “envuelve” el valor 3 en un objeto
object obj = 3;
� Unboxing� Proceso inverso al boxing. Tratamiento de tipo referencia como tipo valor
� Ej.: la siguiente sentencia “desenvuelve” el valor
int x = (int) obj;
Sistema de Tipos UnificadoBoxing & Unboxing
� Boxing
� Reserva espacio
� Copia valor en ese espacio
� Unboxing
� Chequea tipo dato
� Desenvuelve el valor
int i = 123;
object o = i; // boxing
int j = (int)o; // unboxing
Pila (stack) Montón (heap)
123
i
o
int
123
(i boxed)
123
j
Integración de Sistemas
Curso 2009 - 2010 8
Tipos predefinidos
� C#
� Reference object, string
� Signed sbyte, short, int, long
� Unsigned byte, ushort, uint, ulong
� Character char
� Floating-point float, double, decimal
� Logical bool
� Importante: realmente se trata de alias a tipos proporcionados por el sistema
� int es un alias a System.Int32
� Válido: int entero = 100;
entero.ToString();
Tipos predefinidosTipo Descripción Bits Rango 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…
9.223.372.036.854.775.807]
long
UInt64 Enteros largos sin signo 64 [0…18.446.744.073.709.551.615] ulong
Single Reales con 7 dígitos 32 [±1,5×10-45…±3,4×1038] float
Double Reales de 15-16 dígitos 64 [±5,0×10-324 …± 1,7×10308] double
Decimal Reales de 28-29 dígitos significativos 128 [±1,0×10-28 …±7,9×1028] decimal
Boolean Valores lógicos 32 true, false bool
Char Caracteres Unicode 16 [‘\u0000’, ‘\uFFFF’] char
String Cadenas de caracteres VariableValor máximo determinado por memoria
string
Object Cualquier objeto Variable Cualquier objeto object
Integración de Sistemas
Curso 2009 - 2010 9
Tipos predefinidosSufijos
� Problema:
� public static void Foo(int x){...}
� public static void Foo(long x){...}
� ¿Llamada Foo(100)?
� Tipo del literal entero es el primero que permita almacenarlo: int, uint, long, ulong
� Foo(100) llama al primer método
� Sufijos
� L (long, ulong), U (int, uint), UL (ulong)
� F (float), D (double), M (decimal)
� Ejemplo
� Foo(100L) llama al segundo método
Clases
� Las clases C# son similares a las clases Java
� C# permite los siguientes miembros de clase (entre otros)
� Constructores
� Destructores
� Campos
� Propiedades
� Métodos
Integración de Sistemas
Curso 2009 - 2010 10
ClasesConstructores
� Llamadas entre constructores: this
class SuperClass
{
private string argument1;
public SuperClass() : this("<Default arg1>") { }
public SuperClass(string arg1)
{
this.argument1 = arg1;
Console.WriteLine("Arguments: " + argument1);
}
public static void Main()
{
// Creating a SuperClass instance
SuperClass sc = new SuperClass();
/* Shows:
* Arguments: <Default arg1>
*/
Console.ReadLine();
}
}
ClasesConstructores
� Llamadas a la clase base: base
class ChildClass : SuperClass
{
private string argument2;
public ChildClass() : this("<Default arg2>") { }
public ChildClass(string arg2)
{
this.argument2 = arg2;
Console.WriteLine("Arguments: " + argument2);
}
public ChildClass(string arg1, string arg2)
: base(arg1)
{
this.argument2 = arg2;
Console.WriteLine("Arguments: " + argument2);
}
}
Integración de Sistemas
Curso 2009 - 2010 11
ClasesConstructores
� Ejemplo
public static void Main()
{
SuperClass sc = new SuperClass();
/* Shows:
* Arguments: <Default arg1>
*/
ChildClass cc = new ChildClass();
/* Shows:
* Arguments: <Default arg1>
* Arguments: <Default arg2>
*/
ChildClass cc2 = new ChildClass("1", "2");
/* Shows:
* Arguments: 1
* Arguments: 2
*/
Console.ReadLine();
}
ClasesConstructores estáticos
� Permiten inicialización de código, que se realizará una única vez para la clase
� Garantizan la ejecución antes de:
� La creación de la primera instancia de la clase
� El acceso a cualquier miembro estático
� Un único constructor estático por clase
� No pueden tener parámetros
� Equivalente a bloque static de Java
Integración de Sistemas
Curso 2009 - 2010 12
ClasesConstructores estáticos
� Llamada automática al acceder por primera vez a la clase
public class LogManager
{
private static FileStream logFile;
// Static Constructor opens the file
static LogManager()
{
logFile = File.Open("logFile.dat", FileMode.Create);
}
public LogManager()
{
logFile.WriteLine(System.DateTime.Now.ToString() +
" Instance created");
}
}
ClasesDestructores
� Llamado automáticamente por Garbage Collector
� Llamada a Garbage Collector: System.GC.Collect()
� No garantiza borrado de memoria
� Los destructores no se heredan
public class LogManager
{
~LogManager()
{
logFile.WriteLine(System.DateTime.Now.ToString() +
" Instance Disposed");
logFile.Close();
}
}
Integración de Sistemas
Curso 2009 - 2010 13
ClasesCampos constantes
� Se evalúan en tiempo de compilación
� Son implícitamente estáticas (error si se usa staticexplícitamente)
� Ejemplo
� Ejemplo de acceso desde código externo:
public const string VERSION = "1.0.0";
public const string URI = "http://" + "www.google.es";
public const double PI = 3.14159265358979;
public const double UNO = Math.Cos(0); //ERROR
MyClass.URI
ClasesCampos de sólo lectura
� Similares a las constantes, pero…
� Se inicializan en tiempo de ejecución (vs. compilación)
� Evitan necesidad de recompilar clientes
� Pueden ser estáticas o por instancia
� Una vez inicializadas, no pueden modificarse
public readonly double UNO = Math.Cos(0);
public static readonly double CERO = Math.Sin(0);
Integración de Sistemas
Curso 2009 - 2010 14
ClasesProperties
� Frecuentemente, en una clase, declaramos un atributo como privado y proporcionamos métodos GetXXX / SetXXX para acceder a él. Es un tipo de encapsulación.
� Buena práctica de programación
� Los atributos no son accesibles desde fuera de la clase
� Es necesario utilizar los métodos GetXXX / SetXXX
� .NET proporciona un mecanismo para encapsular atributos, denominado Properties
ClasesProperties
� Ej. Encapsulación sin properties. Definición:
/* Traditional Encapsultation Without Properties */
class CircleWithGetSet
{
private double radius;
public double GetRadius()
{
return radius;
}
public void SetRadius(double radius)
{
this.radius = radius;
}
<< ... >>
}
Integración de Sistemas
Curso 2009 - 2010 15
ClasesProperties
� Ej. Encapsulación sin properties. Acceso:
public static void Main()
{
CircleWithGetSet circle = new CircleWithGetSet();
// Set
circle.SetRadius(1);
// Get
Console.WriteLine("Radius: " + circle.GetRadius());
}
ClasesProperties
� Ej. Encapsulación con properties. Definición:
/* Encapsulating Type State with Properties */
class CircleWithProperties
{
private double radius;
public double Radius
{ get { return radius; }
/* NOTE: 'value' is a C# reserved word. */
set { radius = value; } }
<< ... >>
}
Integración de Sistemas
Curso 2009 - 2010 16
ClasesProperties
� Ej. Encapsulación con properties. Acceso:
public static void Main()
{
CircleWithProperties circle = new CircleWithProperties();
// Set
circle.Radius = 1;
// Get
Console.WriteLine("Radius: " + circle.Radius);
}
ClasesProperties
� Una “propiedad” puede ser de sólo lectura / sólo escritura. Basta con definir únicamente el accessor get / set
� Son “PascalCase”
� Externamente son accedidas como si de un campo público se tratase, pero internamente es posible asociar código a ejecutar en cada asignación o lectura de su valor
Integración de Sistemas
Curso 2009 - 2010 17
ClasesProperties
� C# 3.0 incorpora Automatic Properties
� No es necesario declarar explícitamente el atributo privado ni las operaciones de asignación y retorno
� El compilador los generará automáticamente
� Para el ejemplo anterior, bastaría escribir:
� Es obligatorio definir ambos métodos de acceso (accessors) get / set. Sin embargo pueden construirse properties de sólo lectura / solo escritura utilizando el modificador de acceso private
public string Radius { get; set; }
public string Radius { private get; set; }
ClasesProperties
� Para ejemplo más complejos, debemos utilizar las propiedades “tradicionales”
� Atajo: En VS, sobre el atributo privado:
� Refactor > Encapsulate Field ⇒ Genera gódigo base, que podemos completar
public double Radius
{
private get { return radius; }
set
{
if (value < 0)
{
this.radius = 0;
}
else
{
this.radius = value;
}
}
}
Integración de Sistemas
Curso 2009 - 2010 18
ClasesProperties
� Es posible definir propiedades abstractas
� Y también en Interfaces
public interface IAnInterface
{
public string APropertie { get; set; }
<< ... >>
}
public abstract class AnAbstractClass
{
public abstract string AbstractProp { get; set; }
<< ... >>
}
ClasesMétodos
� Redefinición de métodos: virtual & override
public class Product
{ public virtual String GetReference()
{ return barCode;
} }
public class Book : Product
{
public override String GetReference() { return ISBN;
}
}
Integración de Sistemas
Curso 2009 - 2010 19
ClasesMétodos
� Modificadores de acceso
� private:
� Sólo código dentro de la misma clase contenedora tiene acceso a un miembro privado
� protected:
� Miembros accesibles desde la clase que los contiene o desde clases derivadas de ésta
� internal:
� Miembros accesibles desde el mismo assembly
� protected internal:
� Miembros accesibles desde el mismo assembly o clases derivadas de la clase que lo contiene (protected + internal)
� public:
� No hay restricciones de acceso
ClasesMétodos
� Paso de parámetros
� Tipos primitivos se pasan por valor
� Para pasar por referencia: refpublic class Util
{
public void Swap(ref int x, ref int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
}
Integración de Sistemas
Curso 2009 - 2010 20
Clases Abstractas
� Una clase abstracta no puede ser instanciada
� Está pensada para ser usada como clase base
� Puede contener métodos abstractos y no abstractos
� Similar a una interfaz
� No puede ser sealed
� Todo método definido como abstract es implícitamente virtual
Clases Abstractas
public abstract class AbstractSQLAccountDAO : IAccountDAO
{
public abstract List<AccountVO> FindByUserIdentifier(
DbConnection connection, DbTransaction transaction,
long userIdentifier, int startIndex, int count);
<<...>>
}
public class CCSqlServerAccountDAO : AbstractSQLAccountDAO
{
public override List<AccountVO> FindByUserIdentifier(
DbConnection connection, DbTransaction transaction,
long userIdentifier, int startIndex, int count)
{
<<...>>
}
}
Integración de Sistemas
Curso 2009 - 2010 21
Clases Sealed
� Es una clase que no se puede extender
� Las clases sealed no pueden ser abstractas
� Todas las estructuras son sealed
� ¿Por qué "cerrar" una clase?
� Para prevenir que sea extendida de forma no intencionada
Estructuras (struct)
� Similares a las clases pero …
� Requisitos de almacenamiento menores
� Paso por valor, no referencia
� No pueden extender ningún tipo (heredan directamente de System.ValueType)
� Ningún tipo puede heredar de ellas
� Pensadas para light weight objects
� Uso más eficiente de la memoria
� Ejemplos: Complex, Point, Color
� La mayoría de los tipos básicos (excepto string y object) implementados como structs
Integración de Sistemas
Curso 2009 - 2010 22
Estructuras (struct)
� Mismos miembros que una clase
� Modificadores de acceso válidos
� private (defecto), internal o public
Estructuras (struct)
public struct Point
{
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int X {
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
<<...>>
}
Point p = new Point(2, 5); p.X += 100;
int px = p.X; // px = 102
Integración de Sistemas
Curso 2009 - 2010 23
Enumeraciones
� Estructuras con explicitación de elementos
� Evitan uso números mágicos
� Facilitan legibilidad del código
� Participan en el mecanismo de comprobación de tipos
� Sólo podrán contener campos públicos constantes y estáticos
� El tipo por defecto de las constantes que forman una enumeración es int, aunque puede dárseles cualquier otro tipo básico entero:
� int, byte, sbyte, short, ushort, uint, long, ulong
Enumeraciones: ejemplo
� Declaración
� Uso
public enum MessageType : int
{
INFO = 1,
WARNING = 2,
ERROR = 3
}
MessageType messageType = MessageType.WARNING;
Integración de Sistemas
Curso 2009 - 2010 24
Interfaces
� Similar a la definición de un contrato
� Pueden incluir métodos, propiedades, eventos
� No pueden incluir operadores, constructores o destructores.
� Cualquier implementación de la interfaz debe dar soporte a todas las partes del contrato
� Miembros de una interfaz son por defecto public y abstract
� Proporcionan polimorfismo
� Diferentes clases y estructuras pueden implementar la misma interfaz
� No contienen implementación
Interfaces
� Declaración
� Implementación
public interface IUserProfileDAO
{
// Interface methods
void Create(...);
void Delete(...);
// Interface properties
UserProfile LastUser { get; set; }
}
public class UserProfileDAO : IUserProfileDAO { }
Integración de Sistemas
Curso 2009 - 2010 25
Operadores
� Aritméticos
� +, -, *, /, %
� Asignación
� +=, -=, *=, /=, %=, ++, --
� Comparación
� ==, !=, <, >, <=, >=
� Lógicos
� &, &&, |, ||, ~, !, ^
Operadores
� Obtención de información sobre tipos
� typeof(Type t)
� Obtiene el objeto System.Type para un tipo
� <expression> is <type>
� as
� Similar a proceso de casting, pero devuelve null en lugar de InvalidCastException
Type t = typeof(SampleClass);
// Alternatively, you could use
// SampleClass obj = new SampleClass();
// Type t = obj.GetType();
Integración de Sistemas
Curso 2009 - 2010 26
Entrada / Salida por Consola
� System.Console
� Entrada
� Console.Read();
� Console.ReadLine();
� Console.ReadKey();
� Salida
� Console.Write();
� Console.WriteLine();
� Opción 1
� Console.Write("Text {n0:format}", var0);
� n0 representa las variables (comienzan en 0)
� format representa el formato (ver sgte. diapositiva)
� Ej:
� Console.Write("Current Balance: {0:C}.", balance)
� Opción 2
� Console.Write("Text " + var0.ToString("format"))
� Si no se especifica formato, puede obviarse la llamada a ToString()
� Ej:
� Console.Write("Current Balance: " + balance.ToString("C"));
Entrada / Salida por ConsolaSalida con formato
Integración de Sistemas
Curso 2009 - 2010 27
Entrada / Salida por ConsolaSalida con formato
� Formatos predefinidos
� Número
C MonedaD DecimalF Punto FijoP PorcentajeH Hexadecimal
� Fecha
S Short DateD Long Datet Short timeT Long TimeF Full Date
Sentencias
� Condicionales
� if
� switch
� Iterativas
� while
� do
� for
� foreach
� Control de Excepciones
� try ...catch...finally
� throw
� Otras
� lock
� using
Integración de Sistemas
Curso 2009 - 2010 28
Sentencias condicionales. if
� Sintaxis General
if (condition)
<statementsIF>
else
<statementsELSE>
Sentencias condicionales. switch
� Sintaxis General
� ¡Obligatorio incluir break al final de cada rama!
switch (i) {
case 1:
statements;
break;
case 2:
statements;
break;
default:
statements;
break;
}
switch (str) {
case "ABC":
statements;
break;
case "XYZ":
statements;
break;
default:
statements;
break;
}
Integración de Sistemas
Curso 2009 - 2010 29
Sentencias iterativas. while
� Sintaxis General
while (condition) {
<statements>
}
� Puede incluir instrucciones break y/o continue
Sentencias iterativas. do...while
� Sintaxis General
do {
<statements>
} while(condition)
� Puede incluir instrucciones break y/o continue
Integración de Sistemas
Curso 2009 - 2010 30
Sentencias iterativas. for
� Sintaxis General
for (initialize-statement;
condition;
increment-statement)
{
statements;
}
� Puede incluir instrucciones break y/o continue
Sentencias iterativas. foreach
� Sintaxis General
foreach (<Type> <e> in <collection>) {
<statements>
}
� Ejemplo
String[] daysOfWeek = { "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday" };
// Print the days of the week
foreach (string day in daysOfWeek)
{
Console.WriteLine(day);
}
Integración de Sistemas
Curso 2009 - 2010 31
Sentencias. Gestión de Excepciones
� Las excepciones son los mecanismos C# para gestionar errores inesperados
� Mejor que devolver valor de estado
� No pueden ser ignoradas
� No tienen porque gestionarse en el punto en el que ocurren
� Pueden usarse incluso donde no se devuelven valores (e.g. en el acceso a una propiedad)
� Se proporcionan excepciones estándar
Sentencias. Gestión de Excepciones
� Sentencia try...catch...finally
� Bloque try contiene código que podría lanzar una excepción
� Bloque catch gestiona la excepción
� Puede haber varios bloques catch para gestionar diferentes tipos de excepciones
� Bloque finally contiene código que se ejecutará siempre
Integración de Sistemas
Curso 2009 - 2010 32
Sentencias. Gestión de Excepciones
� Sentencia throw lanza una excepción
� Una excepción se representa como una instancia de System.Exception o una clase derivada
� Contiene información sobre la excepción
� Propiedades
� Message
� StackTrace
� InnerException
� Es posible relanzar una excepción, o capturarla y lanzar otra
Sentencias. Gestión de Excepciones
try
{
Console.WriteLine("try");
throw new Exception("Message");
}
catch (ArgumentNullException e)
{
Console.WriteLine("Caught null argument");
}
catch (Exception e)
{
Console.WriteLine("catch");
Console.WriteLine("Message: " + e.Message);
Console.WriteLine("StackTrace: " + e.StackTrace);
}
finally
{
Console.WriteLine("finally");
}
Integración de Sistemas
Curso 2009 - 2010 33
Sentencias. lock
� Permite definir regiones críticas dentro de aplicaciones multithreading
� Previene la corrupción de datos
� La sentencia lock proporciona exclusión mutua
� Bloquea acceso a la instancia mientras no finalice la operación
� Emplea la clase System.Threading.Monitor
Sentencias. lock
public class CheckingAccount
{
decimal balance;
public void Deposit(decimal amount)
{
lock (this)
{
balance += amount;
}
}
public void Withdraw(decimal amount)
{
lock (this)
{ balance -= amount;
}
}
}
Integración de Sistemas
Curso 2009 - 2010 34
Sentencias. using
� Objetos que deben limpiarse una vez usados, deberían implementar la interfaz System.IDisposable
� Único método: Dispose()
� Sentencia using permite crear una instancia, emplearla y asegurar que tras ello el método Dispose() se llama
� Similar a bloque finally en la gestión de excepciones
Sentencias. usingpublic class MyResource : IDisposable
{
public void MyResource()
{
// Acquire valuable resource
}
public void Dispose()
{
// Release valuable resource
}
public void DoSomething()
{
// Do something
}
}
<<...>>
static void Main()
{
using (MyResource r = new MyResource())
{
r.DoSomething();
} // r.Dispose() is called
}
Integración de Sistemas
Curso 2009 - 2010 35
Colecciones
interface IEnumerable
{
IEnumerator GetEnumerator();
}
interface IEnumerator
{ object Current { get; }
bool MoveNext();
void Reset();
}
Colecciones: System.Collection
� Clases
� ArrayList
� Hashtable
� DictionaryBase
� SortedList
� Queue
� Stack
� Interfaces
� ICollection
� IComparer
� IDictionary
� IEnumerable
� IEnumerator
� IList
Integración de Sistemas
Curso 2009 - 2010 36
Colecciones: ArrayList
[Serializable]
public class ArrayList : IList, ICollection,
IEnumerable, ICloneable
� Propiedades
� Capacity
� Count
� Item[index] -- Indexer
Colecciones: ArrayList
� Métodos
� Add(object)
� AddRange(Collection)
� Clear()
� Contains(object)
� IndexOf(object)
� Remove(object)
� RemoveAt(int)
� Sort()
� Reverse()
� GetEnumerator()
Integración de Sistemas
Curso 2009 - 2010 37
Colecciones: ArrayList
ArrayList months = new ArrayList();
// Populate ArrayList...
months.Add("January"); <<...>>
months.Add("December");
// Access data with IEnumerator...
IEnumerator enumerator = months.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
// Access data with foreach
foreach (String month in months)
{
Console.WriteLine(month);
}
Colecciones: Hashtable
� Representa una colección de pares de clave y valor organizados en función del código hash de la clave
[Serializable]
public class Hashtable : IDictionary, ICollection, IEnumerable,
ISerializable, IDeserializationCallback, ICloneable
� Propiedades
� Count
� IsFixedSize
� IsReadOnly
� Keys
� Values
Integración de Sistemas
Curso 2009 - 2010 38
Colecciones: Hashtable
� Métodos
� Contains()
� ContainsKey(object)
� ContainsValue(object)
� GetHash(object)
� ...
Colecciones: Hashtable
� Ejemplopublic class Languages {
private static readonly Hashtable LANGUAGES = new Hashtable();
private static readonly ArrayList LANGUAGES_en = new ArrayList();
private static readonly ArrayList LANGUAGES_es = new ArrayList();
// static constructors initializes hashtable values
static Languages()
{
// ArrayLists stores the ListBox information
LANGUAGES_en.Add(new ListItem("English", "en"));
LANGUAGES_en.Add(new ListItem("Spanish", "es"));
LANGUAGES_es.Add(new ListItem("Inglés", "en"));
LANGUAGES_es.Add(new ListItem("Español", "es"));
//Key: "en" Value: ArrayList with english information
LANGUAGES.Add("en", LANGUAGES_en);
//Key: "es" Value: ArrayList with spanish information
LANGUAGES.Add("es", LANGUAGES_es);
}
}
Integración de Sistemas
Curso 2009 - 2010 39
Generics
� Característica de Common Language Runtime, que permite que las clases, estructuras, interfaces y métodos tengan parámetros de tipo genérico para los tipos de datos que almacenan y manipulan
� Los tipos genéricos son una forma de tipos parametrizados
Generics
� Ejemplo sin utilizar Generics
public class List
{
private object[] elements; // array to store list elements private int count = 0; // number of elements in the list
<<...>>
public void Add(object element)
{
if (count == elements.Length) {
Resize();
} elements[count++] = element;
}
/* Allows indexer access to class List */ public object this[int index]
{
get { return elements[index]; } set { elements[index] = value; }
}
}
Integración de Sistemas
Curso 2009 - 2010 40
Generics
� Uso de la lista implementada sin Generics
List intList = new List();
intList.Add(1); // Argument is boxed
intList.Add(2); // Argument is boxed
intList.Add("Three"); // Should be an error
int i = (int)intList[0]; // Cast required
Generics
� Implementación de la clase Lista utilizando Generics
public class List<ItemType>
{
private ItemType[] elements; // array to store list elements
private int count = 0; // number of elements in the list
<<...>>
public void Add(ItemType element)
{
if (count == elements.Length)
{
Resize();
}
elements[count++] = element;
}
/* Allows indexer access to class List */
public ItemType this[int index]
{
get { return elements[index]; }
set { elements[index] = value; }
} }
Integración de Sistemas
Curso 2009 - 2010 41
Generics
� Uso de la lista implementada utilizando Generics
List<int> intList = new List<int>();
intList.Add(1); // No boxing
intList.Add(2); // No boxing
//intList.Add("Three"); // Compile-time error
int i = intList[0]; // No cast required
Generics
� ¿Por qué utilizar Generics?
� Comprobación de tipos en tiempo de compilación
� Rendimiento (no boxing, no downcasts)
� Reduce la complejidad del código
Integración de Sistemas
Curso 2009 - 2010 42
Generics
� Los tipos genéricos pueden aplicarse a
� Clases, estructuras, interfaces, …
class Dictionary<KeyType, ValueType> {...}
struct Pair<FirstType, SecondType> {...}
interface IComparer<T> {...}
<< ... >>
Dictionary<string, Customer> customerLookupTable;
Dictionary<string, List<Order>> orderLookupTable;
Dictionary<int, string> numberSpellings;
Generics
� Los tipos genéricos pueden aplicarse a
� … y métodos
class Array {public static T[] Create<T>(int size) {
return new T[size];}
public static void Sort<T>(T[] array) {...
}}
<< ... >>
string[] names = Array.Create<string>(3);names[0] = "Jones";names[1] = "Anderson";names[2] = "Williams";Array.Sort(names);
Integración de Sistemas
Curso 2009 - 2010 43
DOCUMENTACIÓN XML EN .NETAnexo I
Documentación XML en .NET
� Comentarios XML que emplean conjunto de etiquetas predefinidas
� Etiquetas de uso genérico
� <summary> <remarks> <see> <seealso> <permission>
� Etiquetas relativas a excepciones
� <exception>
� Etiquetas relativas a métodos
� <param> <paramref> <returns>
� Etiquetas relativas a formato
� <example> <code> <c> <para>
� Etiquetas relativas a propiedades
� <value>
Integración de Sistemas
Curso 2009 - 2010 44
Etiquetas XMLEtiquetas de uso genérico
� <summary>
� Indica un resumen sobre el significado del elemento al que precede
� Se puede emplear junto con la etiqueta <remarks> para añadir información complementaria sobre el propio elemento.
///<summary>
/// Esta clase es de muestra para la documentación
///</summary>
///<remarks> Esta clase no realiza ninguna acción, sólo
/// sirve de muestra</remarks>
public class Documentacion
{
public Documentacion()
{
// TODO: Add constructor logic here
}
}
Etiquetas XMLEtiquetas de uso genérico
� <see>
� Indica hipervínculos a otros elementos de la documentación
� <seealso>
� Indica un elemento cuya documentación guarda relación con la del elemento al que precede
� Ambas etiquetas carecen de contenido y el nombre del elemento al que remiten se indica en su atributo cref.
/// <summary>
/// Muestra por la salida estándar el mensaje ¡Hola!.
/// Si no sabe como se escribe en pantalla puede consultar la
/// documentación del método <see cref="System.Console.WriteLine"/>.
/// </summary>
/// <seealso cref="System.Console"/>
public static void Saluda()
{
Console.WriteLine("¡Hola!");
}
Integración de Sistemas
Curso 2009 - 2010 45
Etiquetas XMLEtiquetas de uso genérico
� <permission>
� Indica qué permiso necesita un elemento para poder funcionar
� Atributo cref suele usarse para indicar el tipo del permiso.
/// <summary> Método para guardar en disco </summary>
/// <permission
/// cref="System.Security.Permissions.FileIOPermission">
/// Debe de tener permisos de escritura en la
/// ruta especificada
/// </permission>
public void SaveSomething(String path){ ... }
Etiquetas XMLEtiquetas relativas a excepciones
� <exception>
� Especifica qué excepciones se pueden producir en un método
� NOTA: para el desarrollo de la práctica, consideraremos el uso de esta etiqueta obligatorio
/// <exception cref="ConfigurationErrorsException"> Se produce esta
/// excepción cuando el parámetro especificado no está definido
/// </exception>
public String GetParameter(String paramName)
{
try
{
String paramValue = ConfigurationManager.
AppSettings["nombreParametro"];
<< ... >>
}
catch (ConfigurationErrorsException ex)
{
throw ex;
}
}
Integración de Sistemas
Curso 2009 - 2010 46
Etiquetas XMLEtiquetas relativas a métodos
� <param>
� Documenta el significado de un parámetro de un método
� <paramref>
� Referencia a parámetros de métodos
� <returns>
� Especifica el valor de retorno de un método
/// <summary>
/// Método que muestra por pantalla un texto con un determinado color
/// </summary>
/// <param name="texto"> Texto a mostrar </param>
/// <param name="color">
/// Color con el que mostrar el <paramref name="texto"/> indicado
/// </param>
/// <returns> Indica si el método se ha ejecutado con éxito o no </returns>
Boolean MuestraTexto(string texto, Color color) { ... }
Etiquetas XMLEtiquetas relativas a formato
� <example>
� Ejemplo sobre cómo usar el elemento al que precede
� <code>
� Se emplea dentro de etiquetas <example>
� Delimita textos que han de ser considerados fragmentos de código fuente
� <c>
� Indica que el texto dentro de una descripción debe ser marcado como código
� <para>
� Ayuda a separar la sección que se esté escribiendo en párrafos.
Integración de Sistemas
Curso 2009 - 2010 47
Etiquetas XMLEtiquetas relativas a formato
///<summary>
/// <para>Crea una nueva instancia de la clase Cliente</para>
/// <para>Otro parrafo</para>
///</summary>
///<example> Ejemplo de cómo realizar la instancia del objeto
/// <c>Cliente</c>
/// <code>
/// Cliente objCliente = new Cliente();
/// </code>
///</example>
Etiquetas XMLEtiquetas relativas a propiedades
� <value>
� En el caso de las propiedades, este elemento proporciona una descripción del valor que se está estableciendo o recuperando
/// <summary>
/// Almacena la edad de una persona.
/// </summary>
/// <value> Edad de la persona representada </value>
public int Edad
{
set { edad = value; }
get { return edad; }
}