InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
Tutorial C#
Introduccion a C#
Programacion con C#
Fundamentos de C#
Operadores
Instrucciones
Estrcuturas de control.
Definición de clases
Creación de objetos
Herencia y métodos virtuales
Polimorfismo
Ocultación de miembros
Miembros de tipo
Encapsulación
Espacios de nombres
Importación de espacios de nombres
Espacio de nombres distribuidos
Variables y tipos de datos
Tablas unidimensionales
Tablas multidimensionales
La clase System.Array
Cadenas de texto
Constantes
Orden de inicialización de variables
Métodos
Métodos externos
Constructores
Destructores
Propiedades
Indizadores
Redefinición de operadores
Delegados y eventos
La clase MulticastDelegate
Llamadas asíncronas
Implementación interna de los delegados
Eventos
Estructuras
Boxing y unboxing
Constructores de estructuras
Enumeraciones
Interfaces
Excepciones
Otras instrucciones
Atributos
Definición de nuevos atributos
Lectura de atributos en tiempo de ejecución
Atributos de compilación
Pseudoatributos
Código inseguro
Definición de punteros
Manipulación de punteros
Operadores relacionados con código inseguro
Fijación de variables apuntadas
Novedades de C# 2.0
Genéricos
Tipos parciales
Iteradores
Mejoras en la manipulación de delegados
Tipos anulables
Modificadores de visibilidad de bloques get y set
Clases estáticas
Referencias a espacios de nombres
Supresión temporal de avisos
Atributos condicionales
Incrustación de tablas en estructuras
Modificaciones en el compilador
También puedes ver ...
TransactionScope - Simplificando el trabajo con transacciones.
LinQ To SQL - Un ejemplo sencillo
Cómo activar Intelisense (autocompletado) en el Web.config
Leer un campo XML de SQL Server 2005 con C#
TripleDES - Un ejemplo practico en C#
Mostrar un GridView dentro de un DataList
String.Format
Métodos Extensores: INNER JOIN
Problemas en la instalación de Visual Studio 2008-Visual studio web authoring component
Redimiento de VS2008

Afiliados
La Web del programador
MundoProgramacion


 

Cadenas de texto

    Una cadena de texto no es más que una secuencia de caracteres. .NET las representa internamente en formato Unicode, y C# las representan externamente como objetos de un tipo de dato string, que no es más que un alias del tipo System.String de la BCL.

    Las cadenas de texto suelen crearse a partir literales de cadena o de otras cadenas previamente creadas. Ejemplos de ambos casos se muestran a continuación:


 string cadena1 = "José Antonio";
 string cadena2 = cadena1;

    En el primer caso se ha creado un objeto string que representa a la cadena formada por la secuencia de caracteres José Antonio indicada literalmente (nótese que las comillas dobles entre las que se encierran los literales de cadena no forman parte del contenido de la cadena  que representan sino que sólo se usan como delimitadores de la misma) En el segundo caso la variable cadena2 creada se genera a partir de la variable cadena1 ya existente, por lo que ambas variables apuntarán al mismo objeto en memoria.

    Hay que tener en cuenta que el tipo string es un tipo referencia, por lo que en principio la comparación entre objetos de este tipo debería comparar sus direcciones de memoria como pasa con cualquier tipo referencia. Sin embargo, si ejecutamos el siguiente código veremos que esto no ocurre en el caso de las cadenas:


