Удивительно, что следующий код не сбрасывает Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
Так просто из любопытства, как вы можете определить, является ли данный экземпляр объектом Nullable < > или нет?
Удивительно, что следующий код не сбрасывает Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
Так просто из любопытства, как вы можете определить, является ли данный экземпляр объектом Nullable < > или нет?
Хорошо, во-первых, Nullable<T>
- это структура, поэтому нет объекта как такового. Вы не можете вызвать GetType()
, так как это приведет к значению (в этот момент вы либо получите нуль, и, таким образом, исключение, или значение, не равное нулю, и, следовательно, не тот тип, который вы хотите).
(Бокс - это то, что испортило ваше утверждение здесь - я бы предположил, что IsType
принимает object
.)
Вы можете использовать вывод типа, хотя для получения типа переменной в качестве параметра типа:
public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
Это не огромное количество использования, когда вы знаете точный тип во время компиляции, как в вашем примере, но это полезно для дженериков. (Конечно, есть альтернативные способы его реализации.)
Какова ваша реальная жизненная ситуация? Я предполагаю, что это не утверждение, подобное этому, учитывая, что вы знаете ответ на этот вопрос во время компиляции.
Мне нравится ответ @jon-skeet, но он работает только, если вы знаете тип, с которым вы тестируете. В нашем мире мы используем отражение, чтобы открывать объекты и тестировать значения в выражениях регулярных выражений.
упрощение расширения для работы для любого типа, работающего лучше для нас.
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
дженерики - это кровь жизни, но иногда...:)
int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);
Какое пространство имен Assert
в?
Возвращает true
, как и следовало ожидать:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
Хотя стоит отметить, что typeof(Nullable<int>).IsInstanceOfType(42)
также возвращает true - это потому, что этот метод принимает object
и поэтому получает коробку как Nullable<int>
.
Вот что я придумал, поскольку все остальное, казалось, потерпело неудачу - по крайней мере, в Portable Class Library/DotNet Core s >= С# 6
В основном вы расширяете общий тип Object
и Nullable<T>
и используете тот факт, что статический метод расширения, соответствующий базовому типу, будет вызываться и имеет приоритет над общим методом T
.
public static partial class ObjectExtension
{
public static bool IsNullable<T>(this T self)
{
return false;
}
}
и один для Nullable<T>
public static partial class NullableExtension
{
public static bool IsNullable<T>(this Nullable<T> self) where T : struct
{
return true;
}
}
Использование Reflection и type.IsGeneric
и type.GetGenericParameters()
не работало с моим текущим набором .NET Runtimes.