![](/img/trans.png)
[英]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.