【问题标题】:Return null if generic type is nullable如果泛型类型可以为空,则返回 null
【发布时间】:2017-12-06 23:41:42
【问题描述】:

我正在编写一个函数来检查输出是否为DBNull,如果泛型类型可以为空则返回null。如果不是,它只会抛出错误。

更新:添加了所有建议

public T Get<T>(string key)
{
    int ordinal = reader.GetOrdinal(key);
    if (reader.IsDBNull(ordinal))
    {
        if (typeof(T).GetTypeInfo().IsValueType && Nullable.GetUnderlyingType(typeof(T)) == null) // isn't a nullable field
            throw new InvalidCastException();
        else return default(T);
    }
    return reader.GetFieldValue<T>(ordinal);
}

但是我不确定default(T) 是否为每个可空字段返回空值。如果现在还有其他方法可以让它返回 null 吗?

【问题讨论】:

  • 我不确定reader.GetFieldType(key) 是否通常会返回DBNull - 这是否有效?我会期望返回代表该列将包含的内容如果它不为空
  • 只是作为一个建议(除了 Marc 的回答/评论),反转 if 语句(如果它是 not null,return ...;),并取消elses 只是一个 throw...;

标签: c# generics nullable default-value mysql-connector


【解决方案1】:

是的,default(T) 是每个 T 的正确类型的 null 值,实际上是 SomeType? / Nullable&lt;SomeType&gt;,所以你所拥有的应该可以正常工作。

您可能需要考虑诸如 stringbyte[] 之类的东西 - 这些可以来自数据库并且可以为空。

如果有人只是犯了一个错误并在值为&lt;decimal&gt; 时请求&lt;int&gt;,您可能还想考虑错误应该是什么。这将导致InvalidCastExceptionIDataReader 上有一个 IsDBNull() 方法,它可能比使用异常更合适。

最后:比起throw e;,更喜欢throw;

【讨论】:

【解决方案2】:

就计算机资源而言,捕获和处理异常是一项极其昂贵的任务。您的方法将异常用作其逻辑流程的一部分。这是看待您要解决的问题的错误方式。

此外,您正在专门捕获InvalidCastException 异常。除了尝试强制转换空引用之外,此异常也可能发生在其他情况下。您隐藏/歪曲了一个潜在的有效错误;可能会花费您数小时令人沮丧、令人毛骨悚然的调试。

以下内容应该会为您提供与原始方法相同的行为,但不会产生在集成错误处理期间展开堆栈的开销。

public T Get<T>(string key)
{
    if(reader.IsDbNull(reader.GetOrdinal(key)))
    {
       //IF YOU SPECIFICALLY WANT TO THROW AN ERROR IF A VALUE TYPE
       //if (typeof(T).IsValueType) 
       //{ throw new InvalidCastException(); }
       return default(T);
    }

    return reader.GetFieldValue<T>(reader.GetOrdinal(key));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多