Skip to content

Instantly share code, notes, and snippets.

@karenpayneoregon
Created May 17, 2024 13:49
Show Gist options
  • Save karenpayneoregon/12ded222c856e549f5df78388573908b to your computer and use it in GitHub Desktop.
Save karenpayneoregon/12ded222c856e549f5df78388573908b to your computer and use it in GitHub Desktop.
Lower case first character in a string
public static class StringExtensions
{
public static string? FirstCharacterToLowerCase(this string? sender)
{
if (!string.IsNullOrEmpty(sender) && char.IsUpper(sender[0]))
{
return sender.Length == 1 ?
char.ToLower(sender[0]).ToString() :
$"{char.ToLower(sender[0])}{sender[1..]}";
}
return sender;
}
}
@AndreaLanfranchi
Copy link

AndreaLanfranchi commented May 17, 2024

This code is unsafe as it can happen modified string shares the same reference as original string

Proof

using System.Diagnostics;
using System.Drawing;
using System.Numerics;
using System.Text.RegularExpressions;

public static class StringExtensions {
    public static string FirstCharacterToLowerCase(this string sender) {
        if (!string.IsNullOrEmpty(sender) && char.IsUpper(sender[0])) {
            return sender.Length == 1 ?
                char.ToLower(sender[0]).ToString() :
                $"{char.ToLower(sender[0])}{sender[1..]}";
        }
        return sender;
    }
}
partial class Program7 {

    unsafe static void InPlaceReplace(ref string? str, char newChar) {
        if (str == null) {
            return;
        }
        fixed (char* p = str) {
            for (int i = 0; i < str.Length; i++) {
                    p[i] = newChar;
            }
        }
    }


    static void Main() {

        string original = "hello";
        string modified = original.FirstCharacterToLowerCase();
        InPlaceReplace(ref modified, 'a');

        // Replace one char of modified
        Console.WriteLine(original);
    }
}

This will print out "aaaa" instead of "hello"
Obviously this is streched by the usage of unsafe code which breaks strings immutability in C# but you can understand the implications.

@AndreaLanfranchi
Copy link

AndreaLanfranchi commented May 17, 2024

This is safe instead

using System.Diagnostics;
using System.Drawing;
using System.Numerics;
using System.Text.RegularExpressions;

public static class StringExtensions {
    public static string? FirstCharacterToLowerCase(this string? input) {
        string? ret = null;
        if (input == null) {
            return ret;
        }
        ret = string.Empty;
        if (input.Length > 0) {
            var chars = input.ToCharArray();
            chars[0] = char.ToLower(chars[0]);
            ret = new string(chars);
        }
        return ret;
    }
}
partial class Program7 {

    unsafe static void InPlaceReplace(ref string? str, char newChar) {
        if (str == null) {
            return;
        }
        fixed (char* p = str) {
            for (int i = 0; i < str.Length; i++) {
                    p[i] = newChar;
            }
        }
    }

    static void Main() {

        string? original = "hello";
        string? modified = original.FirstCharacterToLowerCase();
        InPlaceReplace(ref modified, 'a');

        // Replace one char of modified
        Console.WriteLine(original);
    }
}

And orginal still prints out as "hello".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment