Etiqueta: Visual Studio

Posts relacionados con el entorno de desarrollo (IDE) de Visual Studio

  • Métodos de Extensión (Extesion Methods) en VB y C#

    Pues eso… te voy a mostrar algunos ejemplos de los métodos de extensión (Extension Methods) que no es ni más ni menos que una forma de extender el funcionamiento de tipos ya existentes. Como de costumbre, el código de ejemplo estará tanto para Visual Basic .NET como para C#.

    Por ejemplo, que es lo que mostraré en este «post», tenemos las cajas de texto (TextBox) a los que le daremos propiedades para convertir el contenido de la propiedad Text en valores de tipo fecha (Date), hora (TimeSpan), enteros (Integer), decimales (Decimal) o Boolean.

    Para hacer esto solo tenemos que tener una importación al espacio de nombres System.Runtime.CompilerServices y aplicar al método de extensión el atributo Extension y definir el método con lo que queramos que amplíe al tipo en cuestión. Y lo importante de ese método es que: el tipo a ampliar será el primer argumento del método.

    Definir los métodos de extensión

    Lo primero que hay que hacer es definir los métodos de extensión.

    Esa definición la haremos en clases estáticas que en el caso de Visual Basic nos servirán los módulos (Module) mientras que en C# tendrán que ser métodos compartidos (static) definidos en una clase también compartida o estática (static).

    Veamos el código de una clase simple que añadirá el método AsDate y AsInteger a un TextBox. De forma que si quieres convertir el contenido de la propiedad Text de la caja de texto TextBox1 en una fecha solo tengas que hacer algo como esto: fecha = TextBox1.AsDate.

    Ejemplo de métodos de extensión para Visual Basic .NET

    Imports System.Windows.Forms
    Imports System.Runtime.CompilerServices
    
    Module ExtensionTextBox
    
        ''' <summary>
        ''' Devuelve un valor Date de la propiedad Text del TextBox indicado.
        ''' Si la fecha no es válida devuelve el 1 de enero de 1900.
        ''' </summary>
        ''' <param name="txt">El TextBox a extender</param>
        <Extension>
        Public Function AsDate(txt As TextBox) As Date
            Dim f = New Date(1900, 1, 1)
    
            Date.TryParse(txt.Text, f)
    
            Return f
        End Function
    
        ''' <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
    
    End Module
    

    Ejemplo de métodos de extensión para C#

    using System.Runtime.CompilerServices;
    using System.Windows.Forms;
    
    public static class ExtensionTextBox
    {
        /// <summary>
        /// Devuelve un valor Date de la propiedad Text del TextBox indicado.
        /// Si la fecha no es válida devuelve el 1 de enero de 1900.
        /// </summary>
        /// <param name="txt">El TextBox a extender</param>
        public static DateTime AsDate(this TextBox txt)
        {
            var f = new DateTime(1900, 1, 1);
    
            DateTime.TryParse(txt.Text, out f);
    
            return f;
        }
    
        /// <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;
        }
    }
    

    Ejemplo de uso de los métodos de extensión

    En este ejemplo tendremos un formulario con un par de cajas de texto y unas etiquetas, además de un botón que hará ciertos cálculos con los datos de las cajas de textos y mostrará el resultado en las etiquetas.

    En la siguiente captura tienes el aspecto del formulario de ejemplo y a continuación verás el código para usar esos métodos de extensión.

    Figura 1. El formulario en modo diseño
    Figura 1. El formulario en modo diseño

    El código del botón «Convertir» en Visual Basic y C#

    Private Sub btnConvertir_Click(sender As Object,
                                   e As EventArgs) Handles btnConvertir.Click
        Dim fecha = txtFecha.AsDate
        LabelFecha.Text = "La fecha + 1 día = " & fecha.AddDays(1).ToString("dddd, dd.MMM.yyyy")
    
        Dim entero = txtEntero.AsInteger
        LabelEntero.Text = $"{entero} * 2 = " & (entero * 2).ToString
    End Sub
    \f0
    
    
    private void btnConvertir_Click(object sender, EventArgs e)
    {
        var fecha = txtFecha.AsDate();
        LabelFecha.Text = "La fecha + 1 día = " + fecha.AddDays(1).ToString("dddd, dd.MMM.yyyy");
        var entero = txtEntero.AsInteger();
        LabelEntero.Text = $"{entero} * 2 = " + (entero * 2).ToString();
    }
    

    Solo comentar que si los métodos de extensión están en otro espacio de nombres distinto al de la aplicación donde se usan, habrá que hacer una importación de ese espacio de nombres para que esos métodos estén accesibles.
    Pero esto es algo «sabido», ya que aquí es como si usáramos el código de cualquier otra clase «estática/compartida»: si queremos acceder a los miembros que define debemos tener acceso a esa clase.

    Y esto es todo… espero que te sea de utilidad.

    NOTA:
    Los despistes del Guille… resulta que después de publicar este artículo sobre los métodos de extensión, me olvidé… y hace poco (el 24-ago-2020, estoy escribiendo esto el 29 de agosto de 2020) escribí otro artículo sobre el mismo tema… pero con más ejemplos… Te dejo aquí el enlace por si te sirve para aclarar más aún este tema… en fin… ¡la cabeza del Guille! 😉

    Nos vemos.
    Guillermo

  • Cuidadín con los For Each si se modifica el objeto del bucle

    Pues eso… aunque esto ya es algo viejo, y se supone que sabido, el otro día no lo recordé y revisando el código de un procedimiento que, a pesar de tratar con muchos registros de una base de datos de SQL Server, veía que tardaba demasiado… y mientras estaba trabajando el método me entretuve en ver la ventana esa de diagnóstico en la que te muestra todo lo que iba haciendo el código (ver la figura 1), y me percaté que repetía fechas…

    Ventana de las herramientas de diagnóstico de Visual Studio
    Figura 1. La ventana de las Herramientas de diagnósticos de Visual Studio.

    Al principio no caí en porqué lo hacía, así que… me puse a revisar el código con las llamadas a las actualizaciones a la base de datos… y al cabo de un rato caí en que estaba usando un bucle For Each y que la variable de ese bucle era un objeto de la clase que se encarga de actualizar los datos (e incluso de crearlos si no existen en la base de datos) y… ¡se me encendió la bombillita esa Light bulb de… idea!

    Fue cambiarlo a un bucle normal y tardar muchísimo menos Eye rolling smile, creo que una de las veces me llegó a tardar más de media hora y al hacer el cambio se quedó en 4 minutos o menos.
    Y el cambio que hice fue, por ejemplo (en VB), de este:

    For Each p In Productos

    a este otro:

    For i = 0 To Productos.Count - 1
    Dim p = Productos(i)

    Nota:
    El problema de los bucles for each no es solo de Visual Basic, también lo es de C# aunque se escriba de otra forma.

    Y lo cuento aquí para que cuando busque «problemas» me de la solución.

    Es que, por si no lo sabes, cuando no recuerdo cómo hacer algo en VB o C#, busco en Google, pero le añado al final elguille para que salgan los resultados que tengo publicados y, salvo excepciones, encuentro siempre lo que busco Flirt male, así que… ya sabes… Winking smile

    Nos vemos.
    Guillermo

  • Problemas con IntelliSense en VS2019 con el editor de VB

    Pues eso… que te quería seguir contando las cosas buenas de Visual Studio 2019, pero… hay que decirlo todo, y lo malo es que en la fecha en que te cuento esto, no creo que lo vayan a solucionar en la versión final que estará el próximo martes día 2 de abril. Sad smile

    Te cuento lo que me pasa y voy a usar el texto con el bug que he publicado hoy en la comunidad de desarrolladores de Visual Studio (Developer Community). Te dejo el enlace por si te parece la votes a ver si así le hacen más caso (siempre hacen caso a las cosas que cuento por ahí, pero… algunas no las solucionan rápidamente… será porque es Visual Basic… y ya sabes que algunos nos consideran desarrolladores de clase B… Angry smile

    Nota del 05/Abr/19

    Pues resulta que esto mismo ocurre en C# pero en casos concretos (Completion gets in the way attempting to line up arguments) y por tanto han cerrado la incidencia por estar duplicada, y según cuentan ya está solucionado en VS 16.1 Preview 2.

    Aquí va el texto y las capturas (más abajo está la traducción al inglés):

     

    Problemas con IntelliSense en VS2019 y VB

    Con Visual Studio 2019 (RC.4) da muchísimos problemas con IntelliSense y Visual Basic (con C# no ocurre lo mismo).

    Comento dos de los que me suelen ocurrir habitualmente (tanto que estoy pensando dejar de usar el VS2019 al menos para los proyectos de VB) es un verdadero «desastre» hacer ciertas cosas… más o menos habituales.

    Por ejemplo:
    En las declaraciones de los métodos de evento me gusta poner los parámetros del método en líneas separadas (para que se vean mejor los controles que utilizan ese método) y lo que suelo hacer es poner el cursor antes del segundo parámetro (después de la coma) para pulsar la tecla ENTER, cuando lo hago y se cambia de línea se muestra la ventana de IntelliSense (ver la captura de figura 1), si a continuación pulso la tecla TAB para agrandar la indentación, el editor añade la definición de la ventana de IntelliSense (ver la captura de la figura 2) en la que se ve que añade ByRef.

    Figura 1.
    Figura 2.

    Lo mismo ocurre cuando me pongo al principio de una línea con código y pulso ENTER para escribir en la línea anterior, IntelliSense muestra en el principio de la línea el método que estoy usando en ese control (ver la captura de la figura 3), nuevamente si pulso TAB (que en este caso no es la acción que yo querría hacer, pero para demostrar el mismo fallo) se añade erróneamente lo que haya seleccionado en la ventana emergente de IntelliSense (ver captura de la figura 4) y si no pulso la tecla TAB y quiero mover el cursor a la línea anterior (la que se ha creado al pulsar ENTER) tengo que pulsar la tecla ESC para que quite la ventana de IntelliSense.

    Figura 3.
    Figura 4.

    Y como comento al principio esta es una acción muy, muy habitual… y es «frustrante» escribir código de esta manera…

    Ese último error (pulsar INTRO al principio de una línea con código) también ocurre con los comentarios, y en el ejemplo que he hecho (un comentario encima de una asignación a la propiedad TEXT de un Label), al pulsar la tecla ENTER la ventana de IntelliSense muestra la misma propiedad que la indicada en la figura 4 tal como se puede ver en la captura de la figura 5.

    Figura 5.

     

    Esto con Visual Studio 2017 no ocurre.

    En C# he probado los dos ejemplos que acabo de comentar y no ocurre así.

    Realmente es algo que deberían solucionar, ya que si el producto final que saldrá al mercado el próximo 2 de abril tiene este tipo de BUG,, sería lamentable.

    Gracias.
    Guillermo

     

    A ver si lo solucionan rápido… que es un rollo que ocurra eso…

     

    Nos vemos.

    Guillermo

     

    Y como también se lo traducido al inglés (eso lo suelen hacer ellos, pero… para adelantar tiempo. Winking smile

     

    Problems with IntelliSense in VS2019 and VB

    With Visual Studio 2019 (RC.4) it gives many problems with IntelliSense and Visual Basic (with C# the same thing does not happen).

    I mention two of those that usually happen to me habitually (so much so that I’m thinking about stopping using VS2019 at least for VB projects) it’s a real «disaster» to do certain things … more or less usual.

    For example:
    In the declarations of the methods of event I like to put the parameters of the method in separate lines (so that the controls that use that method are seen better) and what I usually do is put the cursor before of the second parameter (after the comma) to press the ENTER key, when I do it and the line is changed the IntelliSense window is displayed (see the capture in Figura 1), if I then press the TAB key to enlarge the indentation, the editor adds the definition of the IntelliSense window (see the capture in Figura 2) in which it is seen that it adds ByRef.

    The same thing happens when I put myself at the beginning of a line with code and pulse ENTER to write on the previous line, IntelliSense shows at the beginning of the line the method I am using in that control (see the capture in Figura 3), again if I press TAB (which in this case is not the action that I would like to do, but to show the same fault) it is wrongly added what you have selected in the IntelliSense pop-up window (see the capture in Figura 4) and if not I press the TAB key and I want to move the cursor to the previous line (the one that was created when pressing ENTER) I have to press the ESC key to remove the IntelliSense window.

    And as I said at the beginning this is a very, very usual action … and it is «frustrating» to write code in this way …

    That last error (press ENTER at the beginning of a line with code) also occurs with the comments, and in the example that I have made (a comment above an assignment to the TEXT property of a Label), by pressing the ENTER key the window of IntelliSense shows the same property as that indicated in the capture: Figure 4 as it can be seen in the capture of Figura 5.

     

    This with Visual Studio 2017 does not happen.

    In C # I have tried the two examples that I just commented and it does not happen that way.

    It really is something that should be solved, because if the final product that will be released on April 2 has this type of BUG, it would be unfortunate.

    Thank you.
    Guillermo