using System;
public class IgualdadCadenas
{
 public static void Main()
 {
  string cadena1 = "José Antonio";
  string cadena2 = String.Copy(cadena1);
  Console.WriteLine(cadena1==cadena2);
 }
}

    El método Copy() de la clase String usado devuelve una copia del objeto que se le pasa como parámetro. Por tanto, al ser objetos diferentes se almacenarán en posiciones distintas de memoria y al compararlos debería devolverse false como pasa con cualquier tipo referencia. Sin embargo, si ejecuta el programa verá que lo que se obtiene es precisamente lo contrario: true. Esto se debe a que para hacer para hacer más intuitivo el trabajo con cadenas, en C# se ha modificado el operador de igualdad para que cuando se aplique entre cadenas se considere que sus operandos son iguales sólo si son lexicográficamente equivalentes y no si referencian al mismo objeto en memoria. Además, esta comparación se hace teniendo en cuenta la capitalización usada, por lo que “Hola”==”HOLA” ó “Hola”==”hola” devolverán false ya que contienen las mismas letras pero con distinta capitalización.

    Si se quisiese comparar cadenas por referencia habría que optar por una de estas dos opciones: compararlas con Object.ReferenceEquals() o convertirlas en objects y luego compararlas con == Por ejemplo:


 Console.WriteLine(Object.ReferecenceEquals(cadena1, cadena2));
 Console.WriteLine( (object) cadena1 == (object) cadena2);

    Ahora sí que lo que se comparan son las direcciones de los objetos que representan a las cadenas en memoria, por lo que la salida que se mostrará por pantalla es:

 False

 False

    Hay que señalar una cosa, y es que aunque en principio el siguiente código debería mostrar la misma salida por pantalla que el anterior ya que las cadenas comparadas se deberían corresponder a objetos que aunque sean lexicográficamente equivalentes se almacenan en posiciones diferentes en memoria:


using System;
public class IgualdadCadenas2
{
 public static void Main()
 {
  string cadena1 = "José Antonio";
  string cadena2 = "José Antonio";
  Console.WriteLine(Object.ReferenceEquals(cadena1, cadena2));
  Console.WriteLine( ((object) cadena1) == ((object) cadena2));
 }
}

    Si lo ejecutamos veremos que la salida obtenida es justamente la contraria:


 True

 True

    Esto se debe a que el compilador ha detectado que ambos literales de cadena son  lexicográficamente equivalentes y ha decidido que para ahorra memoria lo mejor es almacenar en memoria una única copia de la cadena que representan y hacer que ambas variables apunten a esa copia común. Esto va a afectar a la forma en que es posible manipular las cadenas como se explicará más adelante.

Al igual que el significado del operador == ha sido especialmente modificado para trabajar con cadenas, lo mismo ocurre con el operador binario +. En este caso, cuando se aplica entre dos cadenas o una cadena y un carácter lo que hace es devolver una nueva cadena con el resultado de concatenar sus operandos. Así por ejemplo, en el siguiente código las dos variables creadas almacenarán la cadena Hola Mundo:


public class Concatenación
{
 public static void Main()
 {
  string cadena = "Hola" + " Mundo";
  string cadena2 = "Hola Mund" + 'o';
 }
}

Por otro lado, el acceso a las cadenas se hace de manera similar a como si de tablas de caracteres se tratase: su “campo” Length almacenará el número de caracteres que la forman y para acceder a sus elementos se utiliza el operador []. Por ejemplo, el siguiente código muestra por pantalla cada carácter de la cadena Hola en una línea diferente:


using System;
public class AccesoCadenas
{
 public static void Main()
 {
  string cadena = "Hola";         
  Console.WriteLine(cadena[0]);
  Console.WriteLine(cadena[1]);
  Console.WriteLine(cadena[2]);
  Console.WriteLine(cadena[3]);
 }
}

    Sin embargo, hay que señalar una diferencia importante respecto a la forma en que se accede a las tablas: las cadenas son inmutables, lo que significa que no es posible modificar los caracteres que las forman. Esto se debe a que el compilador comparte en memoria las referencias a literales de cadena lexicográficamente equivalentes para así ahorrar memoria, y si se permitiese modificarlos los cambios que se hiciesen a través de una variable a una cadena compartida afectarían al resto de variables que la compartan, lo que podría causar errores difíciles de detectar. Por tanto, hacer esto es incorrecto:


string cadena = "Hola";
cadena[0]="A"; //Error: No se pueden modificar las cadenas

    Sin embargo, el hecho de que no se puedan modificar las cadenas no significa que no se puedan cambiar los objetos almacenados en las variables de tipo string.Por ejemplo, el siguiente código es válido:

 
String cad = "Hola";
 cad = "Adios"
 // Correcto, pues no se modifica la cadena almacenada en cad
 // sino que se hace que cad pase a almacenar otra cadena distinta..

    Si se desea trabajar con cadenas modificables puede usarse Sytem.Text.StringBuilder, que funciona de manera similar a string pero permite la modificación de sus cadenas en tanto que estas no se comparten en memoria. Para crear objetos de este tipo basta pasar como parámetro de su constructor el objeto string que contiene la cadena a representar mediante un StringBuilder, y para convertir un StringBuilder en String siempre puede usarse su método ToString() heredado de System.Object. Por ejemplo:


using System.Text;
using System;
public class ModificaciónCadenas
{
 public static void Main()
 {
  StringBuilder cadena = new StringBuilder("Pelas");
  String cadenaInmutable;
  cadena[0] = 'V';
  Console.WriteLine(cadena); // Muestra Velas     
  cadenaInmutable = cadena.ToString();
  Console.WriteLine(cadenaInmutable); // Muestra Velas
 }
}

    Aparte de los métodos ya vistos, en la clase System.String se definen muchos otros métodos aplicables a cualquier cadena y que permiten manipularla. Los principales son:

  • int IndexOf(string subcadena): Indica cuál es el índice de la primera aparición de la subcadena indicada dentro de la cadena sobre la que se aplica. La búsqueda de dicha subcadena se realiza desde el principio de la cadena, pero es posible indicar en un segundo parámetro opcional de tipo int cuál es el índice de la misma a partir del que se desea empezar a buscar. Del mismo modo, la búsqueda acaba al llegar al final de la cadena sobre la que se busca, pero pasando un tercer parámetro opcional de tipo int es posible indicar algún índice anterior donde terminarla.

    Nótese que es un método muy útil para saber si una cadena contiene o no alguna subcadena determinada, pues sólo si no la encuentra devuelve un –1.
  • int LastIndexOf(string subcadena):  Funciona de forma similar a IndexOf() sólo que devuelve la posición de la última aparición de la subcadena buscada en lugar de devolver la de la primera.
  • string Insert(int posición, string subcadena): Devuelve la cadena resultante de insertar la subcadena indicada en la posición especificada de la cadena sobre la que se aplica.
  • string Remove(int posición, int número): Devuelve la cadena resultante de eliminar el número de caracteres indicado que hubiese en la cadena sobre al que se aplica a partir de la posición especificada.
  • string Replace(string aSustituir, string sustituta): Devuelve la cadena resultante de sustituir en la cadena sobre la que se aplica toda aparición de la cadena aSustituir  indicada por la cadena sustituta especificada como segundo parámetro.
  • string Substring(int posición, int número): Devuelve la subcadena de la cadena sobre la que se aplica que comienza en la posición indicada y tiene el número de caracteres especificados. Si no se indica dicho número se devuelve la subcadena que va desde la posición indicada hasta el final de la cadena.
  • string ToUpper() y string ToLower(): Devuelven, respectivamente, la cadena que resulte de convertir a mayúsculas o minúsculas la cadena sobre la que se aplican.

    Es preciso incidir en que aunque hayan métodos de inserción, reemplazo o eliminación de caracteres que puedan dar la sensación de que es posible modificar el contenido de una cadena, en realidad las cadenas son inmutables y dicho métodos lo que hacen es devolver una nueva cadena con el contenido correspondiente a haber efectuado las operaciones de modificación solicitadas sobre la cadena a la que se aplican. Por ello, las cadenas sobre las que se aplican quedan intactas como muestra el siguiente ejemplo:


using System;
public class EjemploInmutabilidad
{
 public static void Main()
 {
  string cadena1="Hola";
  string cadena2=cadena1.Remove(0,1);
  Console.WriteLine(cadena1);
  Console.WriteLine(cadena2);
 }
}

    La salida por pantalla de este ejemplo demuestra lo antes dicho, pues es:


 Hola

 ola

    Como se ve, tras el Remove() la cadena1 permanece intacta y el contenido de cadena2 es el que debería tener cadena1 si se le hubiese eliminado su primer carácter.


Inicio | Tutorial C# La clase System.ArrayTutorial C#Constantes Versión para imprimir Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial C# La clase System.ArrayTutorial C#Constantes Versión para imprimir

Cadenas de texto
Autor: José Antonio González Seco
Visitas: 15753 Fecha de publicación: 09/10/2006
José Antonio es experto en tecnologias Microsoft. Imparte cursos y conferencias en congresos sobre C# y .NET en Universidades de toda España (Sevilla, Barcelona, San Sebastián, Valencia, Oviedo, etc.) en representación de grandes empresas como Microsoft.




18/08/2008 SQL Server 2008
Visitas: 272 | Comentarios: 0 | Archivo: Articulos
Categorias: Transact-SQL
Visitas: 233 | Comentarios: 0 | Archivo: Articulos
Categorias: C#|ADO.NET|LinQ
Visitas: 268 | Comentarios: 1 | Archivo: Articulos
Categorias: Humor
Visitas: 185 | Comentarios: 0 | Archivo: Articulos
Categorias: WCF
Visitas: 162 | Comentarios: 0 | Archivo: Articulos
Categorias: WCF
Visitas: 247 | Comentarios: 0 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 325 | Comentarios: 5 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 5226 | Comentarios: 4 | Archivo: Articulos
Categorias: C#|Transact-SQL|LinQ
Visitas: 658 | Comentarios: 1 | Archivo: Articulos
Categorias: Visual Studio
Visitas: 1551 | Comentarios: 1 | Archivo: Articulos
Categorias: Transact-SQL

Útimos temas recibidos en los foros ...
INSTALAR VB.NET 2005 EXPRESS EN WINDOWS VISTA por tito2701 ... [Visual Basic .NET] 13 05/07/2007
LLave Primaria por Martin ... [ORACLE] 6 22/06/2007
dar formato a mail por Pako ... [C#] 4 16/03/2007
MP3 en Windows Vista por Alf ... [Actualidad] 3 20/04/2008
autogenerado por mily ... [Visual Basic .NET] 0 27/08/2008
Instalación de Oracle por Tatatn ... [ORACLE] 0 27/08/2008
For Update, existe alguna otra forma? por Sus ... [ORACLE] 1 27/08/2008
Cambiar el color del nodo de un treeview por Moises Bermdez Contreras ... [ASP.NET] 3 15/10/2007
librerias dinamicas por lupitaor ... [C#] 2 26/08/2008
Vista SQL 2005 limitada por Factor ... [SQL] 2 26/08/2008
Combobox por Corven ... [C#] 4 10/07/2008
Datagrid view por Jazmin ... [ASP.NET] 5 25/08/2008

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
29/09/2006 Common Language Runtime - CLR    forma parte de...Conceptos generales .NET
03/10/2006 Definición de clases    forma parte de...Tutorial C#
01/07/2008 LinQ To SQL - Un ejemplo sencillo
06/09/2006 ¿Qué es el Collation en SQL ?
28/06/2006 Excepciones en PL/SQL    forma parte de...Tutorial PL/SQL
26/02/2007 Como generar automáticamente una cadena de conexión OLEDB en Visual Basic 6
23/05/2006 Cursores en PL/SQL    forma parte de...Tutorial PL/SQL
03/10/2006 Creación de objetos    forma parte de...Tutorial C#
02/09/2007 Procedimientos almacenados en Transact SQL    forma parte de...Tutorial de Transact SQL
03/10/2006 Operadores    forma parte de...Tutorial C#

 

Encuesta
¿A que perfil te adaptas mejor?
[Ver] [Votar]