Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the equivalent of Type.GetGenericArguments() in .NETStandard 1.0 / .NET Core?

The method System.Type.GetGenericArguments() is 'missing' from .NETStandard 1.0, and I thought that the TypeInfo.GenericTypeArguments was the replacement for GetGenericArguments(), but unfortuntely they behave differently when supplied with an open generic type. Take for instance the following code:

Type type = typeof(ICommandHandler<>);
type.GetGenericArguments(); // return { TCommand }
type.GetTypeInfo().GenericTypeArguments; // returns empty array

While the GetGenericArguments() method returns the generic type argument TCommand, the GenericTypeArguments simply returns an empty array for the same open-generic type.

What is the exact behavior of GenericTypeArguments and what's the equivalent of Type.GetGenericArguments() in .NET Standard 1.0?

like image 697
Steven Avatar asked Aug 24 '16 17:08

Steven


2 Answers

After further investigation, the Type.GenericTypeArguments seems to only return anything if the type isn't a generic type definition. The TypeInfo.GenericTypeParameters on the other hand, only returns any if the type is a generic type definition.

The following code mimics the behavior of Type.GetGenericArguments():

type.GetTypeInfo().IsGenericTypeDefinition 
    ? type.GetTypeInfo().GenericTypeParameters 
    : type.GetTypeInfo().GenericTypeArguments;
like image 161
Steven Avatar answered Sep 19 '22 23:09

Steven


This may turn out to be a comment (not an answer) after all.

On .NET 4.6.1, there are two members on System.Type, namely:

/* 1 */ type.GetGenericArguments()               // returns { TCommand, }

/* 2 */ type.GenericTypeArguments                // returns empty array

plus one member on System.Reflection.TypeInfo, namely:

/* 3 */ type.GetTypeInfo().GenericTypeParameters // returns { TCommand, }

for a total of three members.

However, the two first-mentioned members are also inherited by System.Reflection.TypeInfo, a subclass of System.Type.

On .NET 4.6.1, when you do type.GetTypeInfo().GenericTypeArguments (as in your question), you really call the property on Type, i.e. my member marked /* 2 */.

like image 37
Jeppe Stig Nielsen Avatar answered Sep 21 '22 23:09

Jeppe Stig Nielsen