BestPractice: trasforma il primo carattere di una stringa in lettere minuscole


136

Mi piacerebbe avere un metodo che trasforma il primo carattere di una stringa in lettere minuscole.

I miei approcci:

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));
}

Quale sarebbe il tuo approccio?

Risposte:


240

Vorrei usare la concatenazione semplice:

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

La prima soluzione non è ottimizzata perché string.Formatè lenta e non è necessaria se si dispone di un formato che non cambierà mai. Genera anche una stringa aggiuntiva per convertire la lettera in minuscolo, che non è necessaria.

L'approccio con "+ 32" è brutto / non mantenibile in quanto richiede la conoscenza degli offset dei valori dei caratteri ASCII. Inoltre genererà un output errato con dati Unicode e caratteri simbolo ASCII.


4
lo farei:char.ToLower(name[0]).ToString() + name.Substring(1)
Andrey,

7
@Rookian: l' +operatore è lento quando si concatenano molte stringhe. In tal caso, un StringBuilderrendimento molto migliore. Tuttavia, +è molto più veloce di string.Format. Usa quest'ultimo quando hai effettivamente bisogno di formattare qualcosa (come visualizzare numeri interi, doppi o date).
Dirk Vollmar,

6
@ 0x03: è lento solo se stai concatenando molte stringhe in modo iterativo. Se li concateni tutti in una singola operazione, l' +operatore non è affatto lento, perché il compilatore lo trasforma in un String.Concat(tuttavia String.Joinè più veloce che String.Concatper qualche motivo sciocco).
Thorarin,

2
Un metodo più veloce è questo: stringa statica pubblica ToFirstLetterLower (string text) {var charArray = text.ToCharArray (); charArray [0] = char.ToLower (charArray [0]); restituisce una nuova stringa (charArray); }
Matteo Migliore,

2
Ho usato l'estensione 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); } Basato sul commento di @MatteMigliore.
KregHEk,

64

A seconda della situazione, potrebbe essere auspicabile una programmazione difensiva:

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

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

L' ifistruzione impedisce inoltre la creazione di una nuova stringa se non verrà comunque modificata. È possibile che si desideri che il metodo abbia esito negativo sull'input null e generare un ArgumentNullException.

Come è già stato detto, l'utilizzo String.Formatper questo è eccessivo.


Correggimi se sbaglio, ma str.Substring (1) restituirà il simbolo in posizione 1 poiché il conteggio per questo metodo non è indicato. quindi avrai carattere [0] in minuscolo + carattere in posizione 1 Quindi ho preferito rimuovere un carattere a partire dal primo carattere nella stringa. Il risultato è la stringa senza prima lettera. Quindi aggiungerò questa stringa al primo carattere che viene convertito in
lettere


7

Nel caso in cui aiuti qualcuno che si imbatte in questa risposta.

Penso che sarebbe meglio come metodo di estensione, quindi puoi chiamarlo con 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);
    }
}

3

Il mio è

if (!string.IsNullOrEmpty (val) && val.Length > 0)
{
    return val[0].ToString().ToLowerInvariant() + val.Remove (0,1);   
}

3
Sono curioso, perché il val.Remove? Mi sembra un po 'controintuitivo.
Thorarin,

@Thorarin ovviamente perché vuoi rimuovere il primo carattere (perché stai aggiungendo la versione minuscola di fronte)
Riki

2

Mi piace la risposta accettata, ma oltre al controllo string.IsNullOrEmptyvorrei anche verificare se Char.IsLower(name[1])nel caso si tratti di abbreviazioni. Ad esempio, non vorresti che "AIDS" diventasse "AIDS".


8
IMO questo è responsabilità del chiamante
onof

1

La soluzione più veloce che conosco senza abusare di 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;
}

0

Combinato alcuni e ha reso un'estensione concatenabile. Aggiunto corto circuito su spazi bianchi e non lettera.

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;

0

Questo è un piccolo metodo di estensione che utilizza la sintassi più recente e le convalide corrette

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);
        }
    }
}

1
Non sono sicuro se lanciare un'eccezione sarebbe la soluzione migliore. Se la stringa è nulla o vuota, basta restituire la stringa nulla o vuota.
R. de Veen,

Se String è nullo o vuoto, l'operazione non ha senso in quanto non esiste un primo carattere da modificare in minuscolo.
Carlos Muñoz,

0

Usa questo:

string newName= name[0].ToString().ToLower() + name.Substring(1);

-3

È meglio usarlo String.Concatche String.Formatse si sa che il formato non è un cambiamento di dati e si desidera solo la concatenazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.