sábado, 25 de junio de 2022

Curso avanzado de C#. Formateo de cadenas

 Formatear valores

Dar formato a un valor para su visualización es una conversión de tipo particularmente importante. Hasta que no se convierta una variable Datetime, decimal o double en algún tipo de cadena, no podremos mostrarla al usuario. Dos de los métodos más útiles para formatear valores como cadenas son ToString y String. Métodos que se describen a continuación.  

ToString 

El objeto de la clase proporciona un método ToString que heredan todas las demás clases. De forma predeterminada, este método devuelve el nombre del tipo de un objeto como una cadena, pero la mayoría de las clases para las que tiene sentido anulan este método para devolver el valor del objeto como una cadena. 

Por ejemplo, si una variable float tiene el valor 1,23, el método ToString devuelve el valor "1,23" como cadena. Por el contrario, si definimos una clase empleado, de forma predeterminada el método ToString devuelve el nombre de la clase, que es similar a WindowsFormsApplication1.Employee. Si utilizamos el método ToString de una variable sin parámetros, obtenemos una representación predeterminada de su valor. El método ToString también podemos tomar como parámetros un proveedor de formato, una cadena de formato o ambos. Al utilizar la cadena de formato, podemos personalizar el texto resultante. Por ejemplo, si la variable costo es un valor flotante (float), la declaración cost.ToString ("0.00") produce una cadena que contiene el valor del costo que se muestra con 2 posiciones decimales. 

Curso avanzado de C#. Formateo de cadenas


String.Format

El método ToString nos permite convertir el valor de una sola variable en una cadena. El método de formato estático de la clase String nos permite crear una cadena que puede contener los valores de muchas variables formateadas de diferentes maneras. El método String.Format tiene algunas versiones sobrecargadas, pero la más común toma como parámetros una cadena de formato y uno o más argumentos que se utilizan para completar elementos dentro de la cadena de formato. Cada elemento en la cadena de formato tiene la siguiente sintaxis de formato compuesto: 

{index [,length] [:formatString]} 

Aquí, índex es el índice de base cero de un parámetro que sigue a la cadena de formato que debe usarse para este elemento; length es la longitud mínima del resultado del elemento; y formatString es una cadena de formato estándar o personalizada para el elemento. Si la longitud es negativa, el valor se alinea a la izquierda dentro de su longitud.

Esto formalmente lo hace parecer confuso, pero en realidad no es tan mala. El siguiente código muestra un ejemplo sencillo. 

int i = 163; 

Console.WriteLine(string.Format("{0} = {1,4} or 0x{2:X}", (char)i, i, i)); 

Utilizamos string.Format para formatear una línea que escribe en la ventana de Salida.

La cadena de formato es {0} = {1,4} or 0x{2:X}. Esta cadena tiene tres elementos de formato que significan: 

{0} muestra el argumento 0 como formato predeterminado 

{1,4} muestra el argumento 1 en un campo de al menos cuatro caracteres de ancho 

{2: X} muestra el argumento 2 con formato cadena X (que muestra un número entero en hexadecimal)

Los otros caracteres dentro de la cadena de formato (=, y or x) se incluyen en la salida tal como aparecen en la cadena de formato. 

Los parámetros que vienen después de la cadena de formato son los argumentos que deben usarse con la cadena de formato. El primer argumento convierte el entero i en un carácter. El segundo y tercer argumento son simplemente la variable i. El resultado es que esta línea muestra el valor 163 convertido en un carácter, luego como un valor decimal y luego en hexadecimal. A continuación se muestra el resultado: 

£ = 163 or 0xA3 

No es necesario utilizar un argumento en la cadena de formato. Los argumentos también se pueden usar en cualquier orden y se pueden usar repetidamente, por lo que la siguiente declaración es válida: 

string text = string.Format("{1} {4} {2} {1} {3}", 

"quién", "yo", "luego", "soy", "pienso"); 

