String em C#

13
Introdução O tipo string apesar de se comportar como um value type é na verdade um reference type. Apesar disso, devemos considerar que estamos trabalhando com um value type quando estamos manipulando strings, tendo em vista que este tipo de dado foi programado para funcionar como tal A classe string possui uma série de métodos estáticos e não estáticos, que são utilizamos para formatação, concatenação, desmembramento, substring, etc. Vamos analisar alguns destes métodos da classe string. O método Substring O método substring é um método não estático que permite pegarmos uma porção de uma string. Para utilizarmos o método substring, basta chamar o método a partir de uma variável string ou mesmo de uma string literal, conforme o exemplo. string nome = "Testando da Silva"; string sobreNome = nome.Substring(12,5); O método substring aceita como parâmetro a posição inicial que queremos obter e quantos caracteres devem ser extraídos. Caso não seja informado o número de caracteres a ser extraído, a função retornará o restante da string a partir da posição inicial informada. O método IndexOf O método IndexOf é utilizado para localizar uma determinada palavra dentro da string. Este método retornará a posição da string desejada. Caso a string não seja encontrada, será retornado o valor -1. string nome = "Testando da Silva"; int pos = nome.IndexOf("Silva"); //A partir do índice 5 int pos2 = nome.IndexOf("Silva", 5);

Transcript of String em C#

Page 1: String em C#

Introdução

O tipo string apesar de se comportar como um value type é na verdade um reference type. Apesar disso, devemos considerar que estamos trabalhando com um value type quando estamos manipulando strings, tendo em vista que este tipo de dado foi programado para funcionar como tal

A classe string possui uma série de métodos estáticos e não estáticos, que são utilizamos para formatação, concatenação, desmembramento, substring, etc. Vamos analisar alguns destes métodos da classe string.

O método Substring

O método substring é um método não estático que permite pegarmos uma porção de uma string. Para utilizarmos o método substring, basta chamar o método a partir de uma variável string ou mesmo de uma string literal, conforme o exemplo.

string nome = "Testando da Silva";

string sobreNome = nome.Substring(12,5);

O método substring aceita como parâmetro a posição inicial que queremos obter e quantos caracteres devem ser extraídos. Caso não seja informado o número de caracteres a ser extraído, a função retornará o restante da string a partir da posição inicial informada.

O método IndexOf

O método IndexOf é utilizado para localizar uma determinada palavra dentro da string. Este método retornará a posição da string desejada. Caso a string não seja encontrada, será retornado o valor -1.

string nome = "Testando da Silva";int pos = nome.IndexOf("Silva");//A partir do índice 5int pos2 = nome.IndexOf("Silva", 5);

Conforme vimos no exemplo, é possível informar a posição inicial para busca como um parâmetro adicional.

Funções ToUpper e ToLower

As funções ToUpper e ToLower permitem colocar uma string em letra minúsculas ou maiúsculas, conforme o exemplo a seguir.

string nome = "Maurício";

nome = nome.ToUpper();nome = nome.ToLower();

Page 2: String em C#

Funções StartsWith e EndsWith

As funções startswith e endswith verificam se a string começo ou termina com uma determinada palavra ou caracter. Estas funções retornam um valor booleano (true ou false).

string arquivo = "comctl32.dll";

if(nome.StartsWith("com")) Console.WriteLine("Começa com COM!");

if(nome.EndsWith(".dll")) Console.WriteLine("É uma dll!");

Funções TrimStart, TrimEnd e Trim

As funções de Trim servem para remover espaços em branco das strings. A função TrimStart remove os espaços em branco do início da string, já a função TrimEnd remove os espaços em branco do final da string. A função Trim remove os espaços em branco do inicio e do fim da string.

string nome = " MAURICIO ";

nome = nome.TrimEnd(); nome = nome.TrimStart();

nome = nome.Trim();

Funções PadLeft e PadRight

As funções PadLeft e PadRight servem para preencher uma string a esquerda ou a direita com um caracter especificado. Os exemplos a seguir mostra o uso das funções PadLeft e PadRight.

string nome = "Mauricio";

nome = nome.PadRight(10, ' '); // "Mauricio "

