Implementación de interfaces: implícitas vs explícitas – O cómo ocultar miembros de interfaces

Las interfaces en .NET y otros lenguajes son una manera de establecer un contrato entre dos clases, de manera que dejemos perfectamente definido de qué manera vana poder interactuar entre ellas. Así, si una clase implementa una determinada interfaz sabemos que dicha clase va a disponer de determinados métodos y podemos contar con ellos a la hora de trabajar con ésta. Además gracias a las interfaces podemos implementar ciertos tipos de polimorfismo o genericidad a la hora de trabajar con conjuntos de clases que implementan la misma interfaz.


En fin, nada nuevo en el párrafo anterior para un programador mínimamente experimentado de .NET o cualquier otro lenguaje orientado a objetos. En nuestro curso de preparación del examen 70-536 se trata profusamente este tema, como es lógico. Lo interesante, y objeto de este post, viene a la hora de decidir cómo implementar una determinada interfaz en una clase. Así, si tenemos definida una interfaz cualquiera, por ejemplo esta:

public interface IMiInterfaz
{
void MiMetodo();
}

Tenemos dos formas de implementarla en una clase. La primera de ellas es la manera implícita:

public class PruebaInterfazImplicita : IMiInterfaz
{
public void MiMetodo()
{
Console.WriteLine(«Hola»);
}
}

La otra manera es la explícita, en la que indicamos de manera evidente qué interfaz estamos implementando:

public class PruebaInterfazExplicita : IMiInterfaz
{
void IMiInterfaz.MiMetodo()
{
Console.WriteLine(«Hola»);
}
}

Fíjate que en este caso ponemos el nombre de la interfaz delante del método para indicar a qué interfaz pertenece éste, y además el método no es público.


Generalmente los programadores no le damos importancia a la forma en la que se implementa una interfaz y se usan indistintamente ambas formas, pero ¿realmente existe alguna diferencia?


Pues sí, hay diferencias y son importantes. A continuación resumiré los detalles relacionados con la implementación de interfaces y con qué cosas debemos tener cuidado.


1.- Implementación de varias interfaces


En .NET no existe la herencia múltiple de clases. Algunos alegarán que es una carencia, y otros dirán que es incluso una ventaja. Se ha escrito mucho sobre el tema. Lo que sí está permitido es la implementación de diversas interfaces. Así, si tenemos dos interfaces que definen métodos con el mismo nombre ¿cómo distinguimos unos de otros?. Por ejemplo, si tenemos dos interfaces I1 e I2 así:

public interface I1
{
void M();
}

public interface I2
{
void M();
}

public class PruebaDobleInterfaz : I1, I2
{
public void M()
{
Console.WriteLine(«Método M»);
}
}

public class Prueba
{
public static void Main()
{
PruebaDobleInterfaz obj = new PruebaDobleInterfaz();
obj.M();
((I1) obj).M();
((I2) obj).M();
Console.Write(«Pulsa una tecla para terminar…»);
Console.ReadKey();
}
}


¿Cual será el resultado del código anterior? Pues que funcionará perfectamente y obtendremos el mismo texto tres veces, resultado de llamar al método M. Esto está genial si realmente queremos que la implementación del método sea idéntica en ambos casos, pero al tratarse de interfaces diferentes generalmente no será así. Ahí es donde entra la implementación explícita, ya que indicaremos qué interfaz exactamente estamos implementando y no habrá confusión posible. Si ahora definimos la clase así:

public class PruebaDobleInterfaz : I1, I2
{
public void M()
{
Console.WriteLine(«Método M»);
}

void I1.M()
{
Console.WriteLine(«Método I1.M»);
}

void I2.M()
{
Console.WriteLine(«Método I2.M»);
}
}


Pues ahora el código anterior mostrará tres mensajes diferentes, dependiendo de si llamamos al método M en la clase, o en una interfaz específica.


2.- Ocultar la implementación de miembros de interfaces


Al implementar de manera explícita miembros de interfaces lo que conseguimos es ocultarlos frente a su uso directo en la clase. Por ejemplo:

public interface IMiInterfaz
{
void MiMetodo();
}