Si utilizamos String.Format para concatenar una serie de declaraciones y producir resultados es en gran parte una cuestión de preferencia personal. 

Formateo de cadenas 

Tanto los métodos ToString como String.Format pueden tomar cadenas de formato como parámetros para indicarles cómo formatear un valor. Para String.Format, esto se refiere a la cadena de formato dentro de los elementos de formato. Por ejemplo, en la declaración string.Format("0x{0:X}", 90) , la cadena de formato es la X dentro de las llaves. Las cadenas de formato se dividen en dos categorías generales: 


Las cadenas de formato estándar permiten determinar  cómo queremos que se muestre un valor en un nivel alto.

Las cadenas de formato estándar tienen en cuenta la configuración regional, por lo que permiten que el programa produzca una salida que sea apropiada para la configuración regional del ordenador. Por ejemplo, la  cadena de formato de fecha "d" indica un patrón de  fecha corto y produce un resultado similar al 4/7/2022 en los Estados Unidos o al 7/04/2022 en España. 

Las cadenas de formato personalizadas nos permiten  crear formatos que no son proporcionados por las  cadenas de formato estándar. Por ejemplo, la siguiente declaración produce un resultado similar a:  Son las 12  en punto.

Console.WriteLine(string.Format("Son     las {0:HH} en punto",DateTime.Now)); 

Podemos usar cadenas de formato personalizadas para producir resultados que sean similares a los producidos por las cadenas estándar, pero debemos utilizar las cadenas estándar siempre que sea posible para obtener los cambios apropiados si nuestro programa se ejecuta en un ordenador que este configurada para una configuración local diferente. 

Los métodos ToString y String.Format comprenden cientos de cadenas de formato estándar y personalizadas. La tabla siguiente enumera las cadenas de formato estándar más útiles para valores numéricos y Datetime

Cadenas de formatos para números estándard

 

Formato

Descripción

Ejemplo

C o c

Moneda

12.345,67  €

D o d

Decimal, sólo tipos enteros

12345

E o e

Notación científica

1.234567E+004

F o f

Punto fujo

12345,67

G o g

General (punto fijo o científico, lo que sea más corto)

12345,67

N o n

Número con decimales y separadores de miles

12.345,67

P o p

Porcentaje (multiplicado por 100 y añadido %)

0,12 se convierte en 12 %

X o x

Hexadecimal (sólo tipos integer)

3039

 

Algunos de estos formatos pueden tener un especificador de precisión opcional que controla el número de dígitos desplegado. Para la mayoría de estos tipos, el especificador de precisión indica el número de dígitos que se mostrarán después de la coma. Por ejemplo, si el valor es 12345,67, value.ToString ("C4") produce 12.345,6700 €.

Para la notación científica, el especificador de precisión indica el número de dígitos después de la coma en la mantisa. Por ejemplo, si el valor es 12345,67, value.ToString ("E2") produce 1,23E + 004.

Cadenas de formato para Datetime

 

Formato

Descripción

Ejemplo

d

Fecha corta

7/04/2022

D

Fecha larga

Jueves 7 de abril de 2022

f

Completa con hora corta

Jueves 7 de abril de 2022 14:23

F

Completa con hora larga

Jueves 7 de abril de 2022 14:23:16

g

General con hora corta

7/04/2022 14:23

G

General con hora larga

7/04/2022 14:23:16

m o M

Dia/ mes

7 /Abril

t

Hora corta

14:23

T

Hora larga

14:23:16

y o Y

Mes / año

Abril 2022

Además de estos formatos estándar, la estructura DateTime proporciona cuatro métodos que producen una salida similar a los especificadores de formato d, D, t y T. Estos métodos son ToShortDateString, ToLongDateString, ToShortTimeString y ToLongTimeString. 

Ejemplo Visualización de valores de moneda 

Modificamos el formulario de entrada de pedidos que creamos para el Manejo Valores porcentuales para que muestre el precio extendido, el subtotal, el impuesto sobre las ventas y el total general en formato de moneda.

