Porticle.Reflection.Extensions 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Porticle.Reflection.Extensions --version 0.1.0
                    
NuGet\Install-Package Porticle.Reflection.Extensions -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Porticle.Reflection.Extensions" Version="0.1.0">
  <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.
<PackageVersion Include="Porticle.Reflection.Extensions" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Porticle.Reflection.Extensions">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Porticle.Reflection.Extensions --version 0.1.0
                    
#r "nuget: Porticle.Reflection.Extensions, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Porticle.Reflection.Extensions@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Porticle.Reflection.Extensions&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Porticle.Reflection.Extensions&version=0.1.0
                    
Install as a Cake Tool

Porticle.Reflection.Extensions

Overview

A .NET library that provides extension methods for converting .NET reflection types into human-readable type strings. This library handles complex scenarios including nullable reference types, nullable value types, generic types, arrays, and C# type aliases, making reflection output easier to read and understand.

Key Features

The library automatically converts reflection types to readable strings:

  • Nullable reference types (string?, List<string>?)
  • Nullable value types (int?, DateTime?)
  • Generic types with proper formatting (List<T>, Dictionary<TKey, TValue>)
  • Arrays (single-dimensional [], jagged [][], and multi-dimensional [,])
  • C# type aliases (int, string, bool instead of Int32, String, Boolean)
  • Event handlers (EventHandler<T>, Action<T>, Func<T>)
  • Nested generic types (List<List<string?>>?)

Installation

Install via NuGet:

dotnet add package Porticle.Reflection.Extensions

Or via Package Manager Console:

Install-Package Porticle.Reflection.Extensions

Usage

Basic Type Conversion

using Porticle.Reflection.Extensions;

// Simple types
Type intType = typeof(int);
Console.WriteLine(intType.ToReadableTypeString()); // Output: int

Type stringType = typeof(string);
Console.WriteLine(stringType.ToReadableTypeString()); // Output: string

// Nullable value types
Type nullableInt = typeof(int?);
Console.WriteLine(nullableInt.ToReadableTypeString()); // Output: int?

// Generic types
Type listType = typeof(List<string>);
Console.WriteLine(listType.ToReadableTypeString()); // Output: List<string>

Type dictType = typeof(Dictionary<int, string>);
Console.WriteLine(dictType.ToReadableTypeString()); // Output: Dictionary<int, string>

Working with Properties (Nullable Reference Types)

public class User
{
    public string Name { get; set; } = "";
    public string? Email { get; set; }
    public List<string>? Tags { get; set; }
    public List<string?> Nicknames { get; set; } = new();
}

// Using PropertyInfo to get nullable reference type information
PropertyInfo nameProperty = typeof(User).GetProperty("Name")!;
Console.WriteLine(nameProperty.ToReadableTypeString()); // Output: string

PropertyInfo emailProperty = typeof(User).GetProperty("Email")!;
Console.WriteLine(emailProperty.ToReadableTypeString()); // Output: string?

PropertyInfo tagsProperty = typeof(User).GetProperty("Tags")!;
Console.WriteLine(tagsProperty.ToReadableTypeString()); // Output: List<string>?

PropertyInfo nicknamesProperty = typeof(User).GetProperty("Nicknames")!;
Console.WriteLine(nicknamesProperty.ToReadableTypeString()); // Output: List<string?>

Working with Method Parameters

public class DataService
{
    public void ProcessData(
        List<string> requiredItems,
        List<string>? optionalItems,
        List<string?> itemsWithNullableElements)
    {
    }
}

MethodInfo method = typeof(DataService).GetMethod("ProcessData")!;
ParameterInfo[] parameters = method.GetParameters();

Console.WriteLine(parameters[0].ToReadableTypeString()); // Output: List<string>
Console.WriteLine(parameters[1].ToReadableTypeString()); // Output: List<string>?
Console.WriteLine(parameters[2].ToReadableTypeString()); // Output: List<string?>

Working with Fields and Events

public class EventDemo
{
    public List<string>? Items;
    public event EventHandler<string>? DataReceived;
}

// Fields
FieldInfo field = typeof(EventDemo).GetField("Items")!;
Console.WriteLine(field.ToReadableTypeString()); // Output: List<string>?

// Events
EventInfo evt = typeof(EventDemo).GetEvent("DataReceived")!;
Console.WriteLine(evt.ToReadableTypeString()); // Output: EventHandler<string>?

Advanced Features

Full Type Names

Use useFullNames: true to include full namespaces:

Type listType = typeof(List<string>);
Console.WriteLine(listType.ToReadableTypeString(useFullNames: true));
// Output: System.Collections.Generic.List<System.String>

Native .NET Type Names

Use useInternalTypeNames: false to get .NET type names instead of C# aliases:

Type intType = typeof(int);
Console.WriteLine(intType.ToReadableTypeString(useInternalTypeNames: false));
// Output: Int32

Type stringType = typeof(string);
Console.WriteLine(stringType.ToReadableTypeString(useInternalTypeNames: false));
// Output: String

Arrays

// Single-dimensional array
Type intArray = typeof(int[]);
Console.WriteLine(intArray.ToReadableTypeString()); // Output: int[]

// Jagged array
Type jaggedArray = typeof(int[][]);
Console.WriteLine(jaggedArray.ToReadableTypeString()); // Output: int[][]

// Multi-dimensional array
Type multiArray = typeof(int[,]);
Console.WriteLine(multiArray.ToReadableTypeString()); // Output: int[,]

Limitations

Type Erasure

Due to .NET's type erasure for nullable reference types, typeof() cannot preserve nullability information for generic type arguments:

// ❌ This will NOT show the nullable string
Type listType = typeof(List<string?>);
Console.WriteLine(listType.ToReadableTypeString()); // Output: List<string> (nullability lost)

// ✅ Use PropertyInfo, ParameterInfo, FieldInfo, or EventInfo instead
public class Example
{
    public List<string?> Items { get; set; } = new();
}

PropertyInfo property = typeof(Example).GetProperty("Items")!;
Console.WriteLine(property.ToReadableTypeString()); // Output: List<string?> (correct)

Note: Nullable value types (like List<int?>) work correctly with typeof() because Nullable<T> is a real runtime type.

Target Frameworks

  • .NET 10.0
  • .NET 9.0
  • .NET 8.0

License

MIT

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 2,304 1/12/2026
1.0.0-beta4 97 1/12/2026
0.1.1 96 1/12/2026
0.1.0 135 1/12/2026
0.0.6 137 1/12/2026