I am trying to generate a human readable string for e.g. ICollection<string>
or any other generic ICollection<> / IList<> / IEnumerable<>
In order to do this I use amongst others the following routine:
public static string HumanReadableTypeName(this Type aType)
{
if (aType == null)
throw new ArgumentNullException($"{nameof(ReflectionExtensions)}.{nameof(HumanReadableTypeName)}");
var lBaseType = Nullable.GetUnderlyingType(aType);
if (lBaseType != null)
return cNullableHdr + HumanReadableTypeName(lBaseType);
if (aType == typeof(string))
return aType.Name;
if (aType.IsArray)
{
var elementTypeName = HumanReadableTypeName(aType.GetElementType());
var lBuilder = new StringBuilder(elementTypeName);
for (var i = 0; i < aType.GetArrayRank(); i++) // add brackets for each dimension
lBuilder.Append("[]");
return lBuilder.ToString();
}
var listtype = aType.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)).FirstOrDefault();
if (listtype != null)
{
var itemType = listtype.GetGenericArguments().Single();
var itemTypeName = HumanReadableTypeName(itemType);
return $"IList<{itemTypeName}>";
}
var collectiontype = aType.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICollection<>)).FirstOrDefault();
if (collectiontype != null)
{
var itemType = collectiontype.GetGenericArguments().Single();
var itemTypeName = HumanReadableTypeName(itemType);
return $"ICollection<{itemTypeName}>";
}
var enumerabletype = aType.GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>)).FirstOrDefault();
if (enumerabletype != null)
{
var itemType = enumerabletype.GetGenericArguments().Single();
var itemTypeName = HumanReadableTypeName(itemType);
return $"IEnumerable<{itemTypeName}>";
}
return aType.Name;
}
Trouble is that when I pass typeof(ICollection<string>)
as an argument I get IEnumerable<string>
as an answer.
In the debugger I entered:
typeof(ICollection<string>).GetInterfaces()
with as result a collection of just 2 elements:
+ [0] {Name = "IEnumerable`1" FullName = "System.Collections.Generic.IEnumerable`1[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]"} System.Type {System.RuntimeType}
+ [1] {Name = "IEnumerable" FullName = "System.Collections.IEnumerable"} System.Type {System.RuntimeType}
So it seems the ICollection<>
interface isn't listed!
What confuses me also is that the following statement:
typeof(ICollection<string>).Name
returns:
"ICollection`1"
So the debugger appears to be able to show it is an ICollection of some kind.
Am I overlooking something, is this featured behavior, or is it a bug in VS22 / .NET7
TIA
Aucun commentaire:
Enregistrer un commentaire