Как проверить, не является ли объект, который я получаю как результат метода , ValueType
и не IEnumerable<ValueType>
?
Вот что я написал:
MethodInfo selectedOverload = SelectOverload(selectedMethodOverloads);
object result = ExecuteAndShowResult(selectedOverload);
ExploreResult(result);
private static void ExploreResult(object result)
{
if (result != null &&
!(result is ValueType) &&
!((IEnumerable)result).GetType().GetProperty("Item").PropertyType) is ValueType)
)
Console.WriteLine("explore");
}
К сожалению, тип PropertyType
- Type
, его содержимое - это тип, который мне нужно проверить (например, int
), но я не знаю, как это сделать.
РЕДАКТИРОВАТЬ:
Хорошо, .IsValueType
работал, но теперь я хочу также исключить строки (которые не распознаются как ValueTypes), и что?
!(((IEnumerable)result).GetType().GetProperty("Item").PropertyType is string)
Не работает!
ИЗМЕНИТЬ 2:
Просто ответил себе:
!(((IEnumerable)result).GetType().GetProperty("Item").PropertyType == typeof(string))
Остается открытым вопрос о том, что, если я хочу проверить наследование от базового класса:
!(((IEnumerable)result).GetType().GetProperty("Item").PropertyType == typeof(BaseClass))
Не работает, потому что typeof проверяет тип среды выполнения, и если PropertyType == InheritedClassType
он вернет false ...
1 ответ
Используйте Type.IsValueType
:
private static void ExploreResult(object result)
{
if (result != null &&
!(result.GetType().IsValueType) &&
!((IEnumerable)result).GetType().GetProperty("Item").PropertyType.IsValueType)
)
Console.WriteLine("explore");
}
Хотя, если result
не является типом значения, но не IEnumerable
, вы получите ошибку приведения. Эта проверка требует доработки.
Ответ на вторую часть
!((IEnumerable)result).GetType().GetProperty("Item").PropertyType is string)
Всегда ложно, потому что PropertyType
возвращает Type
, который никогда не является строкой. Я думаю ты хочешь
!(result.GetType().GetProperty("Item").PropertyType == typeof(string))
Обратите внимание, что я удалил приведение к IEnumerable
, поскольку вы все равно ищете свойство через отражение, поэтому приведение не имеет значения.
Ответ на третье изменение
Я хочу проверить наследование от базового класса
Для этого вам нужно type.IsAssignableFrom()
:
Type itemType = result.GetType().GetProperty("Item").PropertyType;
bool isInheritedFromBaseClass =
typeof(BaseClass).IsAssignableFrom(itemType);
if (result is IEnumerable)
:)
IEnumerable.Item
определяется как object
. Если вы хотите знать, является ли это типом IEnumerable<T>
и что T
является типом значения, вам необходимо выполнить некоторую рефлексию относительно параметра универсального типа.
IEnumerable
вообще не имеет свойства Item
. Вам повезло, что базовым типом является как IEnumerable
, так и IEnumerable<T>
, у которого есть строго типизированное свойство Item
. Если бы тип был простым IEnumerable
(например, ArrayList
), вы бы получили исключение времени выполнения.
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.
GetProperty("Item").PropertyType.IsValueType
?object
, любые типы значений будут помещены в рамку, поэтому вы знаете , что это не тип значения. Вы на 100% уверены, что это всегда ссылочный тип. Если метод универсальный, то он может быть любым.