如何将 C# 可为空的 int 转换为 int
Posted
技术标签:
【中文标题】如何将 C# 可为空的 int 转换为 int【英文标题】:How to convert C# nullable int to int 【发布时间】:2011-08-25 02:48:45 【问题描述】:如何将可为空的int
转换为int
?假设我有 2 种类型的 int 如下:
int? v1;
int v2;
我想将v1
的值分配给v2
。 v2 = v1;
会导致错误。如何将v1
转换为v2
?
【问题讨论】:
当v1
是null
时,期望的行为是什么?
【参考方案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这样,
if(v1.HasValue)
v2=v1.Value
【讨论】:
【参考方案3】:您可以使用 Value 属性进行赋值。
v2 = v1.Value;
【讨论】:
另外——如果你不确定 v1 是否包含 null——你可以使用 null-coalescing 操作符来设置一个后备值。例如。 v2 = v1 ?? 0; 并且一定要先检查v1.HasValue
。
MSDN 说,如果v1
是null
,这将引发异常。在我看来,这不是一个正确的答案。
@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】:v1
和v2
之间的简单转换是不可能的,因为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 是一个整数。
【讨论】:
欢迎来到 ***。没有x.Convert
这样的东西,请修复提供的示例。以上是关于如何将 C# 可为空的 int 转换为 int的主要内容,如果未能解决你的问题,请参考以下文章
如何将 int.TryParse 与可为空的 int 一起使用? [复制]
将 int.TryParse 与可为空的 int 一起使用 [重复]
使用 XmlSerializer 将空 xml 属性值反序列化为可为空的 int 属性
将可为空的 int 映射到可为空的 int + automapper