【问题标题】:How to convert C# nullable int to int如何将 C# 可为空的 int 转换为 int
【发布时间】:2011-08-25 02:48:45
【问题描述】:

如何将可为空的int 转换为int?假设我有 2 种类型的 int 如下:

int? v1;  
int v2; 

我想将v1 的值分配给v2v2 = v1; 会导致错误。如何将v1 转换为v2

【问题讨论】:

  • v1null 时,期望的行为是什么?

标签: c# nullable


【解决方案1】:

目前为止的其他答案都是正确的;我只是想再添加一个稍微干净一点的:

v2 = v1 ?? default(int);

任何Nullable<T> 都可以隐式转换为它的T,前提是要评估的整个表达式永远不会导致对ValueType 的空赋值。因此,空合并运算符?? 只是三元运算符的语法糖:

v2 = v1 == null ? default(int) : v1.Value;

...这又是 if/else 的语法糖:

if(v1==null)
   v2 = default(int);
else
   v2 = v1.Value;

此外,从 .NET 4.0 开始,Nullable<T> 有一个“GetValueOrDefault()”方法,它是一个 null 安全的 getter,基本上执行上面显示的 null 合并,所以这也有效:

v2 = v1.GetValueOrDefault();

【讨论】:

  • 真的需要default(int) 吗?一个简单的0 有什么问题?
  • 它适用于本示例,但在一般情况下,建议在适当的情况下使用default。零作为一个值并不总是有效的,更不用说默认值了,所以如果你用通用的T 替换int,你会发现我的代码有效,而零无效。在某些未来的框架版本中,default 也可能变得可重载;如果发生这种情况,使用默认值的代码将很容易利用,而显式的 null 或零分配将不得不更改。
  • 这应该上升到顶部:.NET 4.0,Nullable 有一个“GetValueOrDefault()”
  • 感谢您回来使用 GetValueOrDefault 编辑它!
  • 由 VS2019 建议 v2 = v1 ??默认;
【解决方案2】:

这样,

if(v1.HasValue)
   v2=v1.Value

