Type Name or Alias via Reflection for TT Code Generation I was working on some TT code generation to get rid of mundane C# codings in VS2013 Express Edition, and after researching online, created the following helper methods to facilitate Type declarations.

I am able to use it successfully in my code generation but wonder if they can be improved further or if there's any scenario which they do not cater for.

public static String GetActualTypeName(Type type, bool bAlias = true, bool bFullQualified = false)
{
    Type nullable = Nullable.GetUnderlyingType(type);
    String name = null;

    if (nullable != null) // handles Nullable types
    {
        name = (bAlias) ? GetAliasName(nullable, bFullQualified)
            : (bFullQualified) ? nullable.FullName : nullable.Name;

        return String.Format("{0}?", name);
    }

    if (!type.GenericTypeArguments.Any()) // handles non generic types
    {
        name = (bAlias) ? GetAliasName(type, bFullQualified)
            : (bFullQualified) ? type.FullName : type.Name;

        return name;
    }

    name = (bFullQualified) ? type.FullName : type.Name;

    // recrusive looping into generic type tree for the required type names 
    String[] names = type.GenericTypeArguments
        .Select(t =&gt; GetActualTypeName(t, bAlias, bFullQualified))
        .ToArray();         

    return String.Format("{0}&lt;{1}&gt;", name.Substring(0, name.IndexOf('`')), String.Join(",", names));
}

public static String GetAliasName(Type type, bool bFullQualified = false)
{
    String alias = null;

    using (var provider = new Microsoft.CSharp.CSharpCodeProvider())
    {
        var typeRef = new System.CodeDom.CodeTypeReference(type);

        alias = provider.GetTypeOutput(typeRef);
    }

    int index = alias.LastIndexOf(".");

    if (bFullQualified || index == -1)
        return alias;

    return alias.Substring(index + 1);
}
bool bAlias


Don't use Hungarian notation on names. When you look at the parameter, you can already see that it's a bool, there is no reason to repeat that in the name.



String name = null;


Since it seems you never want to use that null value, don't initialize the variable at all.

Also, it's more common to write string instead of String.



name = (bAlias) ? GetAliasName(nullable, bFullQualified)
    : (bFullQualified) ? nullable.FullName : nullable.Name;


What's the point of the parentheses around bAlias and bFullQualified. They don't seem to serve any purpose.



String[] names = type.GenericTypeArguments
    .Select(t =&gt; GetActualTypeName(t, bAlias, bFullQualified))
    .ToArray();    


I think names is too general here. I think something like typeArgumentNames would be better here (even if it's significantly longer).

Also, String.Join() can accept IEnumerable&lt;string&gt;, so the ToArray() is unnecessary here.



name.Substring(0, name.IndexOf('`'))


Wouldn't this be more readable as name.Split('`')[0]? (It would also be less efficient, but that might not matter to you.)



String.Join(",", names)


I realize this is for generated code, so beauty does not matter much, but I would still prefer to add a space between the type arguments, i.e. String.Join(", ", names).



using (var provider = new Microsoft.CSharp.CSharpCodeProvider())


Neither CSharpCodeProvider not its base class, CodeDomProvider override Dispose(), it's only there because they inherit from Component. 

This means that there is no need to use using here. But even if you know this, you might still choose to include the using, just to be on the safe side.

Also, since you're already using CSharpCodeProvider for this, why not use it to replace your whole GetActualTypeName()? You would lose the choice of specifying the form of the output, but it might be worth it for so much simplification.