jueves, 29 de agosto de 2013

Caracteres y Cadenas de Caracteres en C# - Parte 2

Tabla de Contenido

0. Introducción
1. El Tipo de Dato string
2. Concatenación de Cadenas de Caracteres
3. Comparaciones en las Cadenas de Caracteres

4. Conclusiones
5. Glosario
6. Referencias

0. Introducción

En está segunda parte vamos a hablar de un tipo de dato fundamental en C#. Se trata del tipo string que nos permite manipular, representar texto como una secuencia (cadena o ristra) de caracteres basados en la codificación Unicode. El tipo string también cuenta con su alias en Framework .NET: System.String [1]) (más adelante dedicaré más tiempo en la manipulación de texto en C# y este tipo es fundamental en esta tarea el cual nos permite representar texto en las aplicaciones de cualquier complejidad).

1. El Tipo de Dato string

Como ya fue dicho el tipo de dato string (alias de System.String). Una cadena de caracteres está compuesta por unidades básicas llamadas caracteres (ver artículo anterior: Caracteres y Cadenas de Caracteres en C# - Parte 1). Para particularizar, una cadena de caracteres es inmutable lo cual significa que cada cadena posible cadena de caracteres que se pueda formar a partir de un alfabeto (A-Z, a-z, por ejemplo) tiene una representación que no puede ser cambiada/alterada (de ahí su nombre) y que si una variable de tipo string que haga referencia a una de estas cadenas de caracteres y que en un momento dado cambie a través de funciones (métodos, eventos, etc) la representación (e.gr., de minúsculas a mayúsculas) creará una nueva secuencia en el heap del programa.

Para formar una literal de tipo string basta con encerrar la secuencia de caracteres dentro de comillas doble; así:

string cadenaCaracteres = "Lenguaje de Programación C#";

Hay que tener en mente, que el tipo de dato string es de tipo por referencia, y no de tipo por valor. Sin embargo, el operador de igualdad (=) sigue la misma semántica que con los tipos por valor; de este modo:

string a = "prueba";
string b = "prueba";
Console.Write (a == b); // Devuelve True

También podemos embeber secuencias de escape como literales tipo char dentro de una cadena de caracteres. Lo único que tenemos que hacer es algo como lo que viene a continuación:

string a = "Aquí podemos poner dentro un tabulador:\t";

Para los casos donde requerimos construir una cadena de caracteres que represente la ruta a un recurso en un servidor, el separador de ruta (\) debe ser representado con la secuencia de escape \\, vemos que es necesario escribirlo dos veces, como en:

string ruta = "\\\\servidor\\carpeta\\ClaseCSharp.cs";

¿Cómo podemos evitar esta complicación de estar escribiendo dos veces el caracter de backslah? Por medio literales cadena de caracteres verbatim [2]. Este símbolo, @, no soporta las secuencias de escape dentro de las cadenas de caracteres, de lo cual nos podemos tomar ventaja para evitar escribir dos veces el caracter backslash. Miremos:

string rutaConVerbatim = @ "\\servidor\carpeta\ClaseCSharp.cs";

Otra de las utilidades de esta literal string verbatim es la de expandir una cadena de caracteres en múltiples líneas. Así:

string conSecuenciasDeEscape = "Primera Línea\r\nSegunda Línea";
string conVerbatim = @ "Primera Línea
Segunda Línea";

Podemos comprobar que ambas cadenas caracteres son iguales (siempre y cuando el IDE usa los separadores de línea CR-LF):

Console.WriteLine (conSecuenciasDeEscape == conVerbatim);

2. Concatenación de Cadenas de Caracteres

El operador + (operador de suma sobreescrito) permite concatenar dos cadenas de caracteres. Como en:

string s = "a" + 5; // a5

En los casos que uno de los operandos sea diferente a una cadena de caracteres, de forma implícita el método ToString es llamado en ese operando. Por ejemplo:

string s = "a" + 5; // a5

Más adelante veremos que el uso abusivo del operador + para concatenar cadenas de caracteres resulta ineficiente. En lugar de este operador, utilizaremos el tipo System.Text.StringBuilder.

3. Comparaciones en las Cadenas de Caracteres

El tipo de dato string no soporta los operadores de comparación < y > para comparaciones de cadenas (a causa de que se trata de un tipo por referencia). Para ello contamos con el método CompareTo; del cual hablaremos más adelante con lujo de detalles.

4. Conclusiones

He descrito, en su elemental esencia, el tipo de dato string en lenguaje de programación C#. Su importancia en la representación, y manipulación de texto. Se habló sobre la oportunidad de incluir secuencias de escape a modo de literales de tipo char dentro de las cadenas de caractares. Además, se trabajó con el uso del literal string verbatim muy útil para omitir secuencias de escape en las cadenas de caracteres (en particular, en las cadenas que representan la ruta de un recurso en una red). Por otro lado, el uso del operador + que permite la concatenación (unión) de cadenas de caracteres. Finalmente, apuntes sobre las comparaciones permitidas en cadenas.

5. Glosario

- Path
- Separador de ruta
- Verbatim

6. Referencias

[2] C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.


O

Caracteres y Cadenas de Caracteres en C# - Parte 1

Tabla de Contenido

0. Introducción
1. El Tipo de Dato Char
1.1 Secuencias de Escape
1.2 Conversiones Char
1.3 Ejemplos
2. Conclusiones
3. Glosario
4. Referencias

0. Introducción

Voy a dedicar esta primera parte para hablar acerca de algunas construcciones que permiten manipular datos en forma de caracteres (unidad básica) y cadenas de caracteres. También las operaciones asociadas a estos tipos de datos esenciales para manipular entrada y salida de datos, representación de valores especiales de acuerdo a la plataforma adyacente, los aspectos regionales (idioma y sus variaciones, por ejemplo).

Es importante que conozcamos y comprendamos la utilidad de los caracteres y las cadenas formadas de estas unidades para el diseño de algoritmos que utilicen eficientemente el espacio en memoria y los ciclos de la unidad de procesamiento. También que conozcamos algunos aspectos que pueden hacer que nuestras aplicaciones sean o no eficientes por el uso de los recursos disponibles en el cómputo adyacente.

1. El Tipo de Dato char

El tipo de dato char ocupa dos bytes (es decir, 16 bits) para codificar, representar, y manipulación  cualquier caracter del juego de caracteres de Unicode [1]. En Framework .NET, el alias para este tipo es System.Char [2]. En C#, en particular, un caracter de tipo char se representa encerrando el caracter en cuestión entre comillas simples; así:

char c = 'A'; // El caracter representado en un dato tipo char

1.1 Secuencias de Escape

Este es un conjunto especial de caracteres que ayudan a representar comodines (por así decirlo) o construcciones literales para elementos de representación o formateo de texto. Comúnmente, el carácter de tabulación horizontal y vertical, de nueva o salto de línea, backspace (remoción de caracter a la izquierda), entre otros más.

Para especificar una secuencia de escape basta con añadir un backslash (\) y el caracter correspondiente de significado particular.

char nuevaLinea = '\n';
char backSlash = '\\';

En la Tabla 1 [3] se presenta el conjunto de secuencias de espcape en el lenguaje de programación C#:
Tabla 1. Secuencias de Escape.
Tabla 1. Secuencias de Escape.
Gracias a que el tipo de dato char nos permite representar cualquier caracter Unicode; las secuencias de escape \u (o también \x) nos permite especificar un caracter Unicode por medio de los cuatro dígitos de código hexadecimal. Así:

char simboloCopyright = '\u00A9';
char simboloOmega = '\u03A9';
char nuevaLinea = '\u000A';

1.2 Conversiones Char

Todas las conversiones de char a cualquier tipo de dato numérico son permitidas siempre y cuando estos últimos soporten el tipo short sin signo (es decir, ushort).

char c = 'A'; // El caracter representado en un dato tipo char
char caracterEnInt = c; // conversión implícita permitada
char caracterEnByte = c; // conversión implícita no permitida (no es posible convertir de char a byte).

1.3 Algunos Ejemplos

En este primer ejemplo (LiteralCaracter), se define la variable tipo char c (línea 5) y se asigna el caracter 's' al espacio de memoria localizado de esta variable (que es el elemento número 5 de la cadena de caracteres "perls"):

Archivo C# LiteralCaracter.cs [enlace alternativo]:

2. Conclusiones

En esta primera parte de Caracteres y Cadenas de Caracteres en C# hemos entendido la utilidad del tipo de dato char idóneo para representar (en 16 bits) caracteres individuales de la codificación Unicode. Se incluyeron ejemplos sobre el uso básico de este tipo de datos. Anteriormente, también se habló acerca de las secuencias de escape que son construcciones o comodines para representar caracteres especiales (tabulación, retorno de carro, backspace, entre otro más).

3. Glosario

- Secuencia de escape
- Unicode

4. Referencias

[1] Unicode - Wikipedia, the free encyclopedia - http://en.wikipedia.org/wiki/Unicode
[4] C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.


O

martes, 13 de agosto de 2013

Operadores Condicionales en C#

Tabla de Contenido

0. Introducción
1. Uso de los Operadores &&, ||
2. Uso de los Operadores &, |
3. El Operador Condicional
4. Conclusiones
5. Glosario
6. Referencias

0. Introducción

En C# podemos encontrar operadores condicionales que nos permite crear expresiones simples o compuestas a la hora de evaluar el camino que debe tomar el flujo de ejecución de un algoritmo en particular basadas en entradas de usuario, peticiones de servicios, monitorización del estado de salud de una aplicación, etc. Estos operadores son: && (and), || (or).

1. Uso de los Operadores && ||

El uso de estos operadores es bastante práctico. En el ejemplo que se presenta a continuación, el método UsarParaguas retorna verdadero si el día está lluvioso o soleado, en caso contrario falso cuando esté venteando (dado que los paraguas no son útiles en estas situaciones):

Archivo C# OperadoresCondicionalesCortoCircuito.cs [enlace alternativo]:
Los operadores en el ejemplo anterior usan la técnica de evaluación de corto circuito, esto quiere decir que una vez la primera expresión se evalúe, en el caso de && a verdadero (true) el resto de las expresiones lógicas se continúan evaluando, en caso contrario, cuando la primera evaluación retorna falso (false), inmediatamente se interrumpe la evaluación de las expresiones lógicas restantes. Esto es eficiente debido a que no es necesario invertir recursos como espacio en memoria y tiempo de procesador en evaluar expresiones que no van alterar la evaluación general (como podría ocurrir con el encabezado de la instrucción de control condicional if (más adelante nos extenderemos en este interesante tópico)).

Por otro lado, la evaluación corto circuito sobre || (or), una vez la primera expresión lógica nos genere verdadero (true) se continúa con la siguiente instrucción, y no es necesario evaluar el resto de las expresiones. Si ocurre lo contrario, es decir, si se retorna falso (false) en la primera evaluación, se continúa probando con las expresiones lógicas restantes. Esto se debe a la naturaleza lógica inclusiva de este operador.

En el código fuente C# anterior, podemos observar que cuando !ventoso se evalúa a falso, la expresión lógica (lluvioso || soleado) no será evaluada. En su interior, esta última expresión sí lluvioso es verdadero (true), soleado no es evaluado (pues es posible que esté lloviendo y haciendo sol, y en cualquier de los casos se usará paraguas).

Además, la técnica de evaluación de corto circuito, es esencial en expresiones que pudieran generar excepciones (más acerca de tópica en artículos posteriores), por ejemplo:

if (cadenaTexto != null && cadenaTexto.Length > 0)

Comprueba que la variable cadenaTexto es distinta de null en la primera expresión (cadenaTexto != null) es útil (y necesario) para evitar el lanzamiento de la excepción NullReferenceException [2].

2. Uso de los Operadores & y |

C# también posee los operadores condicionales & y |, que a diferencia de && y ||, no evalúan las expresiones usando la técnica corto circuito. Un caso de utilidad de estos operadores es cuando las expresiones del encabezado de un if, por ejemplo, requieren cambiar el valor de una variable. Esta es una de las razones por lo que son poco utilizados, pues en la práctica hacer esto conduce a código poco legible.

Nota

A diferencia de otros lenguajes, como C y C++, C# también utiliza los operadores & y | no sólo para evaluaciones lógicas de corto circuito, sino además para operaciones bitwise (bit a bit) sobre operandos numéricos.

3. El Operador Condicional

Este operador condicional también se le conoce como operador ternario (debido a que su estructura sintáctica requiere de hasta 3 operandos para llevar a cabo la evaluación correspondiente). Es el único operador que requiere 3 operandos, y tiene la siguiente forma [4]:


condicion ? primera_expresion : segunda_expresion;

Si condicion es verdadero, primera_expresion es evaluado, sino segunda_expresion es evaluado. Veamos un ejemplo:

Archivo C# OperadorCondicional.cs [enlace alternativo]:

(En artículos posteriores veremos la utilidad de este operador en consultas LINQ.)

En [1] podemos encontrar algunos beneficios de este operador; por ejemplo, la escritura de instrucciones condicionales más cortas y expresivas, o la de asignación a variables constantes.

4. Conclusiones

Hemos comprendido la utilidad de los operadores condicionales útiles para crear instrucciones de alternación en el flujo de ejecución de un algoritmo. La evaluación de corto circuito ayuda a crear expresiones lógicas más eficientes en tiempo de procesador y espacio en memoria.

5. Glosario

- Corto circuito
- Ternario

6. Referencias

[1] c# - Benefits of using the conditional ?: (ternary) operator - http://stackoverflow.com/questions/3312786/benefits-of-using-the-conditional-ternary-operator
[3] C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[4] ?: Operator (C# Reference) - http://msdn.microsoft.com/en-us/library/ty67wk28.aspx


O