【问题标题】:Nullable type and .HasValue still throws a Null Exception可空类型和 .HasValue 仍然抛出空异常
【发布时间】:2016-07-13 23:22:04
【问题描述】:

我有一个类来描述存储的各种电话。有时Importance 属性可以为空。这里是课堂

public class PhoneTypeListInfo
{
    public string AccountNum { get; set; }
    public int PhoneType { get; set; }
    public string PhoneNum { get; set; }

    public int Importance { get; set; }
}

我定义了一个函数,如果电话号码和帐号与给定的一组值匹配,它将返回 PhoneTypeListInfo

    protected PhoneTypeListInfo RetrievePhoneType(string info, string acctNumber)
    {
        PhoneTypeListInfo type = xPhoneTypeList.Where(p => p.PhoneNum == info && p.AccountNum == acctNumber).FirstOrDefault();

        return type;
    }

这一切都很好。我遇到的问题是下面的 linq 查询。

List<AlertBasedPhones> xAccountPhones = new List<AlertBasedPhones>();
xAccountPhones = (from x in xAccountStuff
                  where x.Media == "Phone"
                  let p = RetrievePhoneType(x.Info, acct.AccountNumber)
                  let xyz = x.Importance = (p.Importance as int?).HasValue ? p.Importance : 0
                  orderby p.Importance descending
                  select x).ToList();

我在上面所做的是尝试使用具有不同组成的不同类,除了从 PhoneTypeListInfo 获取“Importance”属性。

我的问题最终是,我需要做什么才能让p.Importance 为空,如果它为空,则将其设置为 0,使 x.Importance 也为 0。

【问题讨论】:

  • 我不认为 p.Importannce 为空,而是 p 本身。
  • 我认为 Scott 是对的,您需要对 p 本身进行额外检查,因为 RetrievePhoneType 可以返回 null
  • 空传播操作符 ?。在这里可能有用。
  • 因为重要性不是可以为空的 int 这个表达式:(p.Importance as int?).HasValue 始终为真

标签: c# linq


【解决方案1】:

不是p.Importannce 为空,而是p 本身。这就是您需要首先检查 null 的事情。如果您使用的是 C# 6,则可以使用 ?. 运算符。您还可以将(p.Importance as int?).HasValue ? p.Importance : 0 的逻辑简化为p.Importance ?? 0。结合两者你得到

List<AlertBasedPhones> xAccountPhones = new List<AlertBasedPhones>();
xAccountPhones = (from x in xAccountStuff
                         where x.Media == "Phone"
                         let p = RetrievePhoneType(x.Info, acct.AccountNumber)
                         let xyz = x.Importance = p?.Importance ?? 0
                         orderby p?.Importance descending
                         select x).ToList();

【讨论】:

  • p 不为空。我将测试罗伯茨的答案,但看起来我应该改用三元。
  • @ChrisClark 如果 0 行匹配 xPhoneTypeList.Where(p =&gt; p.PhoneNum == info &amp;&amp; p.AccountNum == acctNumber),则 p 将为空。罗伯特的回答是对 (null==p) 进行同样的空值检查,我只是使用 C# 6 引入的更方便的 ?. 运算符。
  • @ChrisClark 如果你确信你永远不会遇到xPhoneTypeList.Where(p =&gt; p.PhoneNum == info &amp;&amp; p.AccountNum == acctNumber) 返回 0 行的情况,然后将 .FirstOrDefault() 更改为 .First(),这样如果有 0 行就会抛出异常(但如果永远不会有 0 行,那将不是问题)
  • 我明白你在说什么。我改用三元,因为这不是 c# 6.0
  • 我将此标记为答案,因为我确信如果我有 c# 6.0.我将orderby p?.Importance descending 更改为x.Importance descending。并改用x.Importance = (p == null) ? 0 : p.Importance
【解决方案2】:

使用三元运算符。将p.Importance 替换为(null==p) ? 0 : p.Importance

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-17
    • 2018-10-12
    • 2017-09-02
    • 2012-09-09
    • 2015-09-25
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多