首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将System.Type转换为可为空的版本?

如何将System.Type转换为可为空的版本?
EN

Stack Overflow用户
提问于 2008-09-20 13:08:12
回答 2查看 25.4K关注 0票数 82

再一次:“有没有一种比我的helper方法更简单的内置方法?”

所以从可空类型中获取底层类型很容易,但是如何获取.NET类型的可空版本呢?

所以我有

代码语言:javascript
复制
typeof(int)
typeof(DateTime)
System.Type t = something;

我想要

代码语言:javascript
复制
int? 
DateTime?

代码语言:javascript
复制
Nullable<int> (which is the same)
if (t is primitive) then Nullable<T> else just T

有没有内置的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2008-09-20 13:15:33

下面是我使用的代码:

代码语言:javascript
复制
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;
}
票数 120
EN

Stack Overflow用户

发布于 2011-10-14 03:34:10

我在我的实用程序库中编写了几个我非常依赖的方法。第一个是将任何类型转换为其对应的可空形式的方法:

代码语言:javascript
复制
    /// <summary>
    /// [ <c>public static Type GetNullableType(Type TypeToConvert)</c> ]
    /// <para></para>
    /// Convert any Type to its Nullable&lt;T&gt; form, if possible
    /// </summary>
    /// <param name="TypeToConvert">The Type to convert</param>
    /// <returns>
    /// The Nullable&lt;T&gt; 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&lt;T&gt;"/>
    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是否可以为空。此方法由第一个方法调用,并单独使用:

代码语言:javascript
复制
    /// <summary>
    /// [ <c>public static bool IsTypeNullable(Type TypeToTest)</c> ]
    /// <para></para>
    /// Reports whether a given Type is nullable (Nullable&lt; Type &gt;)
    /// </summary>
    /// <param name="TypeToTest">The Type to test</param>
    /// <returns>
    /// true = The given Type is a Nullable&lt; Type &gt;; 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&lt; T &gt; 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代码相同,只是最后一行代码更简单、更快:

代码语言:javascript
复制
        // 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;

享受吧!

标记

附注:关于“可空性”

我应该重复我在单独的帖子中所做的关于空性的声明,这直接适用于正确地解决这个主题。也就是说,我认为这里讨论的焦点不应该是如何检查对象是否为泛型Nullable类型,而是是否可以为其类型的对象赋值为null。换句话说,我认为我们应该确定一个对象类型是否可以为空,而不是它是否可以为空。不同之处在于语义,即确定可空性的实际原因,这通常是最重要的。

在使用在运行时之前可能未知类型的对象(web服务、远程调用、数据库、提要等)的系统中,一个常见的要求是确定是否可以将null分配给对象,或者该对象是否可能包含null。在不可为空的类型上执行这样的操作可能会产生错误,通常是异常,这在性能和编码要求方面都是非常昂贵的。要采取主动避免此类问题的首选方法,有必要确定任意类型的对象是否能够包含null;即,它是否通常是“可空”的。

在非常实际和典型的意义上,.NET术语中的可空性并不意味着对象的类型是可空的一种形式。事实上,在许多情况下,对象都有引用类型,可以包含空值,因此都是可以为空的;这些对象都没有可为空的类型。因此,在大多数情况下,出于实际目的,应该对一般的可空性概念进行测试,而不是对依赖于实现的可空性概念进行测试。因此,我们不应该仅仅关注.NET Nullable类型,而是将我们对其要求和行为的理解融入到关注一般的、实用的nullability概念的过程中。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/108104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档