[英]How do I get ConfigurationSection property as a System.Type
[英]How do I convert a System.Type to its nullable version?
再說一遍:“是否有一種比我的助手方法更簡單的內置處理方式?”
因此從可為空的類型中獲取基礎類型很容易,但是如何獲取.NET類型的可為空的版本呢?
所以我有
typeof(int)
typeof(DateTime)
System.Type t = something;
而且我要
int?
DateTime?
要么
Nullable<int> (which is the same)
if (t is primitive) then Nullable<T> else just T
有內置方法嗎?
這是我使用的代碼:
Type GetNullableType(Type type) {
// Use Nullable.GetUnderlyingType() to remove the Nullable<T> wrapper if type is already nullable.
type = Nullable.GetUnderlyingType(type) ?? type; // avoid type becoming null
if (type.IsValueType)
return typeof(Nullable<>).MakeGenericType(type);
else
return type;
}
我已經在實用程序庫中編寫了一些我非常依賴的方法。 第一種是將任何Type轉換為其對應的Nullable <Type>形式的方法:
/// <summary>
/// [ <c>public static Type GetNullableType(Type TypeToConvert)</c> ]
/// <para></para>
/// Convert any Type to its Nullable<T> form, if possible
/// </summary>
/// <param name="TypeToConvert">The Type to convert</param>
/// <returns>
/// The Nullable<T> converted from the original type, the original type if it was already nullable, or null
/// if either <paramref name="TypeToConvert"/> could not be converted or if it was null.
/// </returns>
/// <remarks>
/// To qualify to be converted to a nullable form, <paramref name="TypeToConvert"/> must contain a non-nullable value
/// type other than System.Void. Otherwise, this method will return a null.
/// </remarks>
/// <seealso cref="Nullable<T>"/>
public static Type GetNullableType(Type TypeToConvert)
{
// Abort if no type supplied
if (TypeToConvert == null)
return null;
// If the given type is already nullable, just return it
if (IsTypeNullable(TypeToConvert))
return TypeToConvert;
// If the type is a ValueType and is not System.Void, convert it to a Nullable<Type>
if (TypeToConvert.IsValueType && TypeToConvert != typeof(void))
return typeof(Nullable<>).MakeGenericType(TypeToConvert);
// Done - no conversion
return null;
}
第二種方法只是報告給定的Type是否可為空。 此方法由第一個調用,並且分別有用:
/// <summary>
/// [ <c>public static bool IsTypeNullable(Type TypeToTest)</c> ]
/// <para></para>
/// Reports whether a given Type is nullable (Nullable< Type >)
/// </summary>
/// <param name="TypeToTest">The Type to test</param>
/// <returns>
/// true = The given Type is a Nullable< Type >; false = The type is not nullable, or <paramref name="TypeToTest"/>
/// is null.
/// </returns>
/// <remarks>
/// This method tests <paramref name="TypeToTest"/> and reports whether it is nullable (i.e. whether it is either a
/// reference type or a form of the generic Nullable< T > type).
/// </remarks>
/// <seealso cref="GetNullableType"/>
public static bool IsTypeNullable(Type TypeToTest)
{
// Abort if no type supplied
if (TypeToTest == null)
return false;
// If this is not a value type, it is a reference type, so it is automatically nullable
// (NOTE: All forms of Nullable<T> are value types)
if (!TypeToTest.IsValueType)
return true;
// Report whether TypeToTest is a form of the Nullable<> type
return TypeToTest.IsGenericType && TypeToTest.GetGenericTypeDefinition() == typeof(Nullable<>);
}
上面的IsTypeNullable實現每次都像冠軍一樣工作,但是在最后一行代碼中有些冗長和緩慢。 以下代碼主體與上面的IsTypeNullable相同,但最后一行代碼更簡單,更快捷:
// Abort if no type supplied
if (TypeToTest == null)
return false;
// If this is not a value type, it is a reference type, so it is automatically nullable
// (NOTE: All forms of Nullable<T> are value types)
if (!TypeToTest.IsValueType)
return true;
// Report whether an underlying Type exists (if it does, TypeToTest is a nullable Type)
return Nullable.GetUnderlyingType(TypeToTest) != null;
請享用!
標記
PS-關於“可空性”
我應該在另一篇文章中重復有關可空性的聲明,該聲明直接適用於正確解決此主題。 也就是說,我認為這里的討論重點不應是如何檢查對象是否為通用Nullable類型,而是應該是否可以為該類型的對象分配null值。 換句話說,我認為我們應該確定對象類型是否可為空,而不是它是否可為空。 區別在於語義,即確定可為空性的實際原因,通常這很重要。
在使用對象的類型直到運行時可能未知的系統(Web服務,遠程調用,數據庫,提要等)中,一個共同的要求是確定是否可以為該對象分配空值,或者該對象是否可能包含空值。 對非空類型執行此類操作可能會產生錯誤,通常是異常,這在性能和編碼要求方面都非常昂貴。 為了采取主動避免此類問題的首選方法,有必要確定任意類型的對象是否能夠包含null。 即,它通常是否為“可為空”。
從非常實際和典型的意義上講,.NET術語中的可為空性不一定表示對象的類型是可為空的形式。 實際上,在許多情況下,對象具有引用類型,可以包含空值,因此都可以為空。 這些都沒有Nullable類型。 因此,出於實用目的,在大多數情況下,應該針對可空性的一般概念進行測試,而不是依賴於實現的可空性概念。 因此,我們不應該只專注於.NET Nullable類型,而應該在專注於通用性,實用性的可空性概念的過程中結合我們對它的要求和行為的理解。
Lyman的回答很好,對我有所幫助,但是,還有一個錯誤需要修復。
僅當類型尚未為Nullable
類型時,才應調用Nullable.GetUnderlyingType(type)
。 否則,當類型派生自System.RuntimeType
(例如,當我傳入typeof(System.Int32)
),它似乎錯誤地返回了null。 下面的版本通過檢查類型是否為Nullable
來避免調用Nullable.GetUnderlyingType(type)
。
在下面,您將找到此方法的ExtensionMethod
版本,該版本將立即返回類型, 除非它是尚未為Nullable
的ValueType
。
Type NullableVersion(this Type sourceType)
{
if(sourceType == null)
{
// Throw System.ArgumentNullException or return null, your preference
}
else if(sourceType == typeof(void))
{ // Special Handling - known cases where Exceptions would be thrown
return null; // There is no Nullable version of void
}
return !sourceType.IsValueType
|| (sourceType.IsGenericType
&& sourceType.GetGenericTypeDefinition() == typeof(Nullable<>) )
? sourceType
: typeof(Nullable<>).MakeGenericType(sourceType);
}
(對不起,但是我不能簡單地在萊曼的答案中發表評論,因為我是新來的,並且沒有足夠的代表。)
我不知道內置什么內容,例如int?
等只是Nullable<T>
語法糖; 並且沒有得到特別的待遇。 鑒於您嘗試從給定類型的類型信息中獲取此信息,這種情況尤其不可能發生。 通常,這總是需要一定的“滾動自己的”代碼。 您將必須使用Reflection創建帶有輸入類型的type參數的新Nullable
類型。
編輯:正如評論所建議的,實際上Nullable<>
被特殊對待,並在運行時按照本文中的說明進行引導。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.