Integración de Sistemas El lenguaje de programación C# Integración de Sistemas Parte II. Diseño e implementación de aplicaciones Web con .NET Indice Curso 2008 - 2009 Introducción Operadores p Compilador C# Entrada / Salida por Consola Namespaces Sentencias Sistema de tipos unificado Colecciones Tipos predefinidos Generics Clases Estructuras (struct) Anexo I. Documentación XML en .NET NET Enumeraciones Interfaces 1 Integración de Sistemas Introducción C# es un lenguage OO usado para desarrollar aplicaciones en la plataforma .NET 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 g en lugar g de detalles de p programación g de bajo j nivel Introducción En C# todo es un objeto Curso 2008 - 2009 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) L ti Los tipos primitivos i iti sólo ól se ttratan t como objetos bj t cuando d lla situación it ió llo requiere, mientras tanto pueden aplicárseles optimizaciones específicas 2 Integración de Sistemas Introducción Hola 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 13. { 14. Console.WriteLine("Hello World!"); 15. Console.ReadLine(); 16. } 17. #endregion 18. } 19. } Introducción Hola 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 Curso 2008 - 2009 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 g sitáxis PascalCase ((e.g., g , FindByUserIdentifier(…)) y ( )) Los atributos siguen sitáxis camelCase (e.g., firstName) 3 Integración de Sistemas 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ón La clase System.Object Curso 2008 - 2009 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) 4 Integración de Sistemas Compilador C# Los archivos C# tienen extensión .cs Ubicación Compilador C# Sintaxis Opciones C:\windows\Microsoft.NET\Framework\vn.n.nnn\csc.exe csc [opciones] fich1.cs [, fich2.cs] /out:ficheroSalida /t:winexe /t:library /r:librería.dll /main:clase Por defecto se referencia a mscorlib.dll. ⇒ Todo esto se puede hacer desde el Visual Studio Namespaces Declaración: namespace <NombreEspacio> { <Definición clases> } Anidación de namespaces válida Referencia a namespaces externos using Alias: evitar conflictos entre namespaces Curso 2008 - 2009 NmbEspacio1.NmbEspacio2.NmbEspacio3; using <alias> = <NombreCompletoClase>; 5 Integración de Sistemas Namespaces using using i using using using System; S System.Collections.Generic; t C ll ti G i System.Text; System.Collections; System.IO; static void Main(string[] args) { string username; ArrayList namesCollection; using SC = System.Collections; using i SIO = S System.IO; t IO static void Main(string[] args) { string username; string filename SC.ArrayList namesCollection; filename = SIO.Path.Combine( ... ); ¿A qué namespace pertenece? Sistema de Tipos Unificado Tipos valor y referencia Curso 2008 - 2009 Valor Primitivos i t i 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]; 6 Integración de Sistemas Sistema de Tipos Unificado Boxing & Unboxing Los tipos valor (struct, enum, int…) pueden ser convertidos en tipos g (y referencia (y viceversa)) de forma automática mediante Boxing 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; Tipos predefinidos Curso 2008 - 2009 C# Reference object string object, 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(); 7 Integración de Sistemas Tipos predefinidos Tipo Descripción SByte Bytes con signo Byte Bytes sin signo Int16 Enteros cortos con signo UInt16 Enteros cortos sin signo Int32 UInt32 Bits Rango Alias [-128…127] sbyte 8 [0…255] byte 16 [-32.768…32.767] short 16 [0…65.535] ushort Enteros normales 32 [-2.147.483.648…2.147.483.647] int Enteros normales sin signo 32 [0…4.294.967.295] uint 8 [-9.223.372.036.854.775.808… Int64 Enteros largos long 64 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 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 object String Cadenas de caracteres Variable Valor máximo determinado por memoria Object Cualquier objeto Variable Cualquier objeto Tipos predefinidos Sufijos 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 S f Sufijos L (long, ulong), U (int, uint), UL (ulong) F (float), D (double), M (decimal) Ejemplo Curso 2008 - 2009 Foo(100) llama al primer método Foo(100L) llama al segundo método 8 Integración de Sistemas 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 Clases Constructores 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(); } } Curso 2008 - 2009 9 Integración de Sistemas Clases Constructores 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); } } Clases Constructores 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(); } Curso 2008 - 2009 10 Integración de Sistemas Clases Constructores 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 Clases Constructores 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"); } } Curso 2008 - 2009 11 Integración de Sistemas Clases Destructores Llamado automáticamente por Garbage Collector public class LogManager { ~LogManager() { logFile.WriteLine(System.DateTime.Now.ToString() + " Instance Disposed"); logFile.Close(); } } Llamada a Garbage Collector: System.GC.Collect() System GC Collect() No garantiza borrado de memoria Los destructores no se heredan Clases Campos constantes Se evalúan en tiempo de compilación Son implícitamente estáticas (error si se usa static explícitamente) Ejemplo public public public public const const const const string string double double VERSION = "1.0.0"; URI = "http://" + "www.google.es"; PI = 3.14159265358979; UNO = Math.Cos(0); //ERROR Ej Ejemplo l de d acceso desde d d código ódi externo: t MyClass.URI Curso 2008 - 2009 12 Integración de Sistemas Clases Campos de sólo lectura Similares a las constantes, pero… Se inicializan en tiempo p de ejecución j ((vs. compilación) p ) 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); Clases Properties Curso 2008 - 2009 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, d denominado i d Properties P ti 13 Integración de Sistemas Clases Properties 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; } << ... >> } Clases Properties Ej. Encapsulación sin properties. Acceso: public static void Main() { CircleWithGetSet circle = new CircleWithGetSet(); // Set circle.SetRadius(1); // Get Console.WriteLine("Radius: " + circle.GetRadius()); } Curso 2008 - 2009 14 Integración de Sistemas Clases Properties 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; } } << ... >> } Clases Properties Ej. Encapsulación con properties. Acceso: public static void Main() { CircleWithProperties circle = new CircleWithProperties(); // Set circle.Radius = 1; // Get Console.WriteLine("Radius: " + circle.Radius); } Curso 2008 - 2009 15 Integración de Sistemas Clases Properties 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 Clases Properties 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: public string Radius { get; set; } 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 { private get; set; } Curso 2008 - 2009 16 Integración de Sistemas Clases Properties Para ejemplo más complejos, debemos utilizar las propiedades “tradicionales” 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; } } } Clases Properties Es posible definir propiedades abstractas public abstract class AnAbstractClass { public abstract string AbstractProp { get; set; } << ... >> } Y también en Interfaces public interface IAnInterface { public string APropertie { get; set; } << ... >> } Curso 2008 - 2009 17 Integración de Sistemas Clases Mé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; } } Clases Métodos Modificadores de acceso private: protected: internal: Miembros accesibles desde la clase que los contiene o desde clases derivadas de ésta Miembros accesibles desde el mismo assembly protected internal: Mi b Miembros accesibles ibl d desde d ell mismo i assembly o clases l d derivadas i d d de lla clase l que llo contiene (protected + internal) public: Curso 2008 - 2009 Sólo código dentro de la misma clase contenedora tiene acceso a un miembro privado No hay restricciones de acceso 18 Integración de Sistemas 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 bli abstract b t t List<AccountVO> Li t<A tVO> Fi FindByUserIdentifier( dB U Id tifi ( 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) { <<...>> } } Curso 2008 - 2009 19 Integración de Sistemas 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) Curso 2008 - 2009 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 20 Integración de Sistemas 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, 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 Curso 2008 - 2009 21 Integración de Sistemas 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 q puede p dárseles cualquier q otro tipo p básico entero: int, byte, sbyte, short, ushort, uint, long, ulong Enumeraciones: ejemplo Declaración public enum MessageType : int { INFO = 1, WARNING = 2, ERROR = 3 } Uso MessageType messageType = MessageType.WARNING; MessageType WARNING; Curso 2008 - 2009 22 Integración de Sistemas 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 public interface IUserProfileDAO { // Interface methods void Create(...); void Delete(...); // Interface properties UserProfile LastUser { get; set; } } Implementación public class UserProfileDAO : IUserProfileDAO { } Curso 2008 - 2009 23 Integración de Sistemas Operadores Aritméticos Asignación +=, -=, *=, /=, %=, ++, -- Comparación +, -, *, /, % ==, !=, <, >, <=, >= Ló i Lógicos &, &&, |, ||, ~, !, ^ Operadores Obtención de información sobre tipos typeof(Type t) Obtiene el objeto System.Type para un tipo Type t = typeof(SampleClass); // Alternatively, you could use // SampleClass obj = new SampleClass(); // Type t = obj.GetType(); <expression> is <type> as Curso 2008 - 2009 Similar a proceso de casting, pero devuelve null en lugar de InvalidCastException 24 Integración de Sistemas Entrada / Salida por Consola System.Console Entrada Console.Read(); Console.ReadLine(); Console.ReadKey(); Salida Console.Write(); Console.WriteLine(); Entrada / Salida por Consola Salida con formato Opción 1 Console.Write("Text {n0:format}", var0); n0 representa las variables (comienzan en 0) format representa el formato (ver sgte. diapositiva) Ej: Opción 2 Console.Write("Text " + var0.ToString("format")) Si no se especifica formato, puede obviarse la llamada a ToString() Ej: Curso 2008 - 2009 Console.Write("Current Balance: {0:C}.", balance) Console.Write("Current Balance: " + balance.ToString("C")); 25 Integración de Sistemas Entrada / Salida por Consola Salida con formato Formatos predefinidos Número C D F P H Fecha Moneda Decimal Punto Fijo Porcentaje Hexadecimal S D t T F Short Date Long Date Short time Long Time Full Date Sentencias Curso 2008 - 2009 Condicionales Control de Excepciones p if try ...catch...finally switch throw Iterativas while do for foreach Otras lock using 26 Integración de Sistemas 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; } Curso 2008 - 2009 switch (str) { case "ABC": statements; break; case "XYZ": statements; break; default: statements; break; } 27 Integración de Sistemas Sentencias iterativas. while Sintaxis General while (condition) { <statements> } Puede incluir instrucciones break yy/o continue Sentencias iterativas. do...while Sintaxis General do { <statements> } while(condition) Curso 2008 - 2009 Puede incluir instrucciones break yy/o continue 28 Integración de Sistemas 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); } Curso 2008 - 2009 29 Integración de Sistemas 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 Curso 2008 - 2009 Puede haber varios bloques catch para gestionar diferentes tipos de excepciones Bl Bloque finally contiene ti código ódi que se ejecutará j t á siempre i 30 Integración de Sistemas 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"); } Curso 2008 - 2009 31 Integración de Sistemas Sentencias. using Objetos que deben limpiarse una vez usados, deberían implementar la interfaz System.IDisposable 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. using public 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 } Curso 2008 - 2009 32 Integración de Sistemas Colecciones interface IEnumerable { IEnumerator GetEnumerator(); } interface IEnumerator { object Current { get; } bool MoveNext(); void Reset(); } Colecciones: System.Collection Curso 2008 - 2009 Clases Interfaces ArrayList ICollection Hashtable IComparer DictionaryBase IDictionary SortedList IEnumerable Queue IEnumerator Stack IList 33 Integración de Sistemas Colecciones: ArrayList [Serializable] public class ArrayList : IList, ICollection, IEnumerable, ICloneable Propiedades Capacity Count Item[index] -- Indexer Colecciones: ArrayList Curso 2008 - 2009 Métodos Add(object) AddRange(Collection) Clear() Contains(object) IndexOf(object) Remove(object) RemoveAt(int) Sort() Reverse() GetEnumerator() 34 Integración de Sistemas 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 Curso 2008 - 2009 Propiedades Count IsFixedSize IsReadOnly Keys Values 35 Integración de Sistemas Colecciones: Hashtable Métodos Contains() ContainsKey(object) ContainsValue(object) GetHash(object) ... Colecciones: Hashtable Ejemplo public bli class l L 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); } } Curso 2008 - 2009 36 Integración de Sistemas Generics Característica de Common Language Runtime, que permite que las clases estructuras 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; private int count = 0; // array to store list elements // 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; } } } Curso 2008 - 2009 37 Integración de Sistemas Generics Uso de la lista implementada sin Generics List intList = new List(); intList.Add(1); intList.Add(2); intList.Add("Three"); // Argument is boxed // Argument is boxed // 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; private int count = 0; // array to store list elements // 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; } } } Curso 2008 - 2009 38 Integración de Sistemas Generics Uso de la lista implementada utilizando Generics List<int> intList = new List<int>(); intList.Add(1); intList.Add(2); //intList.Add("Three"); // No boxing // No boxing // Compile-time error int i = intList[0]; // No cast required Generics Curso 2008 - 2009 ¿Por qué utilizar Generics? Comprobación de tipos en tiempo de compilación Rendimiento (no boxing, no downcasts) Reduce la complejidad del código 39 Integración de Sistemas 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, y g, List<Order>> orderLookupTable; p 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); Curso 2008 - 2009 40 Integración de Sistemas Anexo I DOCUMENTACIÓN XML XM EN .NET NET Documentación XML en .NET Comentarios XML que emplean conjunto de etiquetas predefinidas Etiquetas de uso genérico Etiquetas relativas a excepciones Etiquetas relativas a métodos Etiquetas q relativas a formato Etiquetas relativas a propiedades Curso 2008 - 2009 <summary> <remarks> <see> <seealso> <permission> <exception> <param> <paramref> <returns> <example> <code> <c> <para> <value> 41 Integración de Sistemas Etiquetas XML Etiquetas 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 XML Etiquetas de uso genérico <see> <seealso> Indica hipervínculos a otros elementos de la documentación 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!"); } Curso 2008 - 2009 42 Integración de Sistemas Etiquetas XML Etiquetas 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 p g g p path){ ... } Etiquetas XML Etiquetas relativas a excepciones <exception> E Especifica ifi qué é excepciones i se pueden d producir d i en un método ét d /// <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; } } Curso 2008 - 2009 NOTA: para el desarrollo de la práctica, consideraremos el uso de esta etiqueta obligatorio 43 Integración de Sistemas Etiquetas XML Etiquetas relativas a métodos <param> <paramref> Documenta el significado de un parámetro de un método 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 XML Etiquetas relativas a formato <example> <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> Curso 2008 - 2009 Ejemplo sobre cómo usar el elemento al que precede Ayuda a separar la sección que se esté escribiendo en párrafos. 44 Integración de Sistemas Etiquetas XML Etiquetas 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 XML Etiquetas relativas a propiedades <value> En el caso de las propiedades propiedades, este elemento proporciona una descripción del valor que se está estableciendo o recuperando /// <summary> /// Almacena /// </summary> /// <value> Edad public int Edad { set { edad = get { return } Curso 2008 - 2009 la edad de una persona. de la persona representada </value> value; } edad; } 45