I am trying to check the following
typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( targetProperty.PropertyType.GetTypeInfo() )
where the argument passed into IsAssignableFrom
is an IList<Something>
. But it is returning false.
The following also returns false.
typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( targetProperty.PropertyType.GetTypeInfo().GetGenericTypeDefinition() )
Even the following is returning false.
typeof( ICollection<> ).GetTypeInfo().IsAssignableFrom( typeof(IList<>) )
Shouldn't the latter definitely return true?
How can I get the correct result when targetProperty.PropertyType
can be any type at all? It could be a List<T>
, an ObservableCollection<T>
, a ReadOnlyCollection<T>
, a custom collection type, etc.
You have two open generic types. IsAssignableFrom
interprets these like asking whether ICollection<T1>
is assignable from IList<T2>
. This is, in general, false. It is only true when T1 = T2. You need to do something to close the generic types with the same type argument. You could fill in the type as object
or you could get the generic parameter type and use that:
var genericT = typeof(ICollection<>).GetGenericArguments()[0]; // a generic type parameter, T.
bool result = typeof(ICollection<>).MakeGenericType(genericT).IsAssignableFrom(typeof(IList<>).MakeGenericType(genericT)); // willl be true.
It seems GetGenericArguments
is not available in PCL, and its behavior is different than GenericTypeArguments
property. In a PCL you need to use GenericTypeParameters
:
var genericT = typeof(ICollection<>).GetTypeInfo().GenericTypeParameters[0]; // a generic type parameter, T.
bool result = typeof(ICollection<>).MakeGenericType(genericT).GetTypeInfo().IsAssignableFrom(typeof(IList<>).MakeGenericType(genericT).GetTypeInfo()); // willl be true.