You are currently browsing the category archive for the ‘Interfaces’ category.

To implement an interface is to set up one contract between two code blocks, where the block that implements the interface is committed to implement specifically the methods defined by the interface.

At glance this sounds somehow weird. The question that arises is: Don’t I’m complicating my life? It depends…

Let’s suppose that, in the frame of a process, we have a heterogeneous set of objects that we unknown. Some have a serialization method named Save, if the method exists, then this is the responsible of the object persistence. If doesn’t exist such Save method, the object is persisted in the database by another method.

The question is how to find out, in runtime, if an object is implementing one method with a specific name? The following attempts to answer this. To develop that example, you will need to start Visual Studio and create one project of windows Console type for Visual Basic or C#.

Now we create the interface ISerializable, that contains the Save function that returns a boolean value:

[VB]

Public Interface ISerializable

Function Save() As Boolean

 End Interface

[C#]

using System;

interface ISerializable

{

bool Save();

}

By convention the names of the interfaces are prefixed with an “I” for better identification.

Then we are going to create one class, named PettyControl, with one unique property named Data of string type:

[VB]

Public Class PettyControl

Private mData As String

Public Property Data() As String

Get

Return mData

End Get

Set(ByVal value As String)

mData = value

End Set

End Property

End Class

[C#]

using System;

public class PettyControl

{

protected string Data;

public string data

{

get

{

return Data;

}

set

{

Data = value;

}

}

}

I define now one control, named myControl, that inherits from PettyControl and implements the ISerializable interface.

[VB]

Public Class myControl

Inherits PettyControl

Implements ISerializable

Public Sub New()

Data = “These are the test data…”

End Sub

Public Function Save() As Boolean

Implements ISerializable.Save

Console.WriteLine(“Saving…{0}”, Data)

Return True

End Function

End Class

[C#]

using System;

class myControl : PettyControl, IValidate, ISerializable

{

public myControl()

{

data = “These are the test data…”;

}

public bool Save()

{

Console.WriteLine(“Saving…{0}”, data);

return true;

}

}

In this way we have implemented the Save method of ISerializable interface. You will see that when typing the code line referred to the implementation of the interface, when you click on Enter, Visual Studio writes automatically the header of the function that the interface defines.

At this point, we know how to implement an Interface.

Now the problem is to know, programmatically, if one class implements some specific interface. For the example we are seeing, in concrete terms, is to know whether the class has implemented some Save method, in other words, if the class implements some serialization method.

So,we are going to write the application that will start in console, naming it App.

[VB]

Module App

Sub Main()

Console.WriteLine(“Visual Basic Version”)

Dim myControl As New myControl

Dim ser As ISerializable = DirectCast(myControl, ISerializable)

Dim success As Boolean = ser.Save

Console.WriteLine(“‘{0}’ Validation was{1}success.”, myControl.Data, IIf(success, ” “, ” not “))

End Sub

Console.ReadLine()

End Module

[C#]

class App

{

public static void Main()

{

Console.WriteLine(“C# Version”);

myControl myControl = new myControl();

ISerializable ser = (ISerializable)myControl;

bool success = ser.Save();

Console.WriteLine(“‘{0}’ Validation was{1}success.”, myControl.data, (success ? ” “ : ” not “));

}

Console.ReadLine();

}

This seems to work, but if the interface is not implemented “DirectCast(myControl, ISerializable)” in VB, or “(ISerializable)myControl” in C#, both in this case fail.

The correct way to ask is: “TypeOf (myControl) Is ISerializable”, in VB, or “myControl Is ISerializable” in C#. Let’s see:

[VB]

Module App

Sub Main()

Console.WriteLine(“Visual Basic Version”)

Dim myControl As New myControl

If TypeOf (myControl) Is ISerializable Then

Dim ser As ISerializable = DirectCast(myControl, ISerializable)

Dim anotherSuccess As Boolean = ser.Save

Console.WriteLine(“{0}’ Have{1}been successfully saved., myControl.Data, IIf(anotherSuccess, ” “, ” not “))

End If

Console.ReadLine()

End Sub

End Module

[C#]

class App

{

public static void Main()

{

Console.WriteLine(“C# Version”);

myControl myControl = new myControl();

if (myControl is ISerializable)

{

ISerializable ser = (ISerializable)myControl;

bool anotherSuccess = ser.Save();

Console.WriteLine({0}’ Have{1}been successfully saved., myControl.data, (anotherSuccess ? ” “ : ” not “));

}

Console.ReadLine();

}

}

This works fine in both languages. But there is an optimized way, in terms of MSIL.

In VB, “TryCatch” is used, which evaluates whether the interface is implemented, if doesn’t it, doesn’t return an error but instead Nothing. In C# this is analogous to the “as” operator.

[VB]

Module App

Sub Main()

Console.WriteLine(“Visual Basic Version”)

Dim myControl As New myControl

Dim serial As ISerializable = TryCast(myControl, ISerializable)

If Not serial Is Nothing Then

Dim anotherMoreSuccess As Boolean = serial.Save

Console.WriteLine(‘{0}’ Have{1}been successfully saved, with an optimized version., myControl.Data, IIf(anotherMoreSuccess, ” “, ” not “))

End If

Console.ReadLine()

End Sub

End Module

[C#]

class App

{

public static void Main()

{

Console.WriteLine(“C# Version”);

myControl myControl = new myControl();

ISerializable serial = myControl as ISerializable;

if (null != serial)

{

bool anotherMoreSuccess = serial.Save();

Console.WriteLine(‘{0}’ Have{1}been successfully saved, with an optimized version., myControl.data, (anotherMoreSuccess ? ” “ : ” not “));

}

Console.ReadLine();

}

}

The solution, with example projects may be downloaded from Interfaces.zip.

I hope this will be useful. 🙂

Anuncios

Implementar una interface es establecer un contrato entre dos bloques de código, donde el bloque que implementa la interface se compromete a implementar concretamente los métodos que la interface implementada define. 

En principio esto a veces suena raro. La pregunta que surge es ¿no me estaré complicando la vida?… depende… 

Supongamos que en el marco de un proceso tenemos un conjunto de objetos heterogéneos que desconocemos. Algunos tienen un método de serialización de nombre Save, si el método existe, es el encargado de persistit al objeto. Si no existe el método Save, el objeto se persiste en base de datos por medio de otro método.

La pregunta es ¿cómo preguntar, en tiempo de ejecución, si un objeto implementa un método de un determinado nombre?Lo que sigue intenta responder esto. Para desarrollar este ejemplo, hay que abrir Visual Studio y crear un proyecto de Windows de Consola en Visual Basic o C#.

Ahora creamos la interface ISerializable, que contiene la función Save que devuelve un boolean: 

[VB]

Public Interface ISerializable   

    Function Save() As Boolean

End Interface 

[C#]

using System; 

interface ISerializable

    {

        bool Save();

    }

Por convención a los nombres de las interfaces se les prefija una “I” para una mejor identificación. 

Luego vamos a crear una clase, de nombre Controlcito, con una única propiedad llamada Datos de tipo string: 

[VB]

Public Class Controlcito

    Private mDatos As String

    Public Property Datos() As String

        Get

            Return mDatos

        End Get

        Set(ByVal value As String)

            mDatos = value

        End Set

    End Property

End Class 

[C#]

using System;

     public class Controlcito

    {

        protected string Data;

        public string data

        {

            get

            {

                 return this.Data;

            }

            set

            {

                this.Data = value;

            }

        }

    }

 Defino ahora un control, con nombre miControl, que herede de Controlcito e implemente la interface ISerializable 

[VB]

Public Class miControl

    Inherits Controlcito

    Implements ISerializable

     Public Sub New()

        Datos = “Estos son los datos de prueba…”

     End Sub

     Public Function Save() As Boolean

         Implements ISerializable.Save

        Console.WriteLine(“Grabando…{0}”, Datos)

        Return True

    End Function

End Class 

 

[C#]

using System;

class miControl : Controlcito, IValidate, ISerializable 

    {

        public miControl()

        {

            data = “Mis datos de prueba.”;

        }

         public bool Save()

        {

            Console.WriteLine(“Grabando…{0}”, data);

            return true;

        }

    }

De esta forma queda implementado, efectivamente, el método Save de la interface ISerializable. Verán que al tipear la linea de código referida a la implementación de la interface, cuando se hace click en Enter, Visual Studio escribe el encabezado de la función que define la interface.

Ya sabemos cómo implementar una Interface.

Ahora el problema es saber, programáticamente, si una clase implementa una Interface. Para el ejemplo que estamos viendo, en términos concretos, es saber si la clase tiene implementado un método Save, en otras palabras, si la clase implementa algún método de serialización.

Entonces vamos a escribir la aplicación que se lanzará en consola, la llamamos App 

[VB]

Module App

    Sub Main()

        Console.WriteLine(“Versión Visual Basic”)

        Dim miControl As New miControl

        Dim ser As ISerializable = DirectCast(miControl, ISerializable)

        Dim exito As Boolean = ser.Save

        Console.WriteLine(“La validación de ‘{0}’ {1} fue correcta”, miControl.Datos, IIf(exito, “”, “no”))

    End Sub

    Console.ReadLine()

End Module 

 

[C#]

class App

    {

        public static void Main()

        {

            Console.WriteLine(“Versión C#”);

            miControl miControl = new miControl();

            ISerializable ser = (ISerializable)miControl;

            bool exito = ser.Save();

            Console.WriteLine(“La validación de ‘{0}’ {1} fue correcta”, miControl.data, (true == exito ? “” : “no”));

        }

        Console.ReadLine();

    }

Esto parece funcionar, pero si la interface no está implementada DirectCast(miControl, ISerializable), en VB, o (ISerializable)miControl, en C#, ambos, en ese caso dan error.

La forma correcta de preguntar es TypeOf (miControl) Is ISerializable, en VB, o miControl Is ISerializable, en C#. Veamos:

[VB]

Module App

    Sub Main()

        Console.WriteLine(“Versión Visual Basic”)

        Dim miControl As New miControl

        If TypeOf (miControl) Is ISerializable Then

            Dim ser As ISerializable = DirectCast(miControl, ISerializable)

            Dim otroExito As Boolean = ser.Save

            Console.WriteLine(“Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente”, miControl.Datos, IIf(otroExito, “”, “no”))

        End If

        Console.ReadLine()

    End Sub

End Module 

[C#]

class App

    {

        public static void Main()

        {

            Console.WriteLine(“Versión C#”);

            miControl miControl = new miControl();

            if (miControl is ISerializable)

            {

                ISerializable ser = (ISerializable)miControl;

                bool otroExito = ser.Save();

                Console.WriteLine(“Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente”, miControl.data, (true == otroExito ? “” : “no”));

            }

            Console.ReadLine();

        }

    }

Esto funciona correctamente en ambos lenguajes. Pero existe una forma optimizada, en términos de código MSIL.

En VB se usa TryCast que evalúa si la interface está implementada, si no lo está, no devuelve error sino Nothing. En C# esto es análogo con el operador as. 

[VB]

Module App

    Sub Main()

        Console.WriteLine(“Versión Visual Basic”)

        Dim miControl As New miControl

        Dim serial As ISerializable = TryCast(miControl, ISerializable)

        If Not serial Is Nothing Then

            Dim otroExitoMas As Boolean = serial.Save

            Console.WriteLine(“Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente, con una versión optimizada”, miControl.Datos, IIf(otroExitoMas, “”, “no”))

        End If

        Console.ReadLine()

    End Sub

End Module 

 

[C#]

class App

    {

        public static void Main()

        {

            Console.WriteLine(“Versión C#”);

            miControl miControl = new miControl();

            ISerializable serial = miControl as ISerializable;

            if (null != serial)

            {

                bool otroExitoMas = serial.Save();

                Console.WriteLine(“Los Datos de ‘{0}’ {1} se han guardado satisfactoriamente, con una versión optimizada”, miControl.data, (true == otroExitoMas ? “” : “no”));

            }

            Console.ReadLine();

        }

    }

La solución, con los proyectos de ejemplo pueden descargarse de Interfaces.zip

Ojalá haya servido de algo. 🙂

Asesoramiento a Organizaciones Públicas y Privadas.

Cursos a grupos ya constituidos.

Charlas de orientación.

Metodologías Ágiles.

Startups.

Visitas

  • 136,510 hits

Mejor calificado

del.icio.us