string codigo = "123"; codigo = codigo.PadLeft(6, '0'); // "000123"

Funções String.Join e String.Split

A função Split serve para quebrar uma string em um array de strings de acordo com um separador. Ao contrário da função split, a função Join concatena um array de string inserindo um separador.

string linha = "Teste, 10, 20, 10/06/2007";

string[] campos = linha.Split(',');

Page 3: String em C#

string linhaNova = String.Join(';', campos);

A Função String.Format

A função String.Format é uma das funções mais versáteis da classe string. Esta função permite a criação de uma string baseada em um padrão. Podemos colocar dentro do padrão da string de formatação alguns tokens que poderam ser substituídos por variáveis passadas por parâmetro no comando format.

string teste = String.Format("Vou colocar o {0} aqui.", "parâmetro");

No exemplo acima, o padrão da string (primeiro parâmetro) contém um token {0}. Este token indica que este valor deve ser substituido pelo segundo parâmetro passado para a função (neste caso a palavra “parâmetro”).

sTeste = String.Format("Formatação de string com {0} parâmetro. ","Agora são {1}. Valor numérico: {2}", 1, Now(), 15.5);

No exemplo acima, temos o padrão da string com mais de um token, com números de 0 à 2. A função também recebe 3 parâmetros adicionais que correspondem aos valores que serão substituídos na string. Além de informarmos os tokens, podemos informar regras de formatação que serão utilizadas de acordo com o tipo de dado passado por parâmetro, conforme o exemplo,

sTeste = String.Format("Custom Format: {0:d/M/yyy HH:mm:ss}", dtHoje);sTeste = String.Format("Formatação do número inteiro: {0:D}.", iNumero);sTeste = String.Format("Formatação do número inteiro: {0:D4}.", iNumero);

A classe StringBuilder

Apesar da versatilidade da classe string, operações com string podem consumir muitos recursos e causar perda de desempenho. Isto ocorre porque a cada operação o framework cria um novo buffer para a string resultante da operação, ao invés de aproveitar o buffer que está sendo utilizado. Isto é mais aparente em operações de concatenação.

Para não criar este tipo de problema, podemos utilizar a classe StringBuilder, do namespace System.Text. Esta classe permite a criação de strings aproveitando o buffer utilizado, o que torna o código mais eficiente.

No exemplo a seguir temos um trecho de código com uma operação feita de forma ineficiente e outra mais eficiente usando o stringBuilder, veja a diferença.

// Codigo ineficientestring sql;sql = "SELECT * FROM Products";sql += " WHERE CategoryId=1 AND";sql += " AND UnitPrice>10";

Page 4: String em C#

// Codigo EficienteStringBuilder sb = new StringBuilder();

sb.Append("SELECT * FROM Products");sb.Append(" WHERE CategoryId=1 AND");sb.Append(" AND UnitPrice>10");

sql = sb.ToString();

C# 2.0: Delegações e Métodos Anônimos

Para entender sobre métodos anônimos é necessário antes entender o que são delegates.

Entenda Delegates como uma anologia do C# aos "ponteiros de função" em C e Pascal.

Vamos a um exemplo do uso antigo :

Imagine que você tem um código que precisa criptografar informações, porém o modelo de criptografia pode variar. Assim, em C e Pascal, seria necessário fazer um "case" ou "switch" do modelo desejado e chamar a função correta, exemplo :

 string Criptografa(string str, int modelo){ switch (modelo) { case 0: return RSACripto(str); case 1: return AES128(str); default: return str; }}

Se você precisar adicionar um novo modelo de criptografia seria necessário alterar o código, além de que não é permitido uma criptografia customizada.

Bom, para resolver isso em C e Pascal criou-se o conceito de "ponteiro de função", ou seja, ao invés de receber como parâmetro um modelo de criptografia, receberia uma função como parâmetro obedecendo os parâmetros necessários a uma função de criptografia, assim sendo :

string Criptografa(str str, string (*modelo)(string) ){   (*modelo)(str);}

Lembre-se! Uma função é definida pela sua assinatura ( retorno, nome e parâmetros ), assim, só precisamos informar a assinatura do parâmetro.

