el Guille, la Web del Visual Basic, C#, .NET y más...

Métodos de extensión (ejemplos para Visual Basic y C#)

 
Publicado el 24/Ago/2020
Actualizado el 24/Ago/2020
Autor: Guillermo 'guille' Som

Esto de los métodos de extensión (Extension Methods en inglés) sirve para ampliar la funcionalidad de clases existentes, ya sean definidas en el propio .NET (String, Integer, TextBox, etc.) como en otras librerías (bibliotecas) que tengamos referenciadas en nuestro proyecto. (publicado en mi blog)




 

Este contenido está obtenido de mi blog, la URL original es:
Métodos de extensión (ejemplos para Visual Basic y C#)

Pues eso… y por si no lo sabes, esto de los métodos de extensión (Extension Methods en inglés) sirve para ampliar la funcionalidad de clases existentes, ya sean definidas en el propio .NET (String, Integer, TextBox, etc.) como en otras librerías (bibliotecas) que tengamos referenciadas en nuestro proyecto.

NOTA:
Aquí no te voy a explicar en detalle de qué va esto de los métodos de extensión, solo decirte cómo crear los tuyos propios, con código de Visual Basic y de C#, para ello te pondré unos ejemplos.

NOTA2:
¡Vaya despiste!
Pues eso… que se ve que en septiembre del año pasado (5-sep-2019) ya publiqué algo sobre los métodos de extensión… y es que lo tenía apuntado (en mi cabeza) y se ve que después de publicarlo no lo borré… jajaja… en fin… Más vale 2 que nada… 😉

En este artículo voy a ponerte un par de ejemplos para añadir una nueva función a la clase String y algunos métodos de conversión a la clase TextBox, de forma que puedas usarlos para convertir el contenido de la propiedad Text en un valor entero, un valor decimal, etc.

Crear métodos de extensión en Visual Basic

En Visual Basic necesitamos una importación a System.Runtime.CompilerServices y crear los métodos en un módulo (no se pueden crear en clases).
La definición del método empezará con el atributo <Extension> y después seguirá la definición de la función ( o método), pero en el primer parámetro indicaremos la clase que queremos ampliar (o extender) y después, opcionalmente, podemos usar más parámetros.

Crear método de extensión en C#

Para crear métodos de extensión en C# necesitamos una clase definida como static y definir los métodos de extensión también como compartidos (static), pero no es necesario usar la importación de CompilerServices ni añadir el atributo Extension, ya que el compilador sabe que es un método de extensión si el primer argumento de la función (o método) empieza con this y el tipo que queremos extender.

Un par de ejemplos de métodos de extensión

En el siguiente código tenemos un par de ejemplos de métodos de extensión de la clase String, el primero como función y el segundo como un método que no devuelve nada.
Primero el código de Visual Basic y después el de C#.

Imports System.Runtime.CompilerServices

Module Extensiones
    <Extension>
    Public Function Prueba(str As String) As String
        Return "PRUEBA " & str
    End Function

    <Extension>
    Public Sub Imprimir(str As String)
        Console.WriteLine(str)
    End Sub
End Module
static class Extensiones
{
    //[Extension]
    public static string Prueba(this string str)
    {
        return "PRUEBA " + str;
    }

    public static void Imprimir(this string str)
    {
        Console.WriteLine(str);
    }

Algunos métodos prácticos para extender String y TextBox

Aquí te dejo el código para extender la clase String con un método que quita las tildes (acentos) a las vocales, con idea de que podamos hacer comparaciones sin que se tenga en cuenta si la vocal está o no acentuada (con la tilde).

En el caso del control TextBox te dejo los métodos de extensión para convertir el contenido en un valor de tipo Integer, Double, Decimal, Date y TimeSpan.
Esto lo empecé a usar en el último programa que he hecho, hasta ahora, cuando quería convertir el contenido de una cadena en un valor numérico, etc., lo que hacía era usar funciones para esas conversiones.
Esas conversiones podría haberlas puesto en la clase String, pero al hacerla en el TextBox me ahorraba tener que indicar la propiedad Text cada vez que quería hacer la conversión 😉
En el código de ejemplo te pongo también la función que convierte en número entero para la clase String, así lo tendrás fácil si quieres extender dicha clase en lugar del TextBox.

El código para Visual Basic

Primero los métodos de extensión y después cómo usarlos.

Imports System

Imports System.Runtime.CompilerServices
Imports System.Windows.Forms

Module Extensiones

    ''' <summary>
    ''' Devuelve un valor Integer de la propiedad Text del TextBox indicado.
    ''' </summary>
    ''' <param name="txt">El TextBox a extender</param>
    <Extension>
    Public Function AsInteger(txt As TextBox) As Integer
        Dim i As Integer = 0

        Integer.TryParse(txt.Text, i)

        Return i
    End Function

    ''' <summary>
    ''' Devuelve un valor Double de la propiedad Text del TextBox indicado.
    ''' </summary>
    <Extension>
    Public Function AsDouble(txt As TextBox) As Double
        Dim d As Double = 0

        Double.TryParse(txt.Text, d)

        Return d
    End Function

    ''' <summary>
    ''' Devuelve un valor Decimal de la propiedad Text del TextBox indicado.
    ''' </summary>
    <Extension>
    Public Function AsDecimal(txt As TextBox) As Decimal
        Dim d As Decimal = 0

        Decimal.TryParse(txt.Text, d)

        Return d
    End Function

    ''' <summary>
    ''' Devuelve un valor TimeSpan de la propiedad Text del TextBox indicado.
    ''' </summary>
    <Extension>
    Public Function AsTimeSpan(txt As TextBox) As TimeSpan
        Dim c As New TimeSpan(0, 0, 0)

        TimeSpan.TryParse(txt.Text, c)

        Return c
    End Function

    ''' <summary>
    ''' Devuelve un valor Date de la propiedad Text del TextBox indicado.
    ''' Si es un valor nulo o vacío, devuelve el 1 de enero de 1900.
    ''' </summary>
    <Extension>
    Public Function AsDate(txt As TextBox) As Date
        Dim d As DateTime = New DateTime(1900, 1, 1)

        If Not (String.IsNullOrWhiteSpace(txt.Text) OrElse txt.Text.Equals(DBNull.Value)) Then
            DateTime.TryParse(txt.Text, d)
            If d.Year < 1900 Then
                d = New DateTime(1900, 1, 1, 0, 0, 0)
            End If
        Else
            ' asignar el 01/01/1900 si es un valor en blanco
            d = New DateTime(1900, 1, 1, 0, 0, 0)
        End If

        Return d.Date
    End Function


    ''' <summary>
    ''' Quitar las tildes de una cadena.
    ''' </summary>
    ''' <param name="str">La cadena a extender</param>
    <Extension>
    Public Function QuitarTildes(ByVal str As String) As String
        Dim tildes1 = "ÁÉÍÓÚáéíóú"
        Dim tildes0 = "AEIOUaeiou"
        Dim res As New System.Text.StringBuilder

        For i = 0 To str.Length - 1
            Dim j = tildes1.IndexOf(str(i))
            If j > -1 Then
                res.Append(tildes0.Substring(j, 1))
            Else
                res.Append(str(i))
            End If
        Next
        Return res.ToString
    End Function

    ''' <summary>
    ''' Devuelve un valor Integer de la cadena a la que se aplica este método.
    ''' </summary>
    <Extension>
    Public Function AsInteger(str As String) As Integer
        Dim i As Integer = 0

        Integer.TryParse(str, i)

        Return i
    End Function



    <Extension>
    Public Function Prueba(str As String) As String
        Return "PRUEBA " & str
    End Function

    <Extension>
    Public Sub Imprimir(str As String)
        Console.WriteLine(str)
    End Sub
End Module
Imports System

Imports System.Windows.Forms

Module Module1

    Sub Main()
        Dim s = "Hola"
        Console.WriteLine(s.Prueba)

        s.Imprimir()

        s = "Código de ejemplos prácticos"
        Console.WriteLine(s.QuitarTildes())

        Dim txt As New TextBox

        txt.Text = "125"
        Console.WriteLine("txt.Text : {0}", txt.Text)
        Console.WriteLine("txt.Text.AsInteger+10 : {0}", txt.Text.AsInteger + 10)
        Console.WriteLine("txt.AsInteger+10 : {0}", txt.AsInteger + 10)

        txt.Text = "125,38"
        Console.WriteLine("txt.Text : {0}", txt.Text)
        Console.WriteLine("txt.AsDecimal*2 : {0}", txt.AsDecimal * 2)
        Console.WriteLine("txt.AsDouble*2 : {0}", txt.AsDouble * 2)

        txt.Text = "10:30"
        Console.WriteLine("txt.Text : {0}", txt.Text)
        Console.WriteLine("txt.AsTimeSpan : {0}", txt.AsTimeSpan)

        txt.Text = "24/08/2020"
        Console.WriteLine("txt.Text : {0}", txt.Text)
        Console.WriteLine("txt.AsDate : {0}", txt.AsDate)
        Console.WriteLine("txt.AsDate.AddDays(2) : {0}", txt.AsDate.AddDays(2))


        Console.ReadKey()
    End Sub

End Module

El código para C#

Primero los métodos de extensión y después cómo usarlos.

using System;
using System.Windows.Forms;

static class Extensiones
{
    //[Extension]
    public static string Prueba(this string str)
    {
        return "PRUEBA " + str;
    }

    public static void Imprimir(this string str)
    {
        Console.WriteLine(str);
    }

    /// <summary>
    /// Devuelve un valor Integer de la propiedad Text del TextBox indicado.
    /// </summary>
    /// <param name="txt">El TextBox a extender</param>
    public static int AsInteger(this TextBox txt)
    {
        int i = 0;

        int.TryParse(txt.Text, out i);

        return i;
    }

    /// <summary>
    /// Devuelve un valor Double de la propiedad Text del TextBox indicado.
    /// </summary>
    public static double AsDouble(this TextBox txt)
    {
        double d = 0;

        double.TryParse(txt.Text, out d);

        return d;
    }

    /// <summary>
    /// Devuelve un valor Decimal de la propiedad Text del TextBox indicado.
    /// </summary>
    public static decimal AsDecimal(this TextBox txt)
    {
        decimal d = 0;

        decimal.TryParse(txt.Text, out d);

        return d;
    }

    /// <summary>
    /// Devuelve un valor TimeSpan de la propiedad Text del TextBox indicado.
    /// </summary>
    public static TimeSpan AsTimeSpan(this TextBox txt)
    {
        TimeSpan c = new TimeSpan(0, 0, 0);

        TimeSpan.TryParse(txt.Text, out c);

        return c;
    }

    /// <summary>
    /// Devuelve un valor Date de la propiedad Text del TextBox indicado.
    /// Si es un valor nulo o vacío, devuelve el 1 de enero de 1900.
    /// </summary>
    public static DateTime AsDate(this TextBox txt)
    {
        DateTime d = new DateTime(1900, 1, 1);

        if (!(string.IsNullOrWhiteSpace(txt.Text) || txt.Text.Equals(DBNull.Value)))
        {
            DateTime.TryParse(txt.Text, out d);
            if (d.Year < 1900)
                d = new DateTime(1900, 1, 1, 0, 0, 0);
        }
        else
            // asignar el 01/01/1900 si es un valor en blanco
            d = new DateTime(1900, 1, 1, 0, 0, 0);

        return d.Date;
    }


    /// <summary>
    /// Quitar las tildes de una cadena.
    /// </summary>
    /// <param name="str">La cadena a extender</param>
    public static string QuitarTildes(this string str)
    {
        var tildes1 = "ÁÉÍÓÚáéíóú";
        var tildes0 = "AEIOUaeiou";
        System.Text.StringBuilder res = new System.Text.StringBuilder();

        for (var i = 0; i <= str.Length - 1; i++)
        {
            var j = tildes1.IndexOf(str[i]);
            if (j > -1)
                res.Append(tildes0.Substring(j, 1));
            else
                res.Append(str[i]);
        }
        return res.ToString();
    }

    /// <summary>
    /// Devuelve un valor Integer de la cadena a la que se aplica este método.
    /// </summary>
    public static int AsInteger(this string str)
    {
        int i = 0;

        int.TryParse(str, out i);

        return i;
    }
}
using System;

using System.Windows.Forms;

class Program
{
    static void Main(string[] args)
    {
        var s = "Hola";
        Console.WriteLine(s.Prueba());
        //Console.WriteLine(s.Prueba2());

        s.Imprimir();

        s = "Código de ejemplos prácticos";
        Console.WriteLine(s.QuitarTildes());


        TextBox txt = new TextBox();

        txt.Text = "125";
        Console.WriteLine("txt.Text : {0}", txt.Text);
        Console.WriteLine("txt.Text.AsInteger+10 : {0}", txt.Text.AsInteger() + 10);
        Console.WriteLine("txt.AsInteger+10 : {0}", txt.AsInteger() + 10);

        txt.Text = "125,38";
        Console.WriteLine("txt.Text : {0}", txt.Text);
        Console.WriteLine("txt.AsDecimal*2 : {0}", txt.AsDecimal() * 2);
        Console.WriteLine("txt.AsDouble*2 : {0}", txt.AsDouble() * 2);

        txt.Text = "10:30";
        Console.WriteLine("txt.Text : {0}", txt.Text);
        Console.WriteLine("txt.AsTimeSpan : {0}", txt.AsTimeSpan());

        txt.Text = "24/08/2020";
        Console.WriteLine("txt.Text : {0}", txt.Text);
        Console.WriteLine("txt.AsDate : {0}", txt.AsDate());
        Console.WriteLine("txt.AsDate.AddDays(2) : {0}", txt.AsDate().AddDays(2));


        Console.ReadKey();
    }

    //Error CS1106: Un método de extensión debe definirse en una clase estática no genérica

    //public static string Prueba2(this string str)
    //{
    //    return "PRUEBA2 " + str;
    //}

}

Y esto es todo… espero que te haya sido de utilidad… ya sabes que esa es la idea 😉

Nos vemos.
Guillermo



 


Haz tu donativo a este sitio con PayPal
 

Busca en este sitio con Google
 
Google

La fecha/hora en el servidor es: 29/03/2024 2:25:26

La fecha actual GMT (UTC) es: 

©Guillermo 'guille' Som, 1996-2024