TypeNameFormatter.Sources 1.0.1

TypeNameFormatter provides some extension methods that can be used instead of Type.ToString() to format a type's name the way it would look in C#:

* StringBuilder.AppendFormattedName(Type, [TypeNameFormatOptions])
* Type.GetFormattedName([TypeNameFormatOptions])

See the README at the project's GitHub repository for usage instructions.

This package is a source code distribution of this library. It gets embedded into the referencing project and thus does not introduce an additional package reference for downstream consumers.

There is a newer version of this package available.
See the version list below for details.

Requires NuGet 2.8 or higher.

Install-Package TypeNameFormatter.Sources -Version 1.0.1
dotnet add package TypeNameFormatter.Sources --version 1.0.1
<PackageReference Include="TypeNameFormatter.Sources" Version="1.0.1">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add TypeNameFormatter.Sources --version 1.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

TypeNameFormatter is a small .NET library for formatting type names à la C#.

What is this good for?

Have you ever stumbled over the cryptic formatting of Type objects?

var someType = typeof(IEnumerable<int[]>);

Console.WriteLine(someType);
// => System.Collections.Generic.IEnumerable`1[System.Int32[]]

If you'd rather see something that looks more like a C# type name, then this library might be for you:

using TypeNameFormatter;

var someType = typeof(IEnumerable<int[]>);

Console.WriteLine(someType.GetFormattedName());
// => IEnumerable<int[]>

Formatting any Type involves more special cases than you might expect (such as generic types, nested types, multi-dimensional and jagged arrays, by-reference and pointer types). This library deals with all of those, so that you don't have to.

How do I use it?

By importing the TypeNameFormatter namespace, the following extension methods become available:

  • stringBuilder.AppendFormattedName(Type type, [TypeNameFormatOptions options]):
    Appends a C#-formatted type name to the given StringBuilder.

  • type.GetFormattedName([TypeNameFormatOptions options]):
    Returns a C#-formatted type name as a string. (This is a convenience method that does exactly the same as the above, using a throw-away StringBuilder.)

Both methods allow you to specify any combination of the following TypeNameFormatOptions flags:

  • Namespaces:
    Namespaces should be included. (For example, System.Action instead of Action.)

  • NoAnonymousTypes:
    Anonymous types should not have their "display class" name transformed to a more legible syntax. (For example, ˂˃f__AnonymousType5˂string, int˃ instead of {string Name, int Count}.)

  • NoGenericParameterNames:
    Parameter names of an open generic type should be omitted. (For example, IEnumerable˂˃ instead of IEnumerable˂T˃. Note that this setting does not affect closed generic types; their arguments are always included.)

  • NoKeywords:
    Primitive types should not be mapped to their corresponding C# language keywords. (For example, Int32 instead of int.)

  • NoNullableQuestionMark:
    Nullable types should not be formatted using C# question mark syntax. (For example, Nullable˂int˃ instead of int?.)

  • NoTuple:
    Value tuple types should not be formatted using C# tuple syntax. (For example, ValueTuple˂bool, int˃ instead of (bool, int).)

But it doesn't format ˂some type˃ correctly!

If you think you've found a bug, please raise an issue so it can be looked into. (Make sure to mention the type that doesn't get formatted as expected.)

Alternatives

  • If you're targeting the .NET Framework, you can use good old System.CodeDom (which isn't particularly fast, however):

    using Microsoft.CSharp;
    using System.CodeDom;
    
    static string GetFormattedName(this Type type)
    {
        using (var provider = new CSharpCodeProvider())
        {
            var typeReference = new CodeTypeReference(type);
            return provider.GetTypeOutput(typeReference);
        }
    }
    
  • You could perhaps use Microsoft's .NET Compiler Platform (Roslyn), but that is a large library that can do much more than is needed.

TypeNameFormatter is a small .NET library for formatting type names à la C#.

What is this good for?

Have you ever stumbled over the cryptic formatting of Type objects?

var someType = typeof(IEnumerable<int[]>);

Console.WriteLine(someType);
// => System.Collections.Generic.IEnumerable`1[System.Int32[]]

If you'd rather see something that looks more like a C# type name, then this library might be for you:

using TypeNameFormatter;

var someType = typeof(IEnumerable<int[]>);

Console.WriteLine(someType.GetFormattedName());
// => IEnumerable<int[]>

Formatting any Type involves more special cases than you might expect (such as generic types, nested types, multi-dimensional and jagged arrays, by-reference and pointer types). This library deals with all of those, so that you don't have to.

How do I use it?

By importing the TypeNameFormatter namespace, the following extension methods become available:

  • stringBuilder.AppendFormattedName(Type type, [TypeNameFormatOptions options]):
    Appends a C#-formatted type name to the given StringBuilder.

  • type.GetFormattedName([TypeNameFormatOptions options]):
    Returns a C#-formatted type name as a string. (This is a convenience method that does exactly the same as the above, using a throw-away StringBuilder.)

Both methods allow you to specify any combination of the following TypeNameFormatOptions flags:

  • Namespaces:
    Namespaces should be included. (For example, System.Action instead of Action.)

  • NoAnonymousTypes:
    Anonymous types should not have their "display class" name transformed to a more legible syntax. (For example, ˂˃f__AnonymousType5˂string, int˃ instead of {string Name, int Count}.)

  • NoGenericParameterNames:
    Parameter names of an open generic type should be omitted. (For example, IEnumerable˂˃ instead of IEnumerable˂T˃. Note that this setting does not affect closed generic types; their arguments are always included.)

  • NoKeywords:
    Primitive types should not be mapped to their corresponding C# language keywords. (For example, Int32 instead of int.)

  • NoNullableQuestionMark:
    Nullable types should not be formatted using C# question mark syntax. (For example, Nullable˂int˃ instead of int?.)

  • NoTuple:
    Value tuple types should not be formatted using C# tuple syntax. (For example, ValueTuple˂bool, int˃ instead of (bool, int).)

But it doesn't format ˂some type˃ correctly!

If you think you've found a bug, please raise an issue so it can be looked into. (Make sure to mention the type that doesn't get formatted as expected.)

Alternatives

  • If you're targeting the .NET Framework, you can use good old System.CodeDom (which isn't particularly fast, however):

    using Microsoft.CSharp;
    using System.CodeDom;
    
    static string GetFormattedName(this Type type)
    {
        using (var provider = new CSharpCodeProvider())
        {
            var typeReference = new CodeTypeReference(type);
            return provider.GetTypeOutput(typeReference);
        }
    }
    
  • You could perhaps use Microsoft's .NET Compiler Platform (Roslyn), but that is a large library that can do much more than is needed.

Release Notes

A changelog is available at https://github.com/stakx/TypeNameFormatter/blob/master/CHANGELOG.md.

Dependencies

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on TypeNameFormatter.Sources:

Repository Stars
moq/moq4
Repo for managing Moq 4.x
moq/moq
The most popular and friendly mocking framework for .NET

Version History

Version Downloads Last updated
1.1.0 17 11/12/2020
1.0.1 2,995 12/30/2018
1.0.0 2,880 7/11/2018
1.0.0-beta3 311 6/7/2018
1.0.0-beta 340 5/24/2018
1.0.0-alpha 407 5/24/2018