Рассмотрим следующий код:Переходя параметр типа для универсального типа без каких-либо ограничений бросает исключение ограничений
IEnumerable<Type> oneParameterTypes = Assembly.GetAssembly(typeof(object))
.GetTypes()
.Where(t => t.IsGenericType)
.Where(t => t.GetGenericArguments().Length == 1)
.Where(t => t.GetGenericArguments().Single().GetGenericParameterConstraints().Length == 0);
oneParameterTypes
должен держать все общие типы в System.dll
сборки, которые могут быть переданы единый параметр универсального типа и не применяйте к нему ограничений.
Теперь давайте перейдем в качестве параметра типа:
IEnumerable<Type> intParameterTypes = oneParameterTypes.Select(t => t.MakeGenericType(typeof(int)))
.ToList();
Это должно работать, не так ли? Я имею в виду, что все типы в oneParameterTypes
не должны иметь ограничений типа, поэтому System.Int32
должен быть допустимым типом.
Тем не менее, линия выдает следующее исключение:
GenericArguments [0], 'System.Int32', на 'System.RuntimeType + ListBuilder`1 [Т]' нарушает ограничение типа «Т ».
Что это ListBuilder'1
тип и почему он в oneParameterTypes
, если он имеет ограничение типа? Почему мой фильтр Where
не работает?
Я думаю, это потому, что класс имеет ограничение на общем типе для 'class', но не для определенного класса. (а не 'struct') Например, если вы запустите свой код в пустом' public class Test, где T: class {} ', он будет работать точно так же. С головы до ног я не уверен, как именно вы это проверяете, или почему это обязательно не распространяется на ваши предложения 'Where'. –
@ChrisSinclair Это неутешительно. 'где T: class' является ограничением типа, но он не включен в' type.GetGenericParameterConstraints() '. Это намечено или это ошибка? –
Я так не думаю.См. Ответ [@Szabolcs] (http://stackoverflow.com/a/33530532/1269654). Это просто дополнительные атрибуты, которые вам нужно искать. Я считаю, что 'GetGenericParameterConstraints' проверяет только ограничения наследования _type, а не ограничения' class/struct' или ковариации/контравариантности. EDIT: Возможно, они считаются «атрибутами», а не ограничениями. Несмотря на это, я согласен с тем, что именование немного неоднозначно или сбивает с толку, даже если оно технически правильно (предполагается, что оно). –