Etiqueta: truco

  • Compilar y ejecutar versión para .NET Core (.NET 5.0)

    Nota del 26-oct-2020:
    Esta utilidad (seguramente) no tendrá más actualizaciones.
    En su lugar he publicado otra más completa en github: gsEvaluarColorearCodigoNET que incluye evaluación del código, compilar, compilar y ejecutar (por ahora para un solo fichero), colorear y colorear en HTML y tiene cosas interesantes para la creación de un editor de múltiples ficheros con algunas utilidades más.
    Cuando tenga la página publicada en el blog, te dejaré el enlace.

     

    Pues eso… siguiendo las pruebas de crear proyectos de .NET Core (con .NET 5.0) para Visual Basic, aquí traigo el de Compilar y Ejecutar que está creado con WPF / XAML y que además usa la biblioteca de clases para colorear (gsColorearCore) que también he convertido para .NET Core, en esta ocasión para la versión 3.1.

    La he convertido para usar con .NET 5.0 (.NET Core), más que nada para probar, pero visto lo visto (los problemas) prefiero quedarme con la versión de .NET Framework.

    Nota:
    Abajo tienes una actualización del 16/Sep/2020

     

    ¿Por qué es preferible usar .NET Framework para este tipo de aplicación?

    Por la sencilla razón de que salvo cosas puntuales, no tiene mucho sentido hacerla para .NET Core. Ya que este tipo de aplicaciones (las creadas para WPF o Windows Forms) solo se ejecutarán o funcionarán en equipos que utilicen Windows como sistema operativo.

    Que tú prefieres usar el .NET Core porque «DICEN» que es más rápido, ocupa menos, se puede «embeber» con la aplicación y otras monerías… pues muy bien… lo mismo yo utilizo esas cosas «puntuales» para hacer algo con .NET 5.0, o hacer mucho cuando ya sea .NET 6.0, el tiempo lo dirá… No hay que descartar nada ni decir de este agua no beberé 😉

    Cosas a tener en cuenta en la migración de .NET Framework a .NET Core

    Aparte de que hay ciertas cosas que ya no existen, al menos de la forma a la que estamos habituados en las aplicaciones para .NET Framework, el resto no cambia nada o no cambia mucho.

    Configuración (My.Settings)

    Por ejemplo, me he encontrado con problemas a la hora de usar My.Settings. Me estuvo funcionando y de buenas a primeras dejó de hacerlo, así que… corté por lo sano y me deshice de My.Settings y las configuración la uso por mi cuenta, concretamente usando la clase Config que tengo definida en la DLL de gsColorear.

    No quiero decir con esto que no se puedan usar… solo digo que a mí me estuvo funcionando bien hasta que de buenas a primeras dejó de funcionar.

    Propiedades del proyecto

    A las propiedades del proyecto ya no accede desde el nodo MyProject.
    Ahora puedes hacerlo pulsando en el nombre del proyecto con el botón secundario del ratón (normalmente el derecho) y del menú mostrado pulsar en Propiedades (ver la figura 1).

    Figura 1. Acceder a las propiedades del proyecto

    NOTA:
    Si simplemente haces clic en el nombre del proyecto (y la ventana de propiedades no estaba abierta anteriormente y ocasionalmente si también está abierta) se mostrará el fichero .vbproj con las opciones de configuración en formato XML no con tantas «cosas» como el de una aplicación para .NET Framework (ver la figura 2).
    Ahí, entre otras cosas, se indica la versión del .NET Core que estás usando (en este caso .NET 5.0 para Windows), qué tipo de aplicación es, el espacio de nombres, etc.

    Figura 2. Propiedades del proyecto en XML

    Este es el aspecto (simplificado) de la ventana de propiedades del proyecto (ver figura 3).

    Figura 3. Ventana de propiedades del proyecto

    Si pulsas en Paquete (en el panel izquierdo de la ventana de Propiedades) tendrás algo parecido a la información del ensamblado de las aplicaciones para .NET Framework.

    Referencias

    Las referencias a DLL externas (u otros proyectos), se pueden hacer desde la ventana de propiedades, pero en la ventana del explorador de soluciones ya no se muestra como el nodo Referencias. Ahora está en Dependencias.

    Si pulsas en Referencias de la ventana de propiedades, verás que está vacía, pero puedes agregar las referencias que necesites, supongo que, a diferencia de una aplicación de .NET Framework, aquí solo tienes que añadir las referencias externas, es decir, las que no se encuentren ya definidas en el propio .NET Core.

    En realidad en Dependencias añadirás las mismas cosas que antes (con .NET Framework) añadías en tu proyecto: paquetes NuGet, referencias a otros proyectos, etc.

    En el caso de las referencias a otros proyecto, están en un nodo diferenciado (Proyectos), tal como puedes comprobar en la figura 4.

    Figura 4. Nodo de proyectos usados en el proyecto actual

    Y básicamente estos es lo diferente… y eso que no me he puesto a añadir configuraciones ni recursos desde la ventana de propiedades… pero eso lo dejo estar… al menos por ahora 😉

     

    Todo esto lo estoy escribiendo el 5 de septiembre de 2020 y estoy usando Visual Studio Community 2019 Preview Versión 16.8.0 Preview 2.1 con el .NET 5.0 versión 5.0.100-preview.8.20417.9.

    Para estas pruebas he copiado el proyecto para WPF Compilar y ejecutar versión 1.0.0.21 del 31 de agosto de 2020 con la librería gsColorear2008 versión 1.0.6.3 del 8 de enero de 2019.

    Nota:
    Me apunto actualizar la página de gsColorear en mi sitio para que tenga la última versión tanto de la DLL como de la aplicación.

    En la librería de colorear el código, también tuve que quitar los ficheros de recursos (con las palabras clave de los lenguajes) y guardarlos (y abrirlos al usarlos) de forma manual en vez de como si fuese un recurso. No fue complicado, pero… es otra cosa que rompe la compatibilidad entre proyectos. Y esto es independiente de la versión de .NET Core que tenga asignada en el proyecto, ya que lo probé inicialmente con el .NET 5.0 y después con el .NET Core 3.1.
    Al final lo he dejado con el .NET Core 3.1, ya que al ser una biblioteca de clases, .NET Core 3.1 si da soporte a ese tipo de proyectos de Visual Basic.

     

    Y esto es todo por hoy… otro día más…

    Espero que te haya sido de utilidad.

     

    Actualización del 16/Sep/2020

    He actualizado el código, tanto de la utilidad de compilar y ejecutar como de la DLL de compilar, esta última ahora usa código de Visual Basic en lugar de C#, y también he actualizado la DLL de colorear el código.

    Todos esos cambios están en el repositorio de gitHub de gsCompilarEjecutarNET.

    Además, he convertido el código de la utilidad a C# y también está publicado en gitHub.

     

    Aquí te dejo el enlace original al código que puse cuando publiqué este artículo originalmente el 5 de septiembre.

    El enlace para descargar los proyectos Compilar y ejecutar y gsColorearCore para .NET Core

    ZIP: Compilar_ejecutar_NetCore_20200905_1710.zip (70.8 KB)
    MD5 checksum: ACDC9EF7E2C0F4469719F06D88F8F812

     

    Nos vemos.
    Guillermo

  • Tips para crear proyectos de .NET Core (.NET 5.0) en Visual Studio 2019 Preview

    Pues eso… leyendo el otro día el artículo Visual Basic support planned for .NET 5.0 (soporte planeado en .NET 5.0 para Visual Basic) indicaba una serie de tipos de proyectos, entre ellos de Windows Forms y WPF, pero no solo para Windows y usando el .NET Framework (que es lo que dicen por ahí que será lo que nos quede en un futuro a los que preferimos usar Visual Basic en lugar de C# (u otro lenguaje de .NET).

    Así que… abrí el Visual Studio 2019 (Community) Preview (v16.8.0 Preview 2) y me puse a mirar los tipos de proyectos que había… para C# había de esos dos tipos de aplicaciones tanto para .NET Core como para .NET Framework, pero para Visual Basic solo era para este último marco de trabajo.

    Mirando la configuración de los ficheros del proyecto de C# pude crear un proyecto de Windows Forms para Visual Basic que usa el .NET 5.0 basándome en uno de consola (de esos si que hay para el .NET Core o el .NET 5.0).

    ¡Y funciona!

    El problema, es que al agregar los controles al formulario y crear los métodos de evento (haciendo doble-pulsación en el control), los métodos de evento se creaban, pero no estaban conectados con los controles. Y eso es porque al crear los controles (añadiéndolos al formulario) no se definían con WithEvents.

    La solución es fácil, se abre el fichero Form1.Designer.vb, se modifica la declaración de los controles (que suelen estar al final de ese fichero) y asunto arreglado… bueno, si le añades el típico Handles después de la declaración del método, por ejemplo:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Label1.Text = "¡Hola Mundo!"
    End Sub
    

    Esto último es lo menos engorroso de hacer… lo complicado (o tedioso) es convertir ese proyecto de consola a uno de Windows Forms.
    ¡Y no te voy a explicar cómo hacerlo! 🙂
    No, ya que no es necesario hacer nada si sigues el consejo que te daré a continuación.

    Crear proyectos de Visual Basic para .NET Core (o .NET 5.0)

    Si no quieres complicarte mucho la vida, haz lo siguiente (tal como se muestra en la figura 1):

    Selecciona el menú de Herramientas>Opciones y se muestra la ventana de configuración, selecciona Entorno>Características en versión preliminar y ahí marca la casilla Mostrar todas las plantillas de .NET Core en el cuadro de diálogo nuevo proyecto y pulsa Aceptar. Tendrás que cerrar y abrir nuevamente el Visual Studio y ya tendrás todas las plantillas que hay actualmente disponibles.

     

    Usar los nuevos tipos de proyectos

    Si ahora creas un nuevo proyecto (o agregas uno a una solución existente) verás que ya están los proyectos de Visual Basic para todas las plataformas (usando Windows Forms y WPF entre otros).

    Una vez que seleccionas uno de los proyectos para «todas las plataformas» te dará la opción de elegir la plataforma de destino (el «framework» que usarás). (ver la figura 3)

    Si eliges una aplicación de WPF te mostrará las 3 opciones de la figura anterior, si eliges una aplicación de Windows Forms, solo mostrará .NET Core 3.1 y .NET 5.0.

     

    NOTA:
    Como sabrás .NET 5.0 es una especie de remix entre el .NET Framework y el .NET Core o lo que es lo mismo, es la continuidad de .NET Core, pero unificado con el .NET Framework.
    Y la primera versión definitiva está planeada para noviembre de este año de 2020.

     

    ¿Se soluciona algo al crear así las aplicaciones de Windows Forms?

    Pues no… o casi… Me refiero a que al añadir un control al formulario y hacer doble-clic en él se genere correctamente el método de evento.

    Ni usando el .NET Core 3.1 ni usando el .NET 5.0 (al menos en Visual Basic) se generan correctamente esos métodos de evento.

    Si usas .NET Core 3.1 como plataforma de destino, al menos se definirán los controles con WithEvents, pero tendrás que añadirle el Handles o enlazar el evento y el método con AddHandler.

    Si usas como plataforma de destino el .NET 5.0, no se definen los controles con WithEvents y, por tanto, tampoco se crean los métodos con Handles ya que es un requisito el que las variables (controles en este caso) estén definidos con WithEvents para permitir definir los eventos con Handles.

     

    A esperar toca…

    Esperemos que en futuras revisiones del .NET 5.0 o de Visual Studio esté solucionado, si no… lo tenemos complicado.
    No sé quién será el encargado de arreglar esto, supongo que los de VS, y esperemos que sea así, ya que el .NET 5.0 ha entrado en lo que llaman la fase “feature complete” (función completa) en la Preview 8 de hace una semana y ya solo nos quedan las release candidate en las que solo arreglan bugs, no añaden nuevas características.

    Habrá que reportarlo como BUG para ver si hacen algo y lo solucionan… porque si no lo solucionan, es que realmente no quieren que los desarrolladores de Visual Basic sigamos usándolo… y… optemos por cambiar a C#… en fin…

     

    Nota:
    Aunque al crear los proyectos de Windows Forms y WPF aparentemente sean para todas las plataformas, en realidad solo están soportadas en Windows.
    O al menos eso quiere decir (o es lo que yo entiendo que significa) esto en la configuración de la aplicación:

    <TargetFramework>net5.0-windows</TargetFramework>
    

     

    Espero que te haya servido para algo todo lo aquí comentado… ya sabes que esa es la idea 😉

    Nos vemos.
    Guillermo

  • 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