Solución: El programa ya usa el método ToString para mostrar esos valores. El único cambio necesario es pasar la cadena de formato de moneda "C" a esas llamadas a ToString. Por ejemplo, el siguiente código muestra cómo el programa muestra el Gran Total en formato de moneda:

txtTotal.Text = Total.ToString("C"); 


sábado, 18 de junio de 2022

Como desactivar el firewall de Windows

Hay ocasiones en las que aunque no es recomendable, tenemos que desactivar el firewall de Windows. 

Para desactivar el firewall de Windows basta con pulsar sobre el panel de control en el icono principal de Windows, o teclearlo en la caja de texto si no lo vemos. Una vez en el panel de control elegimos Sistema y seguridad.

Como desactivar el firewall de Windows

Esto nos abrirá una pantalla desde la que pulsamos sobre Firewall de Windows Defender.

Como desactivar el firewall de Windows


En la siguiente pantalla vemos si están activadas las diferentes opciones de seguridad de nuestro equipo, a la izquierda vemos una lista de opciones, pulsamos sobre Cambiar la configuración de notificaciones.

Como desactivar el firewall de Windows

Nos abrirá una pantalla similar a la anterior en la que podemos activar o desactivar las diferentes opciones del Firewall para la red de Dominio, red privada o red pública.

Como desactivar el firewall de Windows



sábado, 11 de junio de 2022

Curso Avanzado de C#. Manipulación de cadenas II

Clases String adicionales 

La clase String es intuitiva y fácil de usar. Podemos utilizar sus métodos para examinar fácilmente las cadenas, eliminar secciones, recortar el inicio o el final de una cadena y extraer subcadenas. Sin embargo, la forma inusual en que se introducen cadenas en nuestro programa, las hace ineficaces para algunos propósitos. La figura muestra el programa de ejemplo de permutaciones.

Clases String adicionales


Este programa muestra una cadena grande que contiene todas las permutaciones de un conjunto de letras entre la A y la H. Hay 8 letras y (5040 permutaciones de esas ocho letras) por lo que el resultado es 5040 cadenas concatenadas. Para empeorar las cosas, el programa crea cada permutación con un carácter cada vez, por lo que cada permutación requiere la construcción de ocho cadenas más pequeñas. Esto significa que el programa construye 8 × 5040 = 40.320 cadenas en total, cada una de las cuales debe ser ingresada. Como resultado, el programa es bastante lento, tardando aproximadamente 23 segundos en producir estas 5.040 permutaciones utilizando la concatenación de cadenas. Para casos especiales como este, cuando la clase String es particularmente ineficiente, un programa puede obtener un mejor rendimiento utilizando las clases de procesamiento de cadenas especializadas: 


StringBuilder 

StringWriter 

StringReader 

El programa tomó solo 0.05 segundos para construir las permutaciones cuando utilizamos StringBuilder en lugar de concatenaciones de String. Cada una de estas clases de procesamiento de cadenas se describe en las siguientes secciones. 

StringBuilder 

La clase StringBuilder representa una cadena mutable no internada. Almacena datos de caracteres en una matriz y puede agregar, eliminar, reemplazar y agregar caracteres sin crear un nuevo objeto String o usar el grupo interno. Normalmente, un programa usa un StringBuilder para construir una cadena en una larga serie de pasos y luego llama al método ToString de StringBuilder para convertir el resultado en una cadena normal. Por ejemplo, el siguiente código utiliza StringBuilder para construir una cadena que contiene una serie de nombres de empleados en líneas separadas:

String[] NombresEmpleados =

{

      "Abel",

      "Bartolo",

      "Carlos",

      "David",

};

StringBuilder allNames = New StringBuilder();

foreach (string name in NombresEmpleados)

{

      allNames.Append("[" + name + "]" + Environment.NewLine);

}

txtEmpleados.Text = allNames.ToString();

