ChatGPT解决这个技术问题 Extra ChatGPT

Nullable<value> 类型的条件运算符赋值?

EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : Convert.ToInt32(employeeNumberTextBox.Text),

我经常发现自己想做这样的事情(EmployeeNumberNullable<int>,因为它是 LINQ-to-SQL dbml 对象的属性,其中列允许 NULL 值)。不幸的是,编译器认为

'null' 和 'int' 之间没有隐式转换

即使这两种类型在对它们自己的可为空的 int 的赋值操作中都是有效的。

据我所知,使用空合并运算符不是一个选项,因为如果它不为空,则需要在 .Text 字符串上进行内联转换。

据我所知,这样做的唯一方法是使用 if 语句和/或分两步分配它。在这种特殊情况下,我发现这非常令人沮丧,因为我想使用对象初始化器语法,而这个赋值将在初始化块中......

有谁知道更优雅的解决方案?

查看 Eric Lippert 的相关博客条目:Type inference woes, part one
Compiler Error CS0173把我带到了这里。
C#9 支持 target typing of conditional expressions 以减少您遇到此问题的机会。在这个问题给出的示例中,如果 EmployeeNumber 属性的类型是 int?,编译器会推断出类型,但如果分配给更通用的类型(如 object)或新的声明的 var 变量。

L
Liam

出现问题是因为条件运算符不查看如何使用值(在这种情况下分配)来确定表达式的类型 - 只是真/假值。在这种情况下,您有一个 null 和一个 Int32,并且无法确定类型(有真正的原因不能只假设 Nullable<Int32>)。

如果你真的想以这种方式使用它,你必须自己将其中一个值强制转换为 Nullable<Int32>,这样 C# 才能解析类型:

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? (int?)null
    : Convert.ToInt32(employeeNumberTextBox.Text),

或者

EmployeeNumber =
    string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : (int?)Convert.ToInt32(employeeNumberTextBox.Text),

您也可以写 new int?()
你说它不能假设 Nullable 有真正的原因。什么原因?
@SLaks 或 default(int?)
真正的原因?我也看不出真正的原因。
N
NerdFury

我认为一种实用方法可以帮助使这个更清洁。

public static class Convert
{
    public static T? To<T>(string value, Converter<string, T> converter) where T: struct
    {
        return string.IsNullOrEmpty(value) ? null : (T?)converter(value);
    }
}

然后

EmployeeNumber = Convert.To<int>(employeeNumberTextBox.Text, Int32.Parse);

这是一个非常好的主意,也是泛型和扩展方法非常棒的一个例子:)
R
Rory McCrossan

虽然 Alex 为您的问题提供了正确和最接近的答案,但我更喜欢使用 TryParse

int value;
int? EmployeeNumber = int.TryParse(employeeNumberTextBox.Text, out value)
    ? (int?)value
    : null;

它更安全,并且可以处理无效输入的情况以及您的空字符串情况。否则,如果用户输入类似 1b 的内容,他们将看到一个错误页面,其中包含在 Convert.ToInt32(string) 中导致的未处理异常。


我更喜欢使用 ASP.NET CompareValidator 来验证用户的输入,它可以设置为 DataTypeCheck 的运算符和 int 的类型。这确保了输入永远不会是整数以外的任何东西,并且如果可以的话,它会在客户端进行。
A
Abe Heidebrecht

您可以转换 Convert 的输出:

EmployeeNumber = string.IsNullOrEmpty(employeeNumberTextBox.Text)
   ? null
   : (int?)Convert.ToInt32(employeeNumberTextBox.Text)

I
Irshad
//Some operation to populate Posid.I am not interested in zero or null
int? Posid = SvcClient.GetHolidayCount(xDateFrom.Value.Date,xDateTo.Value.Date).Response;
var x1 = (Posid.HasValue && Posid.Value > 0) ? (int?)Posid.Value : null;

编辑:上面的简要说明,我试图在变量 X1 中获取 Posid 的值(如果它的非空 int 并且值大于 0)。我必须在 Posid.Value 上使用 (int?) 才能使条件运算符不引发任何编译错误。仅供参考 GetHolidayCount 是一种 WCF 方法,可以给出 null 或任何数字。希望有帮助


通常建议您包含对代码功能的描述,而不仅仅是发布代码。这有助于提出问题的人(以及在遇到相同问题时发现此问题的人)了解您的解决方案在做什么。
G
Glorfindel

C# 9.0 开始,这将最终成为可能:

目标打字??和?:有时是有条件的??和 ?: 表达式在分支之间没有明显的共享类型。这种情况今天失败了,但是如果有两个分支都转换为的目标类型,C# 9.0 将允许它们:Person person = student ??顾客; // 共享基类型 int?结果 = b? 0:空; // 可空值类型

这意味着问题中的代码块也将无错误地编译。

EmployeeNumber =
string.IsNullOrEmpty(employeeNumberTextBox.Text)
    ? null
    : Convert.ToInt32(employeeNumberTextBox.Text),

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