BestPractice - Transforme o primeiro caractere de uma string em minúsculas

136

Eu gostaria de ter um método que transforma o primeiro caractere de uma string em minúsculas.

Minhas abordagens:

1

public static string ReplaceFirstCharacterToLowerVariant(string name)
{
    return String.Format("{0}{1}", name.First().ToString().ToLowerInvariant(), name.Substring(1));
}

2)

public static IEnumerable<char> FirstLetterToLowerCase(string value)
{
    var firstChar = (byte)value.First();
    return string.Format("{0}{1}", (char)(firstChar + 32), value.Substring(1));
}

Qual seria sua abordagem?

Rookian
fonte

Respostas:

240

Eu usaria concatenação simples:

Char.ToLowerInvariant(name[0]) + name.Substring(1)

A primeira solução não é otimizada porque string.Formaté lenta e você não precisa se tiver um formato que nunca será alterado. Ele também gera uma sequência extra para converter a letra em minúscula, o que não é necessário.

A abordagem com "+ 32" é feia / não pode ser mantida, pois requer conhecimento de compensações de valor de caracteres ASCII. Também irá gerar uma saída incorreta com dados Unicode e caracteres de símbolo ASCII.

ligado desligado
fonte
4
eu faria:char.ToLower(name[0]).ToString() + name.Substring(1)
Andrey
7
@Rookian: o +operador é lento quando você está concatenando muitas strings. Nesse caso, a StringBuilderteria um desempenho muito melhor. No entanto, +é muito mais rápido que string.Format. Use o último quando você realmente precisar formatar algo (como exibir números inteiros, duplos ou datas).
Dirk Vollmar
6
@ 0x03: só é lento se você concatenar muitas seqüências iterativamente. Se você concatená-los todos em uma única operação, o +operador não fica lento, porque o compilador o transforma em um String.Concat(no entanto, String.Joiné mais rápido do que String.Concatpor algum motivo bobo).
Thorarin
2
Um método mais rápido é este: string estática pública ToFirstLetterLower (texto da string) {var charArray = text.ToCharArray (); charArray [0] = char.ToLower (charArray [0]); retornar nova string (charArray); }
Matteo Migliore
2
Eu usei a extensão public static string ToLowerFirst(this string source) { if (string.IsNullOrWhiteSpace(source)) return source; var charArray = source.ToCharArray(); charArray[0] = char.ToLower(charArray[0]); return new string(charArray); } Baseada no comentário de @ MatteoMigliore.
precisa saber é o seguinte
64

Dependendo da situação, um pouco de programação defensiva pode ser desejável:

public static string FirstCharacterToLower(string str)
{
    if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        return str;

    return Char.ToLowerInvariant(str[0]) + str.Substring(1);
}

A ifinstrução também evita que uma nova string seja criada se não for alterada. Você pode querer que o método falhe na entrada nula e ative um ArgumentNullException.

Como as pessoas mencionaram, usar String.Formatpara isso é um exagero.

Thorarin
fonte
Corrija-me se estiver errado, mas str.Substring (1) retornará o símbolo na posição 1, pois a contagem desse método não é indicada. então você terá char [0] em letras minúsculas + o char na posição 1. Então, eu preferi remover um char começando no primeiro char na string. O resultado é a sequência sem primeira letra. Então eu adicionarei essa string ao primeiro caractere que é convertido em minúsculas
fedotoves
3
@ B-Rain: considere-se corrigido: msdn.microsoft.com/en-us/library/hxthx5h6%28VS.90%29.aspx
Thorarin
7

Apenas no caso de ajudar alguém que tropeçar nessa resposta.

Eu acho que isso seria melhor como um método de extensão, então você pode chamá-lo com yourString.FirstCharacterToLower ();

public static class StringExtensions
{
    public static string FirstCharacterToLower(this string str)
    {
        if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        {
            return str;
        }

        return Char.ToLowerInvariant(str[0]) + str.Substring(1);
    }
}
carlcheel
fonte
3

O meu é

if (!string.IsNullOrEmpty (val) && val.Length > 0)
{
    return val[0].ToString().ToLowerInvariant() + val.Remove (0,1);   
}
fedotoves
fonte
3
Estou curioso, por que o val.Remove? Parece um pouco contra-intuitivo para mim.
Thorarin 25/08/10
@Thorarin, obviamente, porque você quer remover o primeiro char (porque você está adicionando a versão minúscula na frente)
Riki
2

Eu gosto da resposta aceita, mas, além de marcar string.IsNullOrEmpty, também verificaria se Char.IsLower(name[1])você está lidando com abreviação. Por exemplo, você não gostaria que "AIDS" se tornasse "AIDS".

Slobodan Savkovic
fonte
8
OMI é responsabilidade do
autor
1

A solução mais rápida que conheço sem abusar do c #:

public static string LowerCaseFirstLetter(string value)
{
    if (value?.Length > 0)
    {
        var letters = value.ToCharArray();
        letters[0] = char.ToLowerInvariant(letters[0]);
        return new string(letters);
    }
    return value;
}
Rjz
fonte
0

Combinou alguns e tornou uma extensão encadeada. Adicionado curto-circuito em espaço em branco e sem letra.

public static string FirstLower(this string input) => 
    (!string.IsNullOrWhiteSpace(input) && input.Length > 0 
        && char.IsLetter(input[0]) && !char.IsLower(input[0]))
    ? input[0].ToString().ToLowerInvariant() + input.Remove(0, 1) : input;
Randy Buchholz
fonte
0

Este é um pequeno método de extensão usando a sintaxe mais recente e as validações corretas

public static class StringExtensions
{
    public static string FirstCharToLower(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input.First().ToString().ToLower() + input.Substring(1);
        }
    }
}
Carlos Muñoz
fonte
1
Não tenho certeza se lançar uma exceção seria a melhor solução. Se a sequência for nula ou vazia, basta retornar a sequência nula ou vazia.
R. de Veen 28/09
Se String for nulo ou vazio, a operação não fará sentido, pois não há primeiro caractere a ser alterado para minúsculo.
Carlos Muñoz
0

Usa isto:

string newName= name[0].ToString().ToLower() + name.Substring(1);
hojjat.mi
fonte
-3

É melhor usar do String.Concatque String.Formatse você souber que o formato não é alterar dados e se deseja apenas concatenação.

Konstantin Isaev
fonte