I have a method signature like this:
public class Class1<TItem>
{
public void CopyTo(TItem[] items) { }
}
where TItem
is declared on the parent class.
When I use Reflection to parse this method:
// not returning TItem as generic in signature
string sig = method.FullName; // ClassLibrary1.Class1`1.CopyTo(TItem[])
if (method.ContainsGenericParameters) // true
{
Type[] genericArgs = method.GetGenericArguments(); // returns empty
foreach (Type genericArg in genericArgs)
{
loM.cGenericParameters += genericArg.Name + ",";
}
}
I need to figure out what the generic type signature is so I can look at the XML documentation (need to build the funky generic type lookup signature). I need to map the method signature to what's in the XML documentation which looks like this:
<member name="M:ClassLibrary1.Class1`1.CopyTo(`0[])">
I'm unable to reliably detect whether TItem[] is generic and figure out how to get the generic index (generically).
When I look at the parameter signature, the ParameterType.IsGenericType
is false as is .GenericParameterPosition
. ParameterType.ContainsGenericParameters
is true, but nowhere does it give me the generic raw type signature (ie. '0[]
that the signature requires and is usually seen in the .FullName property).
This all works if the Generic definition is on actual method (ie. SomeMethod<TItem>(TItem[] blah)
at which point I can parse out the parameters as I need to. But when the generic parameter is defined on the type I can't figure out the right signature to reference the parent generic type by it's generic parameter position.
I think the problem is that you're looking at the generic arguments of the method instead of the method's parameters. You'll also have to differentiate between an array and a generic type.
if (method.ContainsGenericParameters)
{
foreach (var parameter in method.GetParameters())
{
if (parameter.ParameterType.IsArray)
{
var elementType = parameter.ParameterType.GetElementType();
var genericArgName = elementType.Name;
var genericParameterPosition = elementType.GenericParameterPosition;
}
else if (parameter.ParameterType.IsGenericType)
{
foreach (var genericArg in parameter.ParameterType.GetGenericArguments())
{
var genericArgName = genericArg.Name;
var genericParameterPosition = genericArg.GenericParameterPosition;
// If you need to differentiate between a generic arg that is declared
// in the method versus being declared in the class/interface/struct:
if (genericArg.DeclaringMethod == null)
{
// Declared in the class/interface/struct
}
else
{
// Declared in the method
}
}
}
}
}
Things get a little weird when you have something like Class2<>.Foo<>
below - the genericArg
variable will have a GenericParameterPosition
of 0
for both iterations of the foreach
loop. Check the DeclaringMethod
property for a null value to determine what that position refers to: the method or the class/interface/struct.
public class Class2<TKey>
{
public void Foo<TValue>(IDictionary<TKey, TItem> items) { }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.