public class PruebaInterfazImplicita : IMiInterfaz
{
void IMiInterfaz.MiMetodo()
{
Console.WriteLine(«Hola»);
}
}

public class Prueba
{
public static void Main()
{
PruebaInterfazImplicita obj = new PruebaInterfazImplicita();
//obj.MiMetodo(); //Produce un error de compilación de que la clase no contiene ese método
((IMiInterfaz) obj).MiMetodo();
Console.Write(«Pulsa una tecla para terminar…»);
Console.ReadKey();
}
}


Fíjate que ahora la llamada al método implementado explícitamente falla cuando lo intentamos hace directamente desde la clase, y se requiere el «casting» explícito a la interfaz para poder llamarlo. Además el método nose mostrará a los programadores en el Intellisense de Visual Studio, por lo que n tendrán la tentación de usarlo de cualquier manera, ocultándolo efectivamente.


¿Para qué podría servir esto? Pues por ejemplo para ocultar ciertos miembros que queremos que se usen con cuidado y sabiendo lo que se hace. Por ejemplo, es muy típico hacer esto al utilizar la interfaz IDisposable, ocultando la implementación del método Dispose() que debe ser llamado por el runtime y no generalmente por el programador.


3.- Ni públicos, ni virtuales ni abstractos


Los métodos de interfaces implementados de manera explícita no pueden definirse como públicos (se declaran automáticamente como privados para ocultarlos) ni tampoco como abstractos o virtuales. Hay que tenerlo en cuenta por si lo necesitásemos. Esto tiene dos importantes implicaciones:



1.- las clases que implementan interfaces de manera explicita no pueden ser abstractas.
2.- Las clases derivadas de clases que implementan interfaces de manera explícita no pueden sobrescribir los métodos definidos explícitamente.


Detalles adicionales


Si quieres ver algunos ejemplso más de cómo implementar interfaces explícitamente puedes echarle un vistazo a este documento de MSDN (en español): Tutorial de implementación explícita de interfaces.


Si ya dominas el tema y quieres profundizar para conocer los detalles de bajo nivel de cómo se implementan por debajo ambas formas de declarar métodos de interfaces, te recomiento este excelente artículo sobre el asunto de Chris Brumme, ingeniero distinguido de Microsoft, aquí: «cbrumme’s Weblog: Interface Layout». ¡Realmente interesante!


Espero que te haya resultado interesante, aunque sea algo árido 🙂

Clases y estructuras en .NET: cuándo usar cuál y otras cuestiones habituales

Algunas preguntas que recibo con frecuencia en el curso de preparación del examen 70-536 en campusMVP están relacionadas con las estructuras y las clases en .NET. Esta misma semana he tenido un par de ellas muy interesantes, lo que me lo ha recordado y me he decidido a resumir aquí algunas de estas preguntas y sus respuestas.


¿Cuál es la principal diferencia entre una estructura y una clase?


La principal diferencia entre Estructura y Clase es que las primeras son tipos por valor y las otras tipos por referencia. Es decir, aunque los primeros pueden trabajar como clases, realmente son valores ubicados en la pila directamente, y no punteros (referencias) a la estructura en memoria. Esto significa que los primeros se pueden gestionar más eficientemente al instanciarlos (se hace más rápido), sobre todo en grandes cantidades, como una matriz. Al crear una matriz de estructuras éstas se crean consecutivamente en memoria y no es necesario instanciar una a una y guardar sus referencias en la matriz, por lo que es mucho más rápido su uso. Por el contrario si pasas a un método una estructura, al hacerlo se crea una copia de la misma en lugar de pasar una referencia y por lo tanto los cambios aplicados sobre ella se pierden. El rendimiento es menor también.


Lo mismo pasa al aplicar ciertas funciones de objetos a estructuras en las que hay que hacer Boxing y Unboxing y eso merma el rendimiento.


¿Cuándo es interesante usar una estructura en lugar de una clase?


Lo habitual es no usar estructuras casi nunca, salvo para realizar optimizaciones.


