【发布时间】:2011-08-25 02:48:45
【问题描述】:
如何将可为空的int 转换为int?假设我有 2 种类型的 int 如下:
int? v1;
int v2;
我想将v1 的值分配给v2。 v2 = v1; 会导致错误。如何将v1 转换为v2?
【问题讨论】:
-
当
v1是null时,期望的行为是什么?
如何将可为空的int 转换为int?假设我有 2 种类型的 int 如下:
int? v1;
int v2;
我想将v1 的值分配给v2。 v2 = v1; 会导致错误。如何将v1 转换为v2?
【问题讨论】:
v1 是null 时,期望的行为是什么?
目前为止的其他答案都是正确的;我只是想再添加一个稍微干净一点的:
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 或零分配将不得不更改。
这样,
if(v1.HasValue)
v2=v1.Value
【讨论】:
您可以使用 Value 属性进行赋值。
v2 = v1.Value;
【讨论】:
v1.HasValue。
v1 是null,这将引发异常。在我看来,这不是一个正确的答案。
你只需要..
v2= v1.GetValueOrDefault();
【讨论】:
如果 v1 为 null,则无法执行此操作,但可以通过操作员检查。
v2 = v1 ?? 0;
【讨论】:
如果您知道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;
【讨论】:
GetValueOrDefault()
检索对象的值。如果为 null,则返回 int 的默认值,即 0。
例子:
v2= v1.GetValueOrDefault();
【讨论】:
如果给定类型的默认值是可接受的结果:
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() 返回字段值而不进行任何检查。
【讨论】:
就我而言,最好的解决方案是使用GetValueOrDefault() 方法。
v2 = v1.GetValueOrDefault();
【讨论】:
根据您的使用上下文,您可以使用 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 检查的风险。
Int nullable 到 int 的转换可以这样完成:
v2=(int)v1;
【讨论】:
在 C# 7.1 及更高版本中,可以使用 default literal 而不是 default operator 来推断类型,因此可以编写如下:
v2 = v1 ?? default;
【讨论】:
v2 = Convert.ToInt32(v1); 可以实现
【讨论】:
你可以的
v2 = v1.HasValue ? v1.Value : v2;
【讨论】:
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;
}
【讨论】:
如果v1不为空,则将v1赋值给v2,否则默认为零。
v2=v1??0
或者下面是另一种写法。
v2 = v1.HasValue?v1:0
【讨论】:
可以使用以下任何一种转换方法来完成:
v2 = Convert.ToInt32(v1);
v2 = (int)v1;
v2 = v1.GetValueOrDefault();
v2 = v1.HasValue ? v1:0;
【讨论】:
int v2= Int32.Parse(v1.ToString());
【讨论】:
我正在研究 C# 9 和 .NET 5,例如
foo 是可空的 int,我需要获取 foo 的 int 值
var foo = (context as AccountTransfer).TransferSide;
int value2 = 0;
if (foo != null)
{
value2 = foo.Value;
}
【讨论】:
普通的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这样的东西,请修复提供的示例。