El código comienza definiendo una matriz de nombres de empleados. Luego crea un StringBuilder y recorre los nombres en la matriz NombresEmpleados. Para cada nombre, el código llama al método Append de StringBuilder para agregar el nombre entre corchetes a la cadena. Una vez que ha procesado todos los nombres, el código llama al método ToString de StringBuilder para convertirlo en un String normal y muestra el resultado en la caja de texto txtEmpleados

La Tabla describe las propiedades más útiles de la clase StringBuilder.

 

Propiedad

Descripción

Capacity

Obtiene o establece el número de caracteres que puede contener StringBuilder. Si la cantidad de texto almacenado en StringBuilder excede esta cantidad, el objeto asigna más espacio. Si sabe que StringBuilder debe contener al menos un cierto número de caracteres, podemos utilizar esta propiedad para hacer que el objeto se preasigne

memoria en lugar de asignar memoria de forma incremental. Algunas versiones sobrecargadas del constructor de la clase  permiten especificar una capacidad inicial.

Length

Obtiene o establece el número actual de caracteres almacenados en StringBuilder. Si establecemos este valor a un menor valor que la longitud actual, el texto en StringBuilder se trunca.

El indexador de StringBuilder devuelve los caracteres almacenados en el objeto. Un programa puede usar el indexador para obtener y establecer valores de caracteres. Por ejemplo, la declaración allNames [10] = 'X' establece el carácter número 10 en X. 

La tabla describe los métodos más útiles de la clase StringBuilder.

 

Método

Descripción

Append

Añade una representación de cadena de un objeto al final del texto de StringBuilder

AppendFormat

Formatea una serie de objetos y agrega el resultado al final del texto de StringBuilder

EnsureCapacity

Garantiza que StringBuilder tenga al menos una capacidad determinada

Insert

Inserta una representación de cadena de un objeto en una posición dada en el texto de StringBuilder

Remove

Elimina un rango de caracteres del texto de StringBuilder

Replace

Reemplaza todas las instancias de un carácter o cadena con un nuevo carácter o cadena

ToString

Devuelve una representación de cadena normal del texto de StringBuilder

 

La clase StringBuilder agrega algo de sobrecarga a un programa y, a veces, hace que el código sea más difícil de leer, por lo que generalmente debemos usarlo solo si realizamos una gran cantidad de operaciones de cadena. En un conjunto de pruebas, la concatenación de cadenas simple fue más rápida que la creación y el uso de StringBuilder para menos de aproximadamente siete concatenaciones.

También hay que tener en cuenta en cuenta que los tiempos involucrados para algunas operaciones de cadena son pequeños. Pero utilizar StringBuilder para concatenar 10 cadenas puede ser un poco más rápido que realizar 10 concatenaciones simples de cadena, pero la cantidad total de tiempo ahorrado se mide en milisegundos. A menos que el programa repita esa operación muchas veces o haga concatenaciones mucho más largas, podemos sacrificar algunos milisegundos para que el código sea más fácil de entender. 

StringWriter 

La clase StringWriter proporciona una interfaz que facilita en algunos casos la creación de una cadena en un StringBuilder subyacente. La clase StringWriter proporciona métodos que facilitan la escritura secuencial de valores en una cadena. La tabla  describe los métodos más útiles de StringWriter. 

 

Método

Descripción

Flush

Vacía los datos almacenados en búfer en el StringWriter subyacente

ToString

Devuelve el contenido actual del objeto como una cadena

Write

Añade un elemento a los datos de la cadena. Las versiones sobrecargadas agregan char, string, int, double y otros muchos tipos de datos.

WriteAsync

Anexa de forma asíncrona un char,string o una matriz de caracteres al final de los datos de la cadena

WriteLine

Agrega un elemento a los datos de la cadena como lo hace Write y luego agrega una nueva línea

 