Un caso concreto de uso de una estructura sería si, por ejemplo, quieres trabajar con números complejos, que como seguramente sabrás están representados por dos cifras: una parte real y una imaginaria. Si quieres tratarlos como un número más, es decir, que sean un tipo por valor, lo lógico es que los hagas estructuras para no tener que instanciarlos y para que cuando llames a métodos pasándole números complejos éstos se pasen por valor, y no se modifiquen con lo que hagas dentro del método al que los pasas. A todos los efectos se comportarían como si fueran otro tipo por valor, como un entero o un double.


Otro ejemplo, más común, es cuando debes trabajar con una cantidad muy elevada de objetos en memoria, uno tras otro. Por ejemplo imagínate que tienes que hacer una transformación sobre puntos tridimensionales en el espacio. Te puedes crear una clase que los represente, pero si debes ir creando y procesando miles de ellos será mucho más eficiente crearlos usando estucturas porque de este modo se crean en la pila y se libera su espacio en cuanto dejas de necesitarlos (los objetos quedarían en memoria hasta la próxima vez que los necesites). 


También hay escenarios de interoperabilidad, cuando se llama a código nativo usando PInvoke, o a objetos COM usando COM/Interop, donde es necesario pasar estructuras y no clases. Pero vamos, como resumen quedate con que, salvo casos raros, todo debe ser clases.


¿Qué diferencia hay entre usar o no New al declarar una variable cuyo tipo es una estructura?


Consideremos por ejemplo esta estructura en C#:

public struct Punto
{
public int x, y;
}

O en VB:

Public Structure Punto
Public X, Y As Integer
End Structure

Puedes declarar una variable que las use de dos formas diferentes: usando New o no. Por ejemplo en VB:

Dim p As Punto
Dim p As New Punto

¿Cuál es la diferencia? A priori parece no haber ninguna. Sin embargo sí que la hay, y tiene que ver con extender las estructuras con propiedades y métodos. 


Las estructuras se pueden extender con métodos, propiedades, etc.. como si fueran clases. Por ejemplo, consideremos el siguiente código en C#:

public struct Punto
{
int x, y;

public int X
{
get { return x; }
set { x = value; }
}

public int Y
{
get { return y; }
set { y = value; }
}
}


Si escribimos el siguiente código (el más habitual):

Punto p;
Console.WriteLine (p.x);

obtendremos un error que nos dice que la variable interna ‘x’ no está inicializada. Sin embargo con este otro código:

Punto p = new Punto();
Console.WriteLine (p.x);

No se produciría error alguno.


Lo importante aquí es que, al ser declaradas por defecto (sin constructor), las estructuras no inicializan sus miembros internos, por lo tanto antes de usarlos debemos asignarles un valor. Cada propiedad tiene un campo interno que no está inicializado cuando intentamos usarlo a través de la propiedad, y obtendrías un error al hacerlo (no se sabe si tu propiedad antes de asignarlo intenta hacer algo con él y por lo tanto te obliga a tenerlo inicializado). Si usas el constructor por defecto explícitamente (con la palabra clave new) lo que éste hace es inicializar todos los miembros internos a su valor por defecto, y a partir de ese momento ya te deja utilizarlos. Si no usas new no se llama al constructor por defecto y los campos están sin inicializar.


Otros posts


Los siguientes siguientes posts de este blog están relacionados también con, que explican precisamente algunas diferencias importantes entre clases y estructuras en determinadas situaciones:



Diferencias al usar Clases y Estructuras en matrices
Algunas sutilezas sobre paso de parámetros por referencia y por valor en C#
Nada se crea ni se destruye, sólo se transforma… Excepto las cadenas en .NET


¡Espero que te resulte útil!

Libro gratuito: Guía de Arquitectura N-Capas DDD .NET 4.0

Ya está disponible en el Centro de Arquitectura MSDN el libro «Guía de Arquitectura N-Capas DDD .NET 4.0», que hemos editado para Microsoft desde Krasis Press.


Se trata de un libro de más de 400 páginas en el que se describe un marco de trabajo común que define un camino para diseñar e implementar aplicaciones empresariales de envergadura, con un volumen importante de lógica de negocio. Seguir las guías del libro ofrece importantes beneficios en cuanto a calidad, estabilidad y especialmente un incremento en la facilidad del mantenimiento futuro de las aplicaciones, debido al desacoplamiento entre sus componentes, así como por la homogeneidad y similitudes de los diferentes desarrollos.


