2013-09-21 3 views
0

Я пытаюсь проверить следующееTypeOf (ICollection <>) .GetTypeInfo(). IsAssignableFrom (TypeOf (IList <>))

typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(targetProperty.PropertyType.GetTypeInfo()) 

где аргумент, переданный в IsAssignableFrom является IList<Something>. Но он возвращает ложь.

Следующие также возвращают false.

typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(targetProperty.PropertyType.GetTypeInfo().GetGenericTypeDefinition()) 

Даже следующее возвращается false.

typeof(ICollection<>).GetTypeInfo().IsAssignableFrom(typeof(IList<>)) 

Не должно ли последнее окончательно вернуться к истине?

Как я могу получить правильный результат, если targetProperty.PropertyType может быть любого типа? Это может быть List<T>, ObservableCollection<T>, a ReadOnlyCollection<T>, пользовательский тип сбора и т. Д.

+0

Мой первый вопрос был дан ниже, а второй - [здесь] (http://stackoverflow.com/a/1075059/122781). – HappyNomad

ответ

5

У вас есть два открытых типа. IsAssignableFrom интерпретирует их, как вопрос, может ли ICollection<T1> назначаться с IList<T2>. Это, в общем, ложно. Это верно только тогда, когда T1 = T2. Вам нужно что-то сделать, чтобы закрыть общие типы с одним и тем же аргументом. Вы можете заполнить типа, как object или вы могли бы получить общий тип параметра и использовать его:

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. 

кажется GetGenericArguments не доступен в PCL, и его поведение отличается от GenericTypeArguments собственности. В PCL вам нужно использовать 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. 
+0

Я получаю 'System.IndexOutOfRangeException' на' typeof (ICollection <>) .GenericTypeArguments [0] '. – HappyNomad

+0

'typeof (ICollection <>) .GetTypeInfo(). Однако работы GenericTypeParameters. – HappyNomad

+0

@HappyNomad 'GenericTypeArguments' возвращает пустой массив для определения общего типа. Вот почему я использовал 'GetGenericArguments()'. –

0

ICollection<T1> не может быть назначен IList<T2>в общем; в противном случае вы можете столкнуться с ситуациями, когда вы назначаете, например, List<char>, ICollection<bool>.

typeof(ICollection<>).IsAssignableFrom(typeof(IList<>))   // false 
typeof(ICollection<bool>).IsAssignableFrom(typeof(List<int>)) // false 

Вы можете , однако, назначить ICollection<T> из IList<T>, при условии, что параметр типа T то же самое.

typeof(ICollection<bool>).IsAssignableFrom(typeof(List<bool>)) // true 

Начиная с C# 4, это также работает для типа ковариации:

typeof(IEnumerable<BaseClass>).IsAssignableFrom(typeof(List<DerivedClass>)));   
    // true in C# 4 
    // false in prior verions 

Кроме того, вы можете назначить необщего базовые интерфейсы из любого универсального типа, который реализует их:

typeof(ICollection).IsAssignableFrom(typeof(List<bool>))   // true 
Смежные вопросы