# 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<System.Int32>.

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 = "<".PadRight(definedArguments.Length, ',') + ">"; return$"{type.Namespace}.{type.Name.Replace(genericIdentifier, genericBraces)}";
}

var formattedTypes = definedArguments.Select(definedArgument => definedArgument.FormatTypeName());

var newGenericArguments = $"<{string.Join(", ", formattedTypes)}>"; 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<,>) or all of the arguments are defined e.g typeof(Dictionary<int, int>).

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 <>. 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.

• Since FormatTypeName is an extension method I don't think that the parameter type can ever be null. Also, if you want more performance you can take a look at this answer for how to create strings of repeated characters. stackoverflow.com/a/720915/7412948 – Jeffrey Parks Oct 31 '19 at 19:42
• @JeffreyParks It can be null! :) – Denis Oct 31 '19 at 19:43
• Good to know! Also, if this proves to be too slow and you have a lot of repeated type usage, you could consider caching the results into a static Dictionary<type,string> so you avoid a lot of repeated work. – Jeffrey Parks Oct 31 '19 at 19:45
• @JeffreyParks an extension method is just syntax sugar for ExtClass.ExtMethod(obj), it's not a member call on obj ;-) – Mathieu Guindon Oct 31 '19 at 19:49

You can let CSharpCodeProvider format Type names:
public static string FormatTypeName(this Type type)
`