Los autores son grandes expertos reconocidos que trabajan en Microsoft o colaboran a menudo con ellos: César de la Torre, Unai Zorrilla, Miguel Ángel Ramos o Javier Calvarro. Algunos son autores habituales de Krasis Press.


Es todavía la primera Beta del contenido (un primer borrador), que se irá actualizando en los próximos meses, cuando .NET 4.0 haya ya salido, y a partir de los comentarios recogidos por todas las empresas que lo usen. Síguenos en Twitter o en Facebook para engerarte de las nuevas versiones.


Puedes descargarlo gratuitamente en formato PDF o XPS, y también dispone de una aplicación completa de ejemplo de implementación. Si además asistes a las jornadas de arquitectura de Microsoft en Madrid esta semana, te llevarás gratis la copia impresa del libro 🙂


Si tu empresa desarrolla aplicaciones empresariales potentes y quieres conocer las mejores prácticas, debes descargarte este libro.

Nuevos libros de Visual Studio y Sharepoint

La semana pasada lanzamos dos libros nuevos en Krasis Press:










VS2010 Visual Studio 2010, .NET 4.0 y ALM. Actualízate desde la versión 2008
Bruno Capuano

Todo lo que necesitas para ponerte al día en estas tecnologías justo antes de que salgan al mercado.
Este libro proporciona un completo recorrido por los cambios más importantes de la versión 2010. El contenido abarca temas que van desde como extender el nuevo IDE utilizando MEF, hasta como generar código a partir de un diagrama UML. También hay otros ejemplos más variados, por ejemplo: cómo trabajar con IntelliTrace, repasar las novedades que se incorporan en C++, C# y Visual Basic, dar un primer acercamiento inicial a F#, dar un repaso a las nuevas herramientas de modelado (UML Designers) y a las nuevas herramientas de arquitectura, conocer las opciones que tenemos para la gestión de proyectos con Team Foundation Server 2010, y muchas más. Incluye tutoriales que permiten no solo leer sobre las nuevas herramientas, sino también poder probar las mismas en pocos minutos.
Sharepoint 2010 Programación en Sharepoint 2010
Gustavo Vélez
         Juan Carlos González


En cuestión de algunos años, SharePoint ha pasado de ser un producto desconocido a ser el servidor de más rápido crecimiento de Microsoft y uno de los productos más excitantes de la compañía. Este libro está dirigido a todas las audiencias que de una u otra forma trabajan con el sistema, ya sean administradores de sistemas, usuarios, usuarios avanzados, arquitectos de IT o desarrolladores.
Los temas tratados son los siguientes:

   • Instalación y configuración.
   • Introducción a la programación de SharePoint, incluyendo el uso
de Visual Studio 2010.
   • Arquitectura básica de SharePoint y el Modelo de Objetos en Servidor.
   • El Modelo de Objetos en Cliente y su utilización.
   • Manejadores de Eventos, Trabajos de Temporizador, Características,
Soluciones y Flujos de Trabajo.
   • SharePoint Designer 2010.


Son tan buenos que Microsoft nos ha comprado ya muchos para formar a sus partners 🙂


Encontrarás información detallada, el índice completo, fragmentos del contenido y puedes comprarlos en los enlaces anteriores.

Cómo incorporar Dynamic Data a un proyecto Web existente

El pasado lunes, en la charla on-line que impartí para el NEt User Group de la UOC sobre Dynamic Data, comenté que existía la posibilidad de sacarle partido a esta interesante tecnología sin tener que crear desde cero un proyecto especial de Dynamic Data, es decir, sin partir de este diálogo:



Tal y como prometí ese día, a continuación explico cómo añadir las capacidades de Dynamic Data a un proyecto Web pre-existente. Como veremos se trata de algo muy sencillo.


Dado que Dynamic Data se basa en el uso plantillas, tanto para las acciones como para generar campos, entidades concretas y otros controles, lo primero que debemos hacer es copiar desde un proyecto Dynamic Data pre-existente los siguientes elementos:



1.- La carpeta de nombre DynamicData
2.- La página maestra Site.master y su correspondiente archivo de código Site.master.vb (o.cs si trabajamos con C#)
3.- La hoja de estilos Site.css


Usa el propio explorador de archivos de Windows para copiarlos, y luego refresca la lista de archivos de proyecto con el botón correspondiente en el explorador de proyectos:



Con esto sólo no es suficiente, ya que también debemos declarar al menos un modelo de datos con el que trabajar.


Asumiendo que hemos definido un contexto de acceso a datos con Linq2SQL o con Entity Framework (enla figura anterior tenemos uno definido en App_Code, con el nombre «MiModelo.dbml»), lo que tenemos que hacer es declararlo en Global.asax a la hora de arrancar la aplicación. Así, debemos escribir en el evento Application_Start un código análogo al siguiente:

    Sub Application_Start(ByVal sender As Object, _
ByVal e As EventArgs)
Dim DefaultModel As MetaModel = New MetaModel()
DefaultModel.RegisterContext(GetType(MiModeloDataContext), _
New ContextConfiguration() With {.ScaffoldAllTables = True})
End Sub

Además, debemos asegurarnos de que están incluídos los siguientes espacios de nombres:

<%@ Import Namespace=»System.ComponentModel.DataAnnotations» %>
<%@ Import Namespace=»System.Web.Routing» %>
<%@ Import Namespace=»System.Web.DynamicData» %>


De esta manera, ya tenemos todo lo necesario para poder usar DynamicData junto con controles de acceso a datos en páginas propias. Más sobre esto enseguida.


Antes de continar me gustaría indicar que podemos hacer uso de las rutas de acceso dinámico a acciones con tablas simplemente declarándolas de la manera habitual, es decir, con un código similar al siguiente dentro de Application_Start en Global.asax:

    RouteTable.Routes.Add(New DynamicDataRoute( _
«{table}/{action}.aspx») _
With {.Constraints = New RouteValueDictionary( _
New With {Key .Action = «List|Details|Edit|Insert»}), _
.Model = DefaultModel})

de forma que quedaría un evento con el código de esta figura:



A partir de este momento podríamos manejar cualquier tabla de nuestro modelo de datos con tan sólo escribir una ruta del estilo de esta:



http://miapplicacion/Productos/List


para listar todos los productos de la base de datos y poder editarlos, borrarlos o añadir nuevos. O también:



http://miapplicacion/Clientes/Insert


para insertar un nuevo cliente en la tabla Clientes (si la hubiera). Como vemos muy útil…


Páginas propias con Dynamic Data


Además de lo que acabamos de ver, que genera páginas de mantenimiento con rutas pre-establecidas, podemos sacar partido a Dynamic Data en formularios propios usando controles normales de datos, como una rejilla (GrtidView) o un FormView, usando los controles especiales disponibles a tal efecto:



Por ejemplo, añade una nueva página y en ésta agrega un control DynamicDataManager (figura anterior), y desde el grupo de controles de datos un LinqDataSource o EntityDataSource (según la tecnología que hayas usado para el modelo de datos),  y una rejilla GridView.


En la vista de marcado de la página .aspx edita el control DynamicDataManager para que active esta tecnología en la rejilla, con un código como este:

        <asp:DynamicDataManager ID=»DynamicDataManager1″ runat=»server» >
<DataControls>
<asp:DataControlReference ControlID=»GridView1″ />
</DataControls>
</asp:DynamicDataManager>

Con esto lo que conseguimos es qu el control GridView1 sea capaz de generar automáticamente campos para mostrar y editar campos de la base de datos que se correspondan con el modelo de datos. Es decir, estamos habilitando Dynamic Data en ese control.


En el control LinqDataSource se configura el contexto de datos que representa a nuestro modelo para que utilice una de las tablas que nos interese (por ejemplo la de productos). Asignamos el control DataSource a la rejilla pero deshabilitamos la capacidad de ésta para generar los campos de manera automática.


Ahora sólo nos resta añadir campos dinámicos a la rejilla de forma que, en tiempo de ejecución, éstos se muestren de acuerdo con lo especificado en el modelo de datos (validación, formato, etc… gracias a las DataAnnotations) y en las plantillas para campos, tal y como se hace siempre en Dynamic Data. Para ello existe un nuevo tipo de campo llamado DynamicField que se usa precisamente para esto. Sólo tenemos que indicar el nombre del campo en el modelo que queremos enlazar y listo, ofreciéndosenos ayuda con Intellisense en Visual Studio:



Quedando campos con el siguiente aspecto:



pudiendo asignar otras características como el texto para la cabecera o el formato (si bien este último es más interesante asignarlo mediante metadatos en el modelo, ya que así nos aseguramos un uso consistente en toda la aplicación).


Si no queremos añadirlos a mano Visual Studio nos ofrece un pequeño asistente desde la lista de acciones de la rejilla:



lo que es mucho más cómodo. Podemos añadirle además un DynamicValidator a la página (ver grupo de controles de dynamic data en una figura anterior), asociándolo con el a rejilla. Con esto tenemos controlada la validación de cada uno de los campos dinámicos que editemos dentro de la rejilla.


Ahora, cuando ejecutemos esta página, dentro de la rejilla se mostrarán los campos de acuerdo con el modelo de datos, y tendremos automáticamente los controles de edición más apropiados según el tipo de datos y el modelo, validación de la información introducida, etc… con las ventajas de velocidad y robustez que ello conlleva.


Espero que esto os resulte útil (sobre todo a los que asistísteis el otro día a mi ponencia sobre Dynamic Data, jeje) 🙂

Libro de email marketing gratuito: "49 formas de dar en el blanco"


La semana pasada estuvimos en OMExpo, la feria de marketing on-line más importante de España, y a todos los que nos visitaron en el Stand les regalamos un ejemplar de nuestro libro «The emailing experience: 49 formas de dar en el blanco». Fué un tremendo éxito y nos agotaron toda la primera edición 🙂


El libro recopila 49 consejos para hacer bien marketing a través de correo electrónico: desde cuestiones básicas como qué es y para qué sirve, hasta otras avanzadas como la entregabilidad. Los autores somos María Capón, Pablo Iglesias y José Manuel Alarcón.


Hace unos días sacamos el libro también en formato electrónico para que puedas descargarlo gratuitamente si no tuviste la oportunidad de obtenerlo en papel.


Lo tienes disponible para lectura on-line directamente en Scribd, para descarga en PDF y también para descarga en los principales eBooks del mercado en los formatos .epub y .mobi.


Para descargarlo visita nuestra página de MAILCast.


¡Espero que te guste!

Próximo lunes doy una charla on-line sobre ASP.NET Dynamic Data en la UOC

El próximo lunes día 15 de marzo de 2010, a las 19:30 hora española, voy a impartir una charla técnica on-line para el DotnetClub de la UOC titulada «Interfaces de datos a la velocidad de la luz: ASP.NET Dynamic Data».


Es gratuita y on-line. Os resumo la charla a continuación:



«Uno de los trabajos más aburridos de los programadores es la creación de interfaces de administración básica de bases de datos. Se trata de los famosos «mantenimientos» que todos nos hemos visto forzados a hacer. Aunque ASP.NET Web Forms nos proporciona fantásticos controles para poder crear interfaces de manera rápida de forma declarativa, ¿no sería fantástico poder automatizar todavía más la creación de estas páginas?. Esto es precisamente lo que nos ofrece ASP.NET Dynamic Data. Con esta tecnología podremos crear interfaces a toda velocidad pero teniendo un control preciso de todo lo que ocurre y pudiendo personalizarlas al máximo.«


Si tienes interés en crear interfaces de acceso a datos para la Web a toda velocidad seguro que te interesa.


Anótate en el enlace de arriba.


Además, hoy por la tarde a las 19:30 estaré en Vigo, en la Casa del Libro, hablando de marketing, en concreto de Branding y el libro «En Clave de Marcas». Otro tema completamente diferente, pero si estás por la zona y te interesa pásate por allí.