VSDiagnostics has an analyzer that verifies whether or not a given identifier is following naming conventions. The following conventions are supported:UpperCamelCaselowerCamelCase_lowerCamelCaseICamelCaseOn top of simply verifying this convention is followed it also suggests a new name that does follow conventions. The way I have implemented the verification is simple: simply generate a new identifier that follows conventions and check whether it's the same as the existing one.Now, the interesting work is done inside the generating of this new identifier of course.The approach I have thought out is the following:Any identifier is basically a group of 0, 1 or more sections. A section is denoted by special characters (anything that isn't a letter or a number) and capital letters that are preceded by a lower-case letter. For example in My_var, MyVar and MY_VAR all identifiers have two sections: My/var, My/Var and MY/VAR. Once everything is grouped in sections we have to apply the proper naming convention. This is now made easy because everything ends with '-CamelCase' meaning we only have to apply the naming convention to the first section and all the remaining ones can have the 'Upper' convention.Written in code that gives you the following implementation: Github/// <summary>///     Removes all non-digit, non-alphabetic characters. The naming convention of the first section can be specified, all///     others use <see cref=NamingConvention.UpperCamelCase />.///     For example:///     input = _allo_ello; first section = allo///     input = IBufferMyBuffer; first section = IBuffer///     input = MY_SNAKE_CASE; first section = MY///     This allows us to remove things like underscores and have the individual sections they denoted in a proper///     convention as well/// </summary>/// <param name=input></param>/// <param name=getFirstEntryConventioned></param>/// <returns></returns>internal static string GetNormalizedString(string input, Func<string, string> getFirstEntryConventioned){    var sections = new List<string>();    var tempBuffer = new StringBuilder();    Action addSection = () =>    {        if (tempBuffer.Length != 0)        {            sections.Add(tempBuffer.ToString());        }        tempBuffer.Clear();    };    var previousCharWasUpper = false;    for (var i = 0; i < input.Length; i++)    {        var currChar = input[i];        if (char.IsLetter(currChar) || char.IsNumber(currChar))        {            var isCurrentCharUpper = char.IsUpper(currChar);            if (isCurrentCharUpper && !previousCharWasUpper)            {                addSection();            }            previousCharWasUpper = isCurrentCharUpper;            tempBuffer.Append(currChar);        }        else        {            // We already have data to add            // Existing data gets added but the current character is being ignored            addSection();        }    }    // If there is stuff remaining in the buffer, flush it as the last section    addSection();    // Identifiers that consist solely of underscores, e.g. _____    if (sections.Count == 0)    {        return input;    }    var sb = new StringBuilder(getFirstEntryConventioned(sections[0]));    for (var i = 1; i < sections.Count; i++)    {        sb.Append(Upper(sections[i]));    }    return sb.ToString();}internal static string Upper(string input){    if (input.Length == 0)    {        return string.Empty;    }    return char.ToUpper(input[0]) + input.Substring(1).ToLowerInvariant();}internal static string Lower(string input){    if (input.Length == 0)    {        return string.Empty;    }    return input.ToLowerInvariant();}internal static string IUpper(string input){    if (input.Length == 0)    {        return string.Empty;    }    if (input.Length == 1)    {        if (string.Equals(I, input, StringComparison.OrdinalIgnoreCase))        {            return I;        }        return I + input.ToUpperInvariant();    }    if (input.StartsWith(I, StringComparison.OrdinalIgnoreCase))    {        return I + char.ToUpper(input[1]) + input.Substring(2).ToLowerInvariant();    }    return I + char.ToUpper(input[0]) + input.Substring(1).ToLowerInvariant();}internal static string UnderscoreLower(string input){    if (input.Length == 0)    {        return string.Empty;    }    return _ + Lower(input);}This has been tested here and hereApparently I have already asked about it. This is a rewrite of that implementation.
Applying naming conventions to any given identifier
c#