ILSpy
ILSpy copied to clipboard
ICSharpCode.Decompiler.TypeSystem.IType property values should match System.Reflection.Type property values
I'm viewing type information in two ways:
- Using
ITypefrom theICSharpCode.DecompilerAPIs - Using
TypefromMetaDataLoadContext.LoadFromAssemblyPath(path).GetTypes()
I notice the your IType API is very similar to the Type API but not identical.
And I don't know whether the difference is on purpose but it troubles me they're not quite interchangeable.
For reference, here's my record into which I load the property values:
public record TypeId(
string? AssemblyName,
string? Namespace,
string Name,
Values<TypeId>? GenericTypeArguments,
TypeId? DeclaringType
);
Here's my initializing that from a System.Reflection.Type instance
static TypeId GetTypeId(Type type)
{
TypeId[]? GetGenericTypeArguments()
{
var types = type.GenericTypeArguments;
return (types.Length == 0) ? null : types.Select(GetTypeId).ToArray();
}
return new TypeId(
AssemblyName: type.Assembly.GetName().Name,
Namespace: type.Namespace,
Name: type.Name,
GenericTypeArguments: GetGenericTypeArguments(),
DeclaringType: type.DeclaringType != null ? GetTypeId(type.DeclaringType) : null
);
}
Here's my initializing that from your IType instance
static TypeId Transform(this IType type)
{
var elementType = (type as TypeWithElementType)?.ElementType ?? type;
var nameSuffix = (type as TypeWithElementType)?.NameSuffix ?? string.Empty;
var assemblyName = elementType.GetDefinition()?.ParentModule?.AssemblyName;
// want a name like "KeyValuePair`2[]" (i.e. with generic arity appended) and not just "KeyValuePair[]"
var name = elementType.GetDefinition()?.MetadataName ?? type.Name;
// we have the name of the element not the type, so add the suffix
name += nameSuffix;
return new TypeId(
assemblyName,
type.Namespace == string.Empty ? null : type.Namespace,
name,
type.TypeArguments.Select(Transform).ToArrayOrNull(),
type.DeclaringType?.Transform()
);
}
In summary the differences I've found so far (after only one day of test-and-debugging) are as follows.
- The AssemblyName when the type is an array -- you correctly (i.e. same as
Type) display the name e.g.Foo[], and the namespace (ofFoo), but not the name of the assembly from which Foo is loaded -- so instead I must fetch that from your ElementType property. - The Namespace, when there isn't one -- you return an empty string,
Typereturns null. - Whether the name of the type is e.g.
KeyValuePairorKeyValuePair2`