【讨论】:

    【解决方案3】:

    您可以使用 Value 属性进行赋值。

    v2 = v1.Value;
    

    【讨论】:

    • 另外——如果你不确定 v1 是否包含 null——你可以使用 null-coalescing 操作符来设置一个后备值。例如。 v2 = v1 ?? 0;
    • 并且一定要先检查v1.HasValue
    • MSDN 说,如果v1null,这将引发异常。在我看来,这不是一个正确的答案。
    • @ventiseis 我认为这是可取的行为——我很惊讶许多其他答案都可以默默地将 null 转换为 0。如果您将可空类型分配给非可空类型,您应该确保该值实际上不是空的。 OP 没有说“我想将 v1 分配给 v2,或者如果 v1 为空,则为 0”,但这似乎是每个人的假设
    【解决方案4】:

    你只需要..

    v2= v1.GetValueOrDefault();
    

    【讨论】:

    • 请注意,如果它为空,则返回 0
    【解决方案5】:

    如果 v1 为 null,则无法执行此操作,但可以通过操作员检查。

    v2 = v1 ?? 0;

    【讨论】:

    • 这个对我最有用
    【解决方案6】:

    如果您知道v1 有值,则可以使用Value 属性:

    v2 = v1.Value;
    

    如果有一个值,使用GetValueOrDefault 方法将分配值,否则为类型的默认值,或您指定的默认值:

    v2 = v1.GetValueOrDefault(); // assigns zero if v1 has no value
    
    v2 = v1.GetValueOrDefault(-1); // assigns -1 if v1 has no value
    

    您可以使用HasValue 属性来检查v1 是否有值:

    if (v1.HasValue) {
      v2 = v1.Value;
    }
    

    GetValueOrDefault(T) 方法也有语言支持:

    v2 = v1 ?? -1;
    

    【讨论】:

    • 您不应该在没有先检查是否有值的情况下使用该值。使用 ??运算符。
    【解决方案7】:

    GetValueOrDefault()

    检索对象的值。如果为 null,则返回 int 的默认值,即 0。

    例子:

    v2= v1.GetValueOrDefault();

    【讨论】:

      【解决方案8】:

      如果给定类型的默认值是可接受的结果:

      if (v1.HasValue)
          v2 = v1.GetValueOrDefault();

      如果在结果未定义时需要不同的默认值:

      v2 = v1.GetValueOrDefault(255);    // or any valid value for int in place of 255

      如果你只想返回值(无论方法是否失败):

      v2 = v1.GetValueOrDefault();


      .NET 4.7.2.:GetValueOrDefault() 返回字段值而不进行任何检查。

      【讨论】:

        【解决方案9】:

        就我而言,最好的解决方案是使用GetValueOrDefault() 方法。

        v2 = v1.GetValueOrDefault();
        

        【讨论】:

        • 这个对我最有用
        • 请注意,如果它为空,则返回 0
        【解决方案10】:

        根据您的使用上下文,您可以使用 C# 7 的模式匹配功能:

        int? v1 = 100;
        if (v1 is int v2)
        {
            Console.WriteLine($"I'm not nullable anymore: {v2}");
        }
        

        编辑:

        由于有些人在不解释的情况下投了反对票,我想补充一些细节来解释将其作为可行解决方案的理由。

        • C# 7's pattern matching 现在允许我们检查值的类型并隐式转换它。在上面的 sn-p 中,只有当存储在 v1 中的值与 v2 的类型兼容时,if 条件才会通过,在这种情况下是 int。因此,当v1 的值为null 时,if 条件将失败,因为 null 不能分配给int。更准确地说,null 不是 int

        • 我想强调的是,这种解决方案可能并不总是最佳选择。正如我所建议的,我相信这将取决于开发人员的确切使用上下文。如果您已经有一个int? 并希望对其值进行有条件地操作if-and-only-if,则分配的值不为空(这是唯一可以安全地转换可为空的 int到一个常规的 int 而不会丢失信息),那么模式匹配可能是最简洁的方法之一。

        【讨论】:

        • 不幸的是,引入新变量名的必要性,但如果没有默认值,这是最好(最安全)的解决方案,因为不存在意外重构 HasValue 检查的风险。
        • 我只是没有看到这种方法比 v1.HasValue 作为检查然后 v1.Value 访问基础值有任何优势。我不会反对它,但我认为这个问题已经解决了,而且新技术并没有使问题更加清晰。我还将它的基准测试为慢了 8-9%。
        • 感谢您对其进行基准测试,很高兴知道!无论您怎么看,差异充其量是微不足道的(除非您在我认为的某个时间关键区域这样做)。我认为这更“简洁”或可能“惯用”,因为它依赖于语言中的语法糖而不是 API。这有点主观,但也许它“更易于维护”。尽管确实如此,但我更喜欢这种方法,而不是像许多其他答案所暗示的那样依赖默认值。
        【解决方案11】:

        Int nullable 到 int 的转换可以这样完成:

        v2=(int)v1;
        

        【讨论】:

        • 如果 v1 为 null,这将导致 InvalidOperationException。
        【解决方案12】:

        在 C# 7.1 及更高版本中,可以使用 default literal 而不是 default operator 来推断类型,因此可以编写如下:

        v2 = v1 ?? default;
        

        【讨论】:

          【解决方案13】:

          v2 = Convert.ToInt32(v1); 可以实现

          【讨论】:

          • 这在技术上是可行的,但其他技术如 HasValue / Value 或 GetValueOrDefault 运行效率更高。
          【解决方案14】:

          你可以的

          v2 = v1.HasValue ? v1.Value : v2;
          

          【讨论】:

            【解决方案15】:

            v1v2 之间的简单转换是不可能的,因为v1 的值域比v2 大。这是v1 可以容纳的所有内容以及null 状态。要进行转换,您需要明确说明 int 中的什么值将用于映射 null 状态。最简单的方法是?? 运算符

            v2 = v1 ?? 0;  // maps null of v1 to 0
            

            这也可以用长格式来完成

            int v2;
            if (v1.HasValue) {
              v2 = v1.Value;
            } else {
              v2 = 0;
            }
            

            【讨论】:

              【解决方案16】:

              如果v1不为空,则将v1赋值给v2,否则默认为零。

              v2=v1??0
              

              或者下面是另一种写法。

              v2 = v1.HasValue?v1:0
              

              【讨论】:

                【解决方案17】:

                可以使用以下任何一种转换方法来完成:

                v2 = Convert.ToInt32(v1);

                v2 = (int)v1;

                v2 = v1.GetValueOrDefault();

                v2 = v1.HasValue ? v1:0;

                【讨论】:

                  【解决方案18】:
                   int v2= Int32.Parse(v1.ToString());
                  

                  【讨论】:

                  • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
                  • 最好使用“最佳实践”的方式来解开可选项,而不是使用卑鄙的技巧。请参阅docs.microsoft.com/en-us/dotnet/csharp/language-reference/… 以供参考
                  • 在回答一个已有 15 个已有答案的 8 岁问题时,重要的是要说明您的答案所针对的问题的新方面,并注意时间的流逝是否改变了答案。添加一些解释几乎总是可以改进仅代码的答案。
                  • 我想这比其他答案要慢得多,绕道而行。仍然失败为空
                  • 我只是做了一个简单的测试:通过字符串往返它比其他一些选项慢大约 60 倍。高达 100 纳秒!
                  【解决方案19】:

                  我正在研究 C# 9 和 .NET 5,例如

                  foo 是可空的 int,我需要获取 foo 的 int 值

                  var foo = (context as AccountTransfer).TransferSide;
                  int value2 = 0;
                  if (foo != null)
                  {
                      value2 = foo.Value;
                  }
                  

                  https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/nullable-value-types#examination-of-an-instance-of-a-nullable-value-type查看更多信息

                  【讨论】:

                    【解决方案20】:

                    普通的TypeConversion会抛出异常

                    例如:

                    int y = 5;    
                    int? x = null;    
                    y = x.value; //It will throw "Nullable object must have a value"   
                    Console.WriteLine(y);
                    

                    使用Convert.ToInt32()方法

                    int y = 5;    
                    int? x = null;    
                    y = x.Convert.ToInt32(x);    
                    Console.WriteLine(y);
                    

                    这将返回 0 作为输出,因为 y 是一个整数。

                    【讨论】:

                    • 欢迎来到 StackOverflow。没有x.Convert这样的东西,请修复提供的示例。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-04-18
                    • 1970-01-01
                    • 2014-10-20
                    • 1970-01-01
                    • 2014-05-22
                    • 1970-01-01
                    • 2014-03-02
                    相关资源
                    最近更新 更多