Closed hsimah closed 6 years ago
I think this may have to be approached from two separate points of view.
T[]
and IEnumerable<T>
to their inner element type, T
.<dev:type>
<maml:name>System.Collections.Generic.IEnumerable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]</maml:name>
<maml:uri />
</dev:type>
should become:
<dev:type>
<maml:name>IEnumerable<int></maml:name>
<maml:uri />
</dev:type>
Looking at Microsoft cmdlets, they do report parameter types as the T[]
and my code simply gives T
. I agree we should be telling the end user that the parameter accepts a collection of inputs.
-I am a little busy at work this week, but if I get time I will play around with trying to output a better type.- Personally I would prefer T[]
over IEnumerable<T>
as it's more powershell-like. I am happy to do what you feel is best, though considering it is your tool.
Shall we move discussion to a new issue or continue in #33 ?
I came up with this:
/// <summary>
/// The type of the parameter.
/// </summary>
public Type ParameterType
{
get
{
switch (MemberInfo.MemberType)
{
case MemberTypes.Property:
return ((PropertyInfo)MemberInfo).PropertyType;
case MemberTypes.Field:
return ((FieldInfo)MemberInfo).FieldType;
default:
throw new NotSupportedException("Unsupported type: " + MemberInfo);
}
}
}
/// <summary>
/// The element type of the parameter
/// </summary>
/// <remarks>Will return null if the parameter type is not an array</remarks>
public Type ParameterElementType
{
get
{
switch (MemberInfo.MemberType)
{
case MemberTypes.Property:
var propertyType = ((PropertyInfo)MemberInfo).PropertyType;
return propertyType.GetElementType();
case MemberTypes.Field:
var fieldType = ((FieldInfo)MemberInfo).FieldType;
return fieldType.GetElementType();
default:
throw new NotSupportedException("Unsupported type: " + MemberInfo);
}
}
}
And
/// <summary>
/// The list of enumerated value names. Returns an empty sequence if there are no enumerated values
/// (normally because the parameter type is not an Enum type).
/// </summary>
public IEnumerable<string> EnumValues
{
get
{
if (MemberInfo.MemberType == MemberTypes.Property)
{
var type = ParameterType;
if (type.IsArray)
{
type = ParameterElementType;
}
if (type.IsEnum)
{
return type
.GetFields(BindingFlags.Public | BindingFlags.Static)
.Select(field => field.Name);
}
}
return Enumerable.Empty<string>();
}
}
This of course only works for array parameters. I only ever use those as I based my binary cmdlets on the Microsoft ones, for better or worse. This will result in the following markup:
For string[]
parameter:
<command:parameterValue required="true">string[]</command:parameterValue>
<dev:type>
<maml:name>System.String[]</maml:name>
<maml:uri />
</dev:type>
For MyType[]
parameter:
<command:parameterValue required="true">MyType[]</command:parameterValue>
<dev:type>
<maml:name>Cmdlets.MyType[]</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>Enum1</dev:defaultValue>
<command:parameterValueGroup>
<command:parameterValue required="false" variableLength="false">Enum1</command:parameterValue>
<command:parameterValue required="false" variableLength="false">Enum2</command:parameterValue>
<command:parameterValue required="false" variableLength="false">Enum3</command:parameterValue>
</command:parameterValueGroup>
There will be other pleases to do this sort of check, but as an idea I think this would work.
for #37 and #33 + some upgrades to C#7 and latest NUnit.