BestPractice - преобразовать первый символ строки в нижний регистр

136

Я хотел бы иметь метод, который преобразует первый символ строки в нижний регистр.

Мои подходы:

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

Каков будет ваш подход?

Rookian
источник

Ответы:

240

Я бы использовал простую конкатенацию:

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

Первое решение не оптимизировано, потому что string.Formatоно медленное, и оно вам не нужно, если у вас есть формат, который никогда не изменится. Он также генерирует дополнительную строку для преобразования буквы в нижний регистр, которая не нужна.

Подход с «+ 32» является уродливым / не обслуживаемым, поскольку требует знания смещений значений символов ASCII. Он также будет генерировать неправильный вывод с данными Unicode и символьными символами ASCII.

onof
источник
4
я бы сделал это:char.ToLower(name[0]).ToString() + name.Substring(1)
Андрей
7
@Rookian: +оператор работает медленно, когда вы объединяете много строк. В этом случае он StringBuilderбудет работать намного лучше. Тем не менее, +это гораздо быстрее, чем string.Format. Используйте последнее, когда вам действительно нужно что-то отформатировать (например, отображать целые числа, двойные числа или даты).
Дирк Воллмар
6
@ 0x03: это только медленно, если вы объединяете много строк итеративно. Если вы объединяете их все в одну операцию, +оператор вообще не работает медленно, потому что компилятор превращает его в String.Concat(но String.Joinэто быстрее, чем String.Concatпо какой-то глупой причине).
Торарин
2
Более быстрый метод: публичная статическая строка ToFirstLetterLower (текст строки) {var charArray = text.ToCharArray (); charArray [0] = char.ToLower (charArray [0]); вернуть новую строку (charArray); }
Маттео Мильоре
2
Я использовал расширение 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); } на основе комментария @ MatteoMigliore.
KregHEk
64

В зависимости от ситуации может потребоваться небольшое защитное программирование:

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

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

Этот ifоператор также предотвращает создание новой строки, если она все равно не будет изменена. Возможно, вы захотите, чтобы метод потерпел неудачу на нулевом вводе, и бросил ArgumentNullException.

Как уже упоминалось, использование String.Formatдля этого является излишним.

Торарин
источник
Поправьте меня, если я ошибаюсь, но str.Substring (1) вернет символ в позиции 1, так как счетчик для этого метода не указан. поэтому у вас будет символ [0] в нижнем регистре + символ в позиции 1. Поэтому я предпочел удалить один символ, начиная с первого символа в строке. Результатом является строка без первой буквы. Затем я добавлю эту строку в первый символ, который преобразуется в нижний регистр
fedotoves
3
@ B-Rain: считать себя исправил: msdn.microsoft.com/en-us/library/hxthx5h6%28VS.90%29.aspx
Торарин
7

На всякий случай это поможет любому, кто случайно наткнется на этот ответ.

Я думаю, что это будет лучше в качестве метода расширения, тогда вы можете вызвать его с помощью 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
источник
3

Мой

if (!string.IsNullOrEmpty (val) && val.Length > 0)
{
    return val[0].ToString().ToLowerInvariant() + val.Remove (0,1);   
}
fedotoves
источник
3
Мне любопытно, почему val.Remove? Кажется, немного нелогичным для меня.
Торарин
@Thorarin, очевидно, потому что вы хотите удалить первый символ (потому что вы добавляете
Riki
2

Мне нравится принятый ответ, но помимо проверки string.IsNullOrEmptyя бы также проверил, если Char.IsLower(name[1])вы имеете дело с сокращением. Например, вы не хотели бы, чтобы «СПИД» стал «СПИДом».

Слободан Савкович
источник
8
ИМО это ответственность вызывающего
onof
1

Самое быстрое решение, которое я знаю, не злоупотребляя 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
источник
0

Объединили несколько и сделали его цепным расширением. Добавлено короткое замыкание на пробел и не букву.

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

Это небольшой метод расширения, использующий последний синтаксис и правильные проверки

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
Не уверен, что выбрасывание исключения будет лучшим решением. Если строка пуста или пуста, просто верните пустую или пустую строку.
Р. де Вин,
Если String равен нулю или пуст, операция не имеет смысла, так как нет первого символа, который можно изменить на строчные.
Карлос Муньос,
0

Использовать это:

string newName= name[0].ToString().ToLower() + name.Substring(1);
hojjat.mi
источник
-3

Лучше использовать, String.Concatчем String.Formatесли вы знаете, что формат не изменяет данные, а просто объединение желательно.

Константин Исаев
источник