Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2. 3.
Nota El IDE de Visual Studio 2005 para C# y Visual Basic solo se puede utilizar para crear ensamblados de un solo archivo. Si se desea crear ensamblados de mltiples archivos, se deben usar compiladores de la lnea de comandos o Visual Studio 2005 con Visual C++.
El ejemplo siguiente muestra el paso 1 del procedimiento anterior, compilando los archivos con espacios de nombres a los que hacen referencia otros archivos. Este ejemplo comienza con algo de cdigo sencillo para el archivo Stringer. Stringer tiene un espacio de nombres llamado myStringer con una clase llamada Stringer. La clase Stringer contiene un mtodo denominado StringerMethod que escribe una nica lnea en la consola. Visual Basic
' Assembly building example in the .NET Framework. Imports System Namespace myStringer Public Class Stringer Public Sub StringerMethod() System.Console.WriteLine("This is a line from StringerMethod.") End Sub End Class End Namespace
C#
// Assembly building example in the .NET Framework. using System; namespace myStringer {
public class Stringer { public void StringerMethod() { System.Console.WriteLine("This is a line from StringerMethod."); } } }
Visual C++
// Assembly building example in the .NET Framework. using namespace System; namespace myStringer { public ref class Stringer { public: void StringerMethod() { System::Console::WriteLine("This is a line from StringerMethod."); } }; }
C#
Visual C++
Si se especifica el parmetro module con la opcin de compilador /t: se indica que el archivo se debe compilar como un mdulo y no como un ensamblado. El compilador produce un mdulo denominado Stringer.netmodule, que se puede agregar a un ensamblado.
En el paso dos del procedimiento anterior, se deben compilar los mdulos con referencias a otros mdulos. En este paso se usa la opcin de compilador /addmodule. En el siguiente ejemplo, un mdulo de cdigo denominado Client tiene un mtodo Mainde punto de entrada que hace referencia a un mtodo del mdulo Stringer.dll creado en el paso 1. En el siguiente ejemplo se muestra el cdigo de Client. Visual Basic
Imports System Imports myStringer 'The namespace created in Stringer.netmodule. Class MainClientApp ' Static method Main is the entry point method. Public Shared Sub Main() Dim myStringInstance As New Stringer() Console.WriteLine("Client code executes") myStringInstance.StringerMethod() End Sub End Class
C#
using System; using myStringer; //The namespace created in Stringer.netmodule. class MainClientApp { // Static method Main is the entry point method. public static void Main() { Stringer myStringInstance = new Stringer(); Console.WriteLine("Client code executes"); myStringInstance.StringerMethod(); } }
Visual C++
#using "Stringer.netmodule" using namespace System; using namespace myStringer; //The namespace created in Stringer.netmodule. ref class MainClientApp { // Static method Main is the entry point method. public: static void Main() { Stringer^ myStringInstance = gcnew Stringer(); Console::WriteLine("Client code executes");
C#
Visual C++
Especifique la opcin /t:module, ya que este mdulo se va a agregar a un ensamblado en un paso posterior. Especifique la opcin /addmodule, ya que el cdigo de Client hace referencia a un espacio de nombres creado por el cdigo en Stringer.netmodule.El compilador produce un mdulo denominado Client.netmodule que contiene una referencia a otro mdulo, Stringer.netmodule.
Nota Los compiladores de C# y Visual Basic son compatibles con la creacin directa de ensamblados de mltiples archivos mediante las dos siguientes sintaxis distintas.
Visual Basic
C#
Visual C++
Visual Basic
C#
Visual C++
La herramienta Assembly Linker (Al.exe) se puede usar para crear un ensamblado a partir de una coleccin de mdulos de cdigo compilados.
Delegados
Un delegado es un tipo de objeto que encapsula un mtodo de forma segura, similar a un puntero a funcin de C y C++. A diferencia de los punteros a funcin de C, los delegados estn orientados a objetos, proporcionan seguridad de tipos y son seguros.El tipo de un delegado se define por su nombre. El ejemplo siguiente declara un delegado denominado Del que puede encapsular un mtodo que toma un valor string como argumento y devuelve un valor void: C#
Generalmente, un objeto de delegado se crea proporcionando el nombre del mtodo que el delegado contendr o con un mtodo annimo. Una vez que se crean instancias de un delegado, el delegado pasar al mtodo una llamada realizada por ste al delegado. Los parmetros que el llamador pas al delegado se pasan al mtodo y el delegado devuelve al llamador el valor devuelto del mtodo, si hay alguno. Esto se conoce como invocar al delegado. Se puede invocar un delegado con instancias como si fuera el propio mtodo contenido. Por ejemplo: C#
// Create a method for a delegate. public static void DelegateMethod(string message) { System.Console.WriteLine(message); }
C#
// Instantiate the delegate. Del handler = DelegateMethod; // Call the delegate. handler("Hello World");
Los tipos de delegados se derivan de la clase Delegate en .NET Framework. Los tipos de delegados son sealed (no se pueden derivar) y no es posible derivar clases personalizadas de Delegate. Puesto que el delegado con instancias es un objeto, puede pasarse como parmetro o asignarse a una propiedad. Esto permite que un mtodo acepte un delegado como parmetro y llame al delegado posteriormente. Esto se conoce como devolucin de llamada asincrnica y constituye un mtodo comn de notificacin de un llamador cuando ha finalizado un proceso largo. Cuando se utiliza un delegado de esta forma, no es necesario que el cdigo que utiliza el delegado conozca la implementacin del mtodo que se est utilizando.
Otro uso comn de devoluciones de llamada es definir un mtodo de comparacin personalizado y pasar ese delegado a un mtodo de ordenacin. Esto permite al cdigo del llamador ser parte del algoritmo de ordenacin. El mtodo del ejemplo siguiente utiliza el tipo Del como parmetro: C#
public void MethodWithCallback(int param1, int param2, Del callback) { callback("The number is: " + (param1 + param2).ToString()); }
MethodWithCallback(1, 2, handler);
y recibir el resultado siguiente en la consola: The number is: 3 Al utilizar el delegado como abstraccin, MethodWithCallback no es necesario llamar a la consola directamente; es decir, el delegado no se tiene que disear pensando en una consola. Lo que MethodWithCallback hace es simplemente preparar una cadena y pasarla a otro mtodo. Esto es especialmente eficaz, puesto que un mtodo delegado puede utilizar cualquier nmero de parmetros. Cuando se crea un delegado para contener un mtodo de instancia, el delegado hace referencia tanto a la instancia como al mtodo. Un delegado no conoce el tipo de instancia a parte del mtodo que ste contiene, de modo que un delegado puede hacer referencia a cualquier tipo de objeto siempre que exista un mtodo en dicho objeto que coincida con la firma del delegado. Cuando se crea un delegado para contener un mtodo esttico, ste slo hace referencia al mtodo. Considere las siguientes declaraciones: C#
public class MethodClass { public void Method1(string message) { } public void Method2(string message) { } }
Junto con el mtodo esttico DelegateMethod que se mostr previamente, ahora tenemos tres mtodos que la instancia de Del puede contener.
Un delegado puede llamar a ms de un mtodo cuando se invoca. Esto se denomina multidifusin. Para agregar un mtodo adicional a la lista de mtodos del delegado (lista de invocacin), simplemente es necesario agregar dos delegados mediante los operadores de suma o de asignacin de suma ('+' o '+='). Por ejemplo: C#
MethodClass obj = new MethodClass(); Del d1 = obj.Method1; Del d2 = obj.Method2; Del d3 = DelegateMethod; //Both types of assignment are valid. Del allMethodsDelegate = d1 + d2; allMethodsDelegate += d3;
En este momento, allMethodsDelegate contiene tres mtodos en su lista de invocacin: Method1, Method2 y DelegateMethod. Los tres delegados originales, d1, d2 y d3 no cambian. Cuando se invoca a allMethodsDelegate, se llama a los tres mtodos por orden. Si el delegado utiliza parmetros de referencia, sta a su vez se pasa secuencialmente a cada uno de los tres mtodos y todos los cambios efectuados por un mtodo son visibles para el siguiente mtodo. Cuando alguno de los mtodos produce una excepcin que no se detecta dentro del mtodo, esa excepcin se pasa al llamador del delegado y no se llama a ninguno de los mtodos siguientes de la lista de invocacin. Si el delegado tiene un valor devuelto y/o fuera de los parmetros, devuelve el valor devuelto y los parmetros del ltimo mtodo invocado. Para quitar un mtodo de la lista de invocacin, utilice el operador de resta o de asignacin de resta ('-' o '-='). Por ejemplo: C#
//remove Method1 allMethodsDelegate -= d1; // copy AllMethodsDelegate while removing d2 Del oneMethodDelegate = allMethodsDelegate - d2;
Puesto que los tipos de delegados se derivan de System.Delegate, los mtodos y las propiedades definidos por esa clase se pueden llamar en el delegado. Por ejemplo, para buscar el nmero de mtodos en la lista de invocacin de un delegado, puede escribir: C#
Los delegados con ms de un mtodo en su lista de invocacin derivan de MulticastDelegate, que es una subclase de System.Delegate. El cdigo anterior funciona en ambos casos porque las dos clases admiten GetInvocationList. Los delegados de multidifusin se utilizan ampliamente en el control de eventos. Los objetos de origen de eventos envan notificaciones de eventos a objetos de destinatario registrados para recibir ese evento. Para registrar un
evento, el destinatario crea un mtodo diseado para controlar el evento, a continuacin crea un delegado para dicho mtodo y pasa al delegado al origen de eventos. El origen llama al delegado cuando se produce el evento. Luego el delegado llama al mtodo de control de eventos del destinatario y entrega los datos del evento. El origen de eventos define el tipo de delegado para un evento dado. Para obtener ms informacin, vea Eventos (Gua de programacin de C#). La comparacin de delegados de dos tipos distintos asignados en tiempo de compilacin producir un error de compilacin. Si las instancias de delegado son estticamente del tipo System.Delegate, se permite la comparacin, pero se devolver false en tiempo de ejecucin. Por ejemplo: C#
delegate void Delegate1(); delegate void Delegate2(); static void method(Delegate1 d, Delegate2 e, System.Delegate f) { // Compile-time error. //Console.WriteLine(d == e); // OK at compile-time. False if the run-time type of f // is not the same as that of d. System.Console.WriteLine(d == f); }