[英]Detecting a Nullable Type via reflection
令人驚訝的是,以下代碼未能通過 Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
因此,出於好奇,您如何確定給定實例是否為 Nullable<> object?
首先, Nullable<T>
是一個結構體,所以沒有這樣的對象。 您不能調用GetType()
,因為這會裝箱該值(此時您要么獲得 null 從而導致異常,要么獲得裝箱的不可為空值,因此不是您想要的類型)。
(拳擊在這里弄亂了你的斷言 - 我假設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<>);
這是我想出的,因為其他一切似乎都失敗了 - 至少在可移植類庫/ DotNet Core with >= C# 6
基本上,您擴展泛型 Type 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;
}
}
使用反射和type.IsGeneric
和type.GetGenericParameters()
在我當前的 .NET 運行時集上不起作用。
Assert
在什么命名空間中?
如您所料,以下返回true
:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
盡管值得注意的是typeof(Nullable<int>).IsInstanceOfType(42)
也返回 true - 這是因為此方法接受一個object
,因此被裝箱為Nullable<int>
。
它對我有用,也希望對你有用。
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
基於弗拉基米爾的回答:
public static class GenericExtensions
{
public static bool IsNullable<T>(this T item) =>
TypedReference.GetTargetType(__makeref(item)).FullName.Contains("System.Nullable");
}
用法:
int? nullableInt = 42;
bool nIntIsNullable = nullableInt.IsNullable();
持續時間:平均機器<2ms。
評論:
Contains("System.Nullable")
可以更具體。這對我有用,可以檢查類型是否為 Nullable..
type.Assembly.FullName.StartsWith("System") && type.Name.Contains("Nullable");
只有這種方式適用於我使用 .net core 7 的情況
bool isNullable = propertyInfo.GetMethod is null ? false : new NullabilityInfoContext().Create(propertyInfo.GetMethod.ReturnParameter).ReadState == NullabilityState.Nullable;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.