Open
Description
Background and motivation
As we have started using the new TypeName
APIs all over the place, I've realized that it would be very nice to have the ability to create a new TypeName
instance with given AssemblyNameInfo
without the need of re-parsing the concatenated input again.
For example, in BinaryFormatter the type and library names are provided separately (#102014 (comment)), I would like to join them without re-parsing the whole thing again.
API Proposal
namespace System.Reflection.Metadata;
public sealed class TypeName
{
/// <summary>
/// Returns a <see cref="TypeName" /> object representing a one-dimensional array
/// of the current type, with a lower bound of zero.
/// </summary>
/// <returns>
public TypeName MakeArrayTypeName();
/// <summary>
/// Returns a <see cref="TypeName" /> object representing an array of the current type,
/// with the specified number of dimensions.
/// </summary>
/// <param name="rank">The number of dimensions for the array. This number must be more than zero and less than or equal to 32.</param>
/// <exception cref="ArgumentOutOfRangeException">rank is invalid. For example, 0 or negative.</exception>
public TypeName MakeArrayTypeName(int rank);
/// <summary>
/// Returns a <see cref="TypeName" /> object that represents a pointer to the current type.
/// </summary>
public TypeName MakePointerTypeName();
/// <summary>
/// Returns a <see cref="TypeName" /> object that represents a managed reference to the current type.
/// </summary>
public TypeName MakeByRefTypeName();
/// <summary>
/// Creates a new constructed generic type name.
/// </summary>
/// <param name="typeArguments">An array of type names to be used as generic arguments of the current simple type name.</param>
/// <exception cref="InvalidOperationException">The current type name is not simple.</exception>
public TypeName MakeGenericTypeName(ImmutableArray<TypeName> typeArguments)
/// <summary>
/// Returns a <see cref="TypeName" /> object that represents the current type name with provided assembly name.
/// </summary>
public TypeName WithAssemblyName(AssemblyNameInfo? assemblyName);
public static TypeName CreateSimpleTypeName(string fullName, TypeName? declaringType = null, AssemblyNameInfo? assemblyInfo = null);
}
API Usage
TypeName WithoutAssemblyVersion(TypeName typeName)
=> typeName.WithAssemblyName(
new AssemblyNameInfo(
typeName.AssemblyName.Name,
version: null,
typeName.AssemblyName.CultureName,
typeName.AssemblyName.Flags,
typeName.AssemblyName.PublicKeyOrToken));
Risks
Some users may miss the fact that the API creates a new instance of TypeName
rather than mutating the current instance.
Sample implementation with tests and usages in dotnet/runtime available at #103713