c# - 为什么可为空的显式转换 LINQ 运算符会对空值抛出无效格式异常?

标签 c# linq linq-to-sql

首先,我知道这个问题可以用一个简单的回答来回答,即空字符串不是空值。此外,我最近才在今年早些时候通过另一个 stackoverflow 问题发现了 cast 运算符,并且对它们没有太多经验。即便如此,它并不完全那么简单的原因是这些强制转换运算符与 null 合并运算符结合使用时,被宣传为处理错误情况(如 LINQ 表达式中缺少元素或属性)的优雅解决方案。我开始使用 the approach described by ScottH in "Improving LINQ Code Smell..."和 ScottGu "Null coalescing operator (and using it with LINQ)"作为一种以简洁和半优雅的方式防止无效/丢失数据的方法。据我所知,这似乎是首先将所有强制转换重载放在 LINQ 类中的动机之一。

因此,在我看来,处理缺失值的用例与处理空值并没有什么不同,在链接的文章中,这种方法被认为是处理此类情况的好方法.

场景:

int length = (int?)elem.Attribute("Length") ?? 0;

如果缺少@Length 属性,转换将导致空值和??运算符返回 0;

如果 @Length 属性存在但为空,则强制转换在 int.tryparse 上进行内部分支并抛出格式异常。当然,对于我的用法,我希望它不会返回 null,这样我就可以在已经有些复杂的 LINQ 代码中继续使用这种方法。

最终,与其说我不能想出一个解决方案,不如说我有兴趣听听是否有一个明显的方法被我遗漏了,或者是否有人对遗漏的原因有很好的看法解决了值(value)场景,但没有解决空值场景。

编辑

似乎有几个关键点我应该尝试强调一下:

  • 链接的文章来 self 钦佩并寻求指导的 MS 员工。这些文章似乎提出(或至少提请注意)一种改进/替代方法来处理可选值

  • 在我的例子中,可选值有时以缺失元素或属性的形式出现,但的形式出现元素或值

  • 所描述的方法对于缺失值按预期工作,但对于空值则失败

  • 遵循上述方法的代码似乎可以防止缺少可选值,但实际上它很脆弱,在特定情况下会中断。我担心的是当实际上你仍然处于危险之中时保护的外表

  • 如果目标元素存在但为空,这可以通过声明两个链接示例都失败并出现运行时异常来突出显示

  • 最后,关键要点似乎是当您有一个契约(Contract)(可能通过架构)确保元素或属性永远为空但在在契约(Contract)不存在的情况下,这种方法无效,需要替代方法

最佳答案

我碰巧同意这种行为;如果我没有“id”属性/元素,那么我很乐意将它算作 null,但如果它存在但不解析,那是不同的 - 空字符串适用于极少数类型。您必须手动执行此操作,或者您可以在 XAttribute 等上添加扩展方法:

public static int? ParseInt32(this XAttribute attrib) {
    if(attrib != null && string.IsNullOrEmpty(attrib.Value)) return null;
    return (int?)attrib;
}

请注意,我在内部使用强制转换作为 虽然它对于 int 来说很简单,但是 .Parse 将是一个不好的例子 DateTime 等,它在 xml 中使用不同的格式,转换在内部处理。

关于c# - 为什么可为空的显式转换 LINQ 运算符会对空值抛出无效格式异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4826287/

相关文章:

performance - 为什么使用 Linq To Objects 时 IQueryable 比 IEnumerable 快两倍

c# - 如何在 XDocument 元素的名称中使用 ':' 字符?

.net - 使用与声明上下文变量相比有优势吗?

c# - 串口缓冲区/波特率/丢失数据

c# - 生成 pgp key 时出现问题?

c# - 动态构建 LINQ 查询 - 强制使用 sp_executesql 而不是原始查询

asp.net - 大数据集的自动完成优化

c# - 与 SQL 更新相比的 LINQ 更新问题。需要帮忙

c# - 如何使用 selenium C# 清除 session 存储?

原始内存流上的 C# 数学性能