BestPractice - Transforme le premier caractère d'une chaîne en minuscules

136

J'aimerais avoir une méthode qui transforme le premier caractère d'une chaîne en minuscules.

Mes approches:

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

Quelle serait votre approche?

Recrue
la source

Réponses:

240

J'utiliserais une concaténation simple:

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

La première solution n'est pas optimisée car string.Format est lente et vous n'en avez pas besoin si vous avez un format qui ne changera jamais. Il génère également une chaîne supplémentaire pour convertir la lettre en minuscules, ce qui n'est pas nécessaire.

L'approche avec "+ 32" est moche / ne peut pas être maintenue car elle nécessite une connaissance des décalages de valeurs de caractères ASCII. Il générera également une sortie incorrecte avec des données Unicode et des caractères de symbole ASCII.

sur
la source
4
Je le ferais:char.ToLower(name[0]).ToString() + name.Substring(1)
Andrey
7
@Rookian: l' +opérateur est lent lorsque vous concaténez beaucoup de chaînes. Dans ce cas StringBuilder, les performances seraient bien meilleures. Cependant, +c'est beaucoup plus rapide que string.Format. Utilisez ce dernier lorsque vous avez réellement besoin de formater quelque chose (comme afficher des entiers, des doubles ou des dates).
Dirk Vollmar
6
@ 0x03: ce n'est lent que si vous concaténez de nombreuses chaînes de manière itérative. Si vous les concaténez tous en une seule opération, l' +opérateur n'est pas du tout lent, car le compilateur le transforme en un String.Concat(cependant String.Joinest plus rapide que String.Concatpour une raison idiote).
Thorarin
2
Une méthode plus rapide est la suivante: chaîne statique publique ToFirstLetterLower (chaîne de texte) {var charArray = text.ToCharArray (); charArray [0] = char.ToLower (charArray [0]); retourne une nouvelle chaîne (charArray); }
Matteo Migliore
2
J'ai utilisé l'extension 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); } basée sur le commentaire de @ MatteoMigliore.
KregHEk
64

Selon la situation, une petite programmation défensive pourrait être souhaitable:

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' ifinstruction empêche également une nouvelle chaîne d'être construite si elle ne va pas être modifiée de toute façon. Vous voudrez peut-être que la méthode échoue sur une entrée nulle à la place et lance un ArgumentNullException.

Comme les gens l'ont mentionné, utiliser String.Formatpour cela est excessif.

Thorarin
la source
Corrigez-moi si je me trompe mais str.Substring (1) renverra le symbole à la position 1 car le décompte de cette méthode n'est pas indiqué. donc vous aurez char [0] en minuscules + le char en position 1 J'ai donc préféré supprimer un caractère à partir du premier caractère de la chaîne. Le résultat est la chaîne sans première lettre. Ensuite, je vais ajouter cette chaîne au premier caractère qui est converti en minuscules
fedotoves
3
@ B-Rain: considérez-vous comme corrigé: msdn.microsoft.com/en-us/library/hxthx5h6%28VS.90%29.aspx
Thorarin
7

Juste au cas où cela aiderait quiconque tomberait sur cette réponse.

Je pense que ce serait mieux comme méthode d'extension, alors vous pouvez l'appeler avec 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
la source
3

Le mien est

if (!string.IsNullOrEmpty (val) && val.Length > 0)
{
    return val[0].ToString().ToLowerInvariant() + val.Remove (0,1);   
}
fedotoves
la source
3
Je suis curieux, pourquoi le val.Remove? Cela me semble un peu contre-intuitif.
Thorarin
@Thorarin évidemment parce que vous voulez supprimer le premier caractère (parce que vous ajoutez la version minuscule devant)
Riki
2

J'aime la réponse acceptée, mais à côté de la vérification, string.IsNullOrEmptyje vérifierais également si Char.IsLower(name[1])vous avez affaire à une abréviation. Par exemple, vous ne voudriez pas que le «sida» devienne «sida».

Slobodan Savkovic
la source
8
OMI , est de la responsabilité de l'appelant
OnOF
1

La solution la plus rapide que je connaisse sans abuser de 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
la source
0

Combiné quelques-uns et en a fait une extension chaînable. Ajout d'un court-circuit sur les espaces et les non-lettres.

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
la source
0

C'est une petite méthode d'extension utilisant la dernière syntaxe et les validations correctes

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
la source
1
Je ne sais pas si lever une exception serait la meilleure solution. Si la chaîne est nulle ou vide, renvoyez simplement la chaîne nulle ou vide.
R. de Veen
Si String est nul ou vide, l'opération n'a pas de sens car il n'y a pas de premier caractère à changer en minuscules.
Carlos Muñoz
0

Utilisez ceci:

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

Il est préférable d'utiliser String.Concatque String.Formatsi vous savez que le format n'est pas une modification des données et qu'une concaténation est souhaitée.

Konstantin Isaev
la source