Observe como agora a função Criptografa simplesmente passa os dados para o modelo desejado que será, também, passado como parâmetro.

Page 5: String em C#

Para termos este mesmo recurso e muito mais, o C# usa o conceito de Delegates, ou melhor, delegações, que continuam sendo "ponteiro de funções" mas agora no mundo gerenciado .NET.

Nosso exemplo acima em C# seria :

// declaração da assinatura da delegaçãopublic delegate string CriptHandler(string str);

E a mudança do método :

string Criptografa(string str, CriptHandler modelo){  modelo(str);}

 Observe que o método Criptografa requer como parâmetro um CriptHandler. Na realidade ele requer qualquer método com a mesma assinatura de CriptHandler,assim sendo, veja um exemplo completo :

// declaração da delegaçãopublic delegate string CriptHandler(string str);

void Main(string[] args){string criptRetorno = Criptografa("mutex", RSACripto);string criptRetorno2 = Criptografa("mutex", AES128);}

string RSACripto(string str){return str + "rsacript";}string AES128(string str){return str + "eascript";}string Criptografa(string str, CriptHandler modelo){return modelo(str);}

Observe como RSACripto e  AES128 tem a mesma assinatura de CriptHandler.

Bom, agora onde entra o recurso do C# 2.0 de Métodos Anônimos ?

É um recurso que permite a criação de um método sem nome. Simples e eficiente !

Veja o mesmo exemplo com métodos anônimos :

// declaração da delegaçãopublic delegate string CriptHandler(string str);

void Main(string[] args){

   CriptHandler rsaCripto = delegate(string str)   {

Page 6: String em C#

      return str + "rsacript";   };

   CriptHandler aes128 = delegate(string str)   {     return str + "eascript";   };

   string criptRetorno = Criptografa("mutex", rsaCripto);   string criptRetorno2 = Criptografa("mutex", aes128);}

string Criptografa(string str, CriptHandler modelo){ return modelo(str);}

Observe que declarei um método dentro de outro, algo não disponível no C# 1.0

ão utilizados em situações onde é necessário adicionar mais funcionalidades para uma classe. Em linguagens como Java, o programador é ainda é incapaz de mudar o comportamento de uma classe diretamente. Para fazer isso, ele teria as opções:

Herdar a classe e adicionar funcionalidade; Fazer uma classe nova separada, e adicionar um método estático que pega um

objeto do tipo da classe e retorna um novo objeto com a modificação desejada.

A primeira opção possui algumas limitações por desfrutar de herança e a segunda é menos intuitiva e requer uma referência para uma classe separada.

Bom, pense em uma situação onde se tenha a necessidade de extender a classe String de Java a fim de adicionar um novo método reverse que retorna o valor da string com os caracteres em ordem invertida. Comumente, este método poderia adicionado em uma classe utilitária. Observe o exemplo de implementação:

String x = "some string value"; String y = Utility.reverse(x);

Entretanto, é difícil de navegar em classes utilitárias e além disso, diferente dos métodos de String, isto não é um membro da classes String, é uma classe totalmente diferente. Uma melhor sintaxe pra isto seria:

String x = "some string value";String y = x.reverse();

A boa notícia para programadores C# é que uma das novas features da linguagem (especificação 3.0) é o método de extensão. Programadores Java terão que esperar um pouquinho (?) mais. Pra implementar a abordagem do exemplo anterior, em C#, teríamos:

public static class Util{ public static string Reverse(this string input) {

Page 7: String em C#

char[] chars = input.ToCharArray(); Array.Reverse(chars); return new String(chars); }}

A grande diferença entre os métodos de extensão e os métodos estáticos normais é que os métodos estáticos são chamados em notação pré-fixa, enquanto que os métodos de extensão são chamados em notação infixa. Exemplo:

Métodos de Extensão: x.doSomething1(arg1).doSomething2(arg2) Métodos estáticos: X.doSomething2(X.doSomething1(x, arg1), arg2)

Um método de extensão é uma forma de se alcançar algo como as classes abertas do Ruby. Seria um recurso interessante e facilitaria um tanto a adoção de novidades como closures e outras alterações propostas para Java 7.

Uma notícia esperançosa para programadores Java é que segundo Neal Gafter (um dos principais idealizadores de closures) em seu post “Closures Prototype Update and Extension Methods“ mencionou que os métodos de extensão são uma alteração proposta em Java 7 ! Olha o pequeno exemplo que ele deu de como a sintaxe vai funcionar:

Arrays jagged (Guide Programming C#)

A denteado matriz is an matriz whose Elementos are Arrays. The Elementos of a denteado matriz can be of different Dimensions and sizes. A denteado matriz is sometimes chamado AN "Matriz de Arrays". The seguinte apresentação Examples How to declare, inicializar, and denteado acessar Arrays.

The seguinte is a declaração of a matriz Simples-dimensional That Has three Elementos, each of which is a Simples-dimensional Matriz de integers:

C#

Copiar Código

[][] jaggedArray = [3][];

Before You can use jaggedArray, its Elementos must be initialized. You can inicializar the Elementos LIKE this:

C#

Copiar Código

jaggedArray[0] = [5];jaggedArray[1] = [4];jaggedArray[2] = [2];

Page 8: String em C#

Each of the Elementos is a Simples-dimensional Matriz de integers. The Primeiro elemento is an Matriz de 5 integers, the segundo is an Matriz de 4 integers, and the third is an Matriz de 2 integers.

It is also possible to use initializers to preencher the Elementos matriz com values, in which maiúscminúsc you do not need the tamanho matriz. Por exemplo:

C#

Copiar Código

jaggedArray[0] = [] { 1, 3, 5, 7, 9 };jaggedArray[1] = [] { 0, 2, 4, 6 };jaggedArray[2] = [] { 11, 22 };

You can also the matriz upon declaração LIKE this inicializar:

C#

Copiar Código

[][] jaggedArray2 = [][] { [] {1,3,5,7,9}, [] {0,2,4,6}, [] {11,22}};

You can use the seguinte Formulário shorthand. Notice that You Cannot omitir the operador new de the inicialização Elementos because there é não usar como padrão inicialização for the Elementos:

C#

Copiar Código

[][] jaggedArray3 = { [] {1,3,5,7,9}, [] {0,2,4,6}, [] {11,22}};

A denteado matriz is an Matriz de Arrays, and therefore its Elementos are Tipos Referência and are initialized to null.

You can individual acessar Elementos matriz LIKE these Exemplos:

C#

Copiar Código

Page 9: String em C#

jaggedArray3[0][1] = 77;

jaggedArray3[2][1] = 88;

It is possible to denteado mixar and multidimensional Arrays. The seguinte is a declaração and inicialização of a denteado Simples-dimensional matriz that contains Elementos matriz bidimensional of different sizes:

C#

Copiar Código

[][,] jaggedArray4 = [3][,] { [,] { {1,3}, {5,7} }, [,] { {0,2}, {4,6}, {8,10} }, [,] { {11,22}, {99,88}, {0,9} } };

You can individual acessar Elementos as shown in this exemplo, which displays the valor of the elemento [1,0] of the Primeiro matriz (valor 5):

C#

Copiar Código

System.Console.Write(, jaggedArray4[0][1, 0]);

The método Length returns the número of Arrays contained in the denteado matriz. For exemplo, assuming que You have Declared the Anterior matriz, this Linha:

C#

Copiar Código

System.Console.WriteLine(jaggedArray4.Length);

will Return a valor of 3.

Exemplo

This exemplo builds an matriz whose Elementos are Themselves Arrays. Each one of the Elementos matriz has a different tamanho.

C#

Copiar Código

ArrayTest

Page 10: String em C#

{ Main() { [][] arr = [2][];

arr[0] = [5] { 1, 3, 5, 7, 9 }; arr[1] = [4] { 2, 4, 6, 8 };

( i = 0; i < arr.Length; i++) { System.Console.Write(, i);

( j = 0; j < arr[i].Length; j++) { System.Console.Write(, arr[i][j], j == (arr[i].Length - 1) ? : ); } System.Console.WriteLine(); } }}

Saída

Element(0): 1 3 5 7 9

Element(1): 2 4 6 8