StringWriter puede ser útil cuando solo deseamos agregar valores a una cadena. StringWriter también implementa una interfaz TextWriter, lo que puede ser útil cuando otras clases requieren un TextWriter para producir una salida y deseamos almacenar esa salida en una cadena. Por ejemplo, el método Serialize de la clase XmlSerializer envía la salida a un TextWriter. Si queremos serializar en una cadena, podemos enviar la salida a StringWriter y luego usar el método ToString de StringWriter para obtener el resultado. Si necesita manipular los datos de la cadena subyacente de otras formas, como eliminar o reemplazar caracteres, StringBuilder proporciona más flexibilidad. 

StringReader 

La clase StringReader proporciona una implementación TextReader que lee fragmentos de datos tomados de un StringBuilder subyacente. Proporciona métodos que facilitan la lectura secuencial de fragmentos de texto de una cadena. La tabla  describe los métodos más útiles de StringReader.

 

Método

Descripción

Peek

Devuelve el siguiente carácter en los datos pero no avanza al carácter

Read

Devuelve el siguiente carácter de los datos y avanza al siguiente carácter. Una versión sobrecargada puede leer un bloque de caracteres

ReadAsync

Lee de forma asíncrona caracteres de StringReader en un búfer

ReadBlock

Lee hasta un número máximo de caracteres de StringReader en un búfer que comienza en un índice especificado

ReadBlockAsync

Lee asincrónicamente hasta un número máximo de carácteres de StringReader en un búfer que comienza en un índice especificado.

ReadLine

Lee carácteres de StringReader hasta que encuentra el final de línea

ReadLineAsync

Lee de forma asíncrona los caracteres de StringReader hasta que encuentra el fin de la línea

ReadToEnd

Devuelve el texto restante de StringReader como una cadena

ReadToEndAsync

Devuelve de forma asíncrona el texto restante de StringReader como una cadena

 

La clase StringReader proporciona acceso a los datos de StringBuilder a un nivel relativamente bajo. A menudo, un programa usa un StringReader solo porque necesita pasar información a un método predefinido que requiere un StringReader o TextReader como parámetro. 

Veamos un ejemplo: Usando StringBuilder 

Usando solo StringBuilders (sin Strings), escribir un programa que muestre todas las subsecuencias iniciales de las letras del alfabeto A, AB, ABC, y así sucesivamente en un TextBox, como se muestra en la figura 

StringBuilder

Private void Form1_Load(Object sender, EventArgs e)

{

      // Genera un StringBuilder sosteniendo los ABC

      StringBuilder letters =

      New StringBuilder("ABCDEFGHIJKLMNOPQRSTUVWXYZ");

      // Éste contiene la siguiente línea de letras.

      StringBuilder line = New StringBuilder();

      // Crea el resultado StringBuilder.

      StringBuilder result = New StringBuilder();

      // Recorre las letras.

      For (int i = 0; i < 26; i++)

      {

            // Agregua la siguiente letra a la línea.

            line.Append(letters[i]);

            //Agrega una línea al resultado.

            result.AppendLine(line.ToString());

      }

      // Muestra el resultado.

      stringBuilderTextBox.Text = result.ToString();

      stringBuilderTextBox.Select(0, 0);

}

El código construye un StringBuilder que contiene las letras del alfabeto. Hace un segundo StringBuilder para mantener una línea de salida y un tercero para mantener el resultado final. A continuación, el código recorre los números del 0 al 25. Para cada valor de i, el código agrega el i-ésimo carácter en letras al valor en línea. Luego agrega el nuevo valor de línea al resultado, siguiéndolo con una nueva línea. Cuando el código termina su ciclo, muestra el resultado. En este ejemplo, no está claro si usar StringBuilder es más rápido que usar concatenaciones de cadenas simples. En una prueba que ejecutó este código y un código similar que realizó concatenaciones de cadenas 100.000 veces, la versión de StringBuilder tomó aproximadamente el 54 por ciento de tiempo, por lo que hay un ahorro de tiempo, pero el resultado para una sola ejecución es insignificante.