Formatting a type's name I'm writing a code generation library, I've exposed a couple of methods and of course in order to define a member you need to specify it's type, the easiest way is to use typeof(Type), which I later format so that it it's compilable and I can insert it as a code chunk e.g. System.Int32, which for non-generic types is basically concatenating the namespace and the type's name. 

That works fine but generic types have the backtick followed by the number of arguments, so I needed a method to format all the types, so that they are always compilable e.g. System.Collection.Generics.List&lt;System.Int32&gt;. 

public static class TypeExtensions
{
    public static string FormatTypeName(this Type type)
    {
        if(type == null) { throw new ArgumentNullException(nameof(type)); }

        if (type.IsGenericType)
        {
            var definedArguments = type.GetGenericArguments();
            var genericIdentifier = $"`{definedArguments.Length}";

            if (definedArguments.First().FullName == null)
            {
                var genericBraces = "&lt;".PadRight(definedArguments.Length, ',') + "&gt;";
                return $"{type.Namespace}.{type.Name.Replace(genericIdentifier, genericBraces)}";
            }

            var formattedTypes = definedArguments.Select(definedArgument =&gt; definedArgument.FormatTypeName());

            var newGenericArguments = $"&lt;{string.Join(", ", formattedTypes)}&gt;";
            return $"{type.Namespace}.{type.Name.Replace(genericIdentifier, newGenericArguments, StringComparison.InvariantCultureIgnoreCase)}";
        }

        return $"{type.Namespace}.{type.Name}";
    }
}


It supports indefinite amount of nested and linear generic arguments due to the recursion that is in-place. 



The way it works is pretty straight forward, there are 2 possible incomes, we have no arguments defined e.g. typeof(Dictionary&lt;,&gt;) or all of the arguments are defined e.g typeof(Dictionary&lt;int, int&gt;).

Since the C# compiler doesn't allow partially defined arguments we can simply check if the first of the arguments has a FullName (note that Name is the name pf the generic argument not the type behind it), if it does we simply concatenate all of the arguments and surround them by &lt;&gt;. if the first argument doesn't have value then it's empty and we just leave the braces with commas separating the arguments.



Since this will be used in a code generation tool, performance is not crucial, but always welcome as long as it doesn't damage the readability and maintainability of the code, which I consider more important in this case. 

However since it will be used in a code generation tool, I'm more worried about whether I've missed some edge cases.
You can let CSharpCodeProvider format Type names:

public static string FormatTypeName(this Type type)
{
    using (var c = new CSharpCodeProvider()) {
        var r = new CodeTypeReference(type);
        return c.GetTypeOutput(r);
    }
}