繁体   English   中英

将null转换为某些内容?

[英]Cast a null into something?

今天我和一位同事进行了有趣的讨论。 我们正在用C#讨论两段代码。

代码段1:

if(!reader.IsDBNull(2))
{
  long? variable1 = reader.GetInt64(2)
}

代码段2:

long variable1 = reader.IsDBNull(2) ? (long?) null : reader.GetInt64(2)

问题是:将null转换为可为null的long是一种好习惯吗? 或者,您宁愿使用传统的if语句来避免将null强制转换为nullable long。

表达式(type?)nulldefault(type?)new Nullable<type>()最终被编译为相同的操作码:

        long? x = (long?)null;
        long? y = default(long?);
        long? z = new Nullable<long>();

变成:

    IL_0001: ldloca.s x
    IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int64>
    IL_0009: ldloca.s y
    IL_000b: initobj valuetype [mscorlib]System.Nullable`1<int64>
    IL_0011: ldloca.s z
    IL_0013: initobj valuetype [mscorlib]System.Nullable`1<int64>

换句话说,如果您正在使用可为空的类型,则可以自由使用最喜欢的版本。 但是请注意,您应该尝试避免使用可为空类型的算术。 如果要从条件表达式返回可为空的值,则两个可能的结果(如果其中一个可以为空)必须为可为空。 在这种情况下,任何其他方式都可能导致异常。

代替

(long?) null

使用

default(long?) 

我会像上面那样重构代码

long? variable1 = reader.IsDBNull(2) ? default(long?) : reader.GetInt64(2)

我更喜欢不使用null值(这对我来说很奇怪):

long? variable1 = reader.IsDBNull(2) ? null : (long?)reader.GetInt64(2);

另一个选择:

long? variable1 = reader.IsDBNull(2) ? default : reader.GetInt64(2); // requires C# 7.1
long? variable1 = reader.IsDBNull(2) ? default(long?) : reader.GetInt64(2);
long? variable1 = reader.IsDBNull(2) ? (long?)null : reader.GetInt64(2);
long? variable1 = reader.IsDBNull(2) ? new Nullable<long>() : reader.GetInt64(2);
long? variable1 = reader.IsDBNull(2) ? new long?() : reader.GetInt64(2);
long? variable1 = reader.IsDBNull(2) ? null : new long?(reader.GetInt64(2));

这只是口味问题。 我认为第一种选择比其他选择更具可读性。

更新:还考虑编写一些扩展方法以使您的代码更清晰:

public static class DataReaderExtensions
{
    public static long? GetNullableInt64(this IDataReader reader, int index)
    {
        if (reader.IsDBNull(index))
            return null;

        return reader.GetInt64(index);
    }
}

在这种情况下,您不使用三元运算符(不强制转换为可空值),并且从reader读取值看起来更漂亮:

long? variable1 = reader.GetNullableInt64(2);

在我的情况下,代码段2值得,因为如果为null您将得到0 ,这对于long是完全有效的值

在C#7.1中,您可以使用更简洁的default文字

var variable1 = reader.IsDBNull(2) ? default : reader.GetInt64(2);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM