ChatGPT解决这个技术问题 Extra ChatGPT

如何将 C# 可为空的 int 转换为 int

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

int? v1;  
int v2; 

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

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

M
Medinoc

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

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。零作为值并不总是有效的,更不用说默认值了,因此如果您将 int 替换为通用 T,您会发现我的代码有效,而零无效。在某些未来的框架版本中,default 也可能变得可重载;如果发生这种情况,使用默认值的代码将很容易利用,而显式的 null 或零分配将不得不更改。
这应该上升到顶部:.NET 4.0,Nullable 有一个“GetValueOrDefault()”
感谢您回来使用 GetValueOrDefault 对其进行编辑!
由 VS2019 建议 v2 = v1 ??默认;
S
Srinivas Reddy Thatiparthy

像这样,

if(v1.HasValue)
   v2=v1.Value

B
BoltClock

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

v2 = v1.Value;

此外 - 如果您不确定 v1 是否包含 null - 您可以使用 null-coalescing 运算符来设置回退值。例如 v2 = v1 ?? 0;
请务必先检查 v1.HasValue
MSDN 表示,如果 v1null,这将引发异常。在我看来,这不是一个正确的答案。
@ventiseis我认为这是可取的行为-我很惊讶许多其他答案都可以将空值静默转换为0。如果您将可空类型分配给不可空类型,则应该确保该值实际上不是空的。 OP 没有说“我想将 v1 分配给 v2,或者如果 v1 为空,则为 0”,但这似乎是每个人的假设
t
thestar

所有你需要的是..

v2= v1.GetValueOrDefault();

请注意,如果它为空,则返回 0
A
Arturo Martinez

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

v2 = v1 ?? 0;

这个对我最有用
G
Guffa

如果您知道 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;

如果没有先检查是否有值,则不应使用该值。使用 ??运算符。
M
Mamta D

获取值或默认值()

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

例子:

v2= v1.GetValueOrDefault();


G
GrzegorzF

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

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() 返回字段值而不进行任何检查。


M
Masoud Darvishian

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

v2 = v1.GetValueOrDefault();

这个对我最有用
请注意,如果它为空,则返回 0
N
Nicholas Miller

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

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

编辑:

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

C# 7 的模式匹配现在允许我们检查值的类型并隐式转换它。在上面的代码片段中,只有当 v1 中存储的值与 v2 的类型兼容时,if 条件才会通过,在本例中为 int。因此,当 v1 的值为 null 时,if 条件将失败,因为 null 不能分配给 int。更准确地说,null 不是 int。

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


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

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

v2=(int)v1;

如果 v1 为 null,这将导致 InvalidOperationException。
a
akesfeden

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

v2 = v1 ?? default;

R
Rev

v2 = Convert.ToInt32(v1); 有可能


这在技术上是可行的,但 HasValue / Value 或 GetValueOrDefault 等其他技术运行效率更高。
F
FIre Panda

你可以做

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

J
JaredPar

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;
}

S
Shaido

如果 v1 不为空,它会将 v1 的值分配给 v2,否则它将采用默认值为零。

v2=v1??0

或者下面是另一种写法。

v2 = v1.HasValue?v1:0

S
Salahuddin Ahmed

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

v2 = Convert.ToInt32(v1);

v2 = (int)v1;

v2 = v1.GetValueOrDefault();

v2 = v1.HasValue ? v1:0;


m
mohammad qavizi
 int v2= Int32.Parse(v1.ToString());

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

我正在研究 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 上查看更多信息


P
Peter Csala

普通的 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,请修复提供的示例。