【问题标题】:Null checking for if then in C# [closed]在 C# 中对 if then 进行空值检查 [关闭]
【发布时间】:2022-01-22 07:54:08
【问题描述】:

我正在检查 C# 中的两个条件:

 if (result.Data.Count > 0)
 {
     if(result.Data[0].AdditionalData != null)
      {
         // To Do
      }
  } 

我的困惑是在单个 if 条件下检查这些是否有更好的方法?

我正在尝试使用 Null-Condition 运算符,但没有成功。 Null-Conditional operator in MSDN

【问题讨论】:

  • if(result.Data.FirstOrDefault()?.AdditionalData != null)
  • Data 也可以为空吗?在这种情况下,您应该添加Data?.。如果Data 可能为空,您可以使用Data?[0],但如果它不为空而是为空,您将得到一个索引越界异常,所以如果您尝试过但没有成功,那就对了:它不会工作。
  • 它可能适用于你的情况(在寻找第一个值时),但如果你想要第二个等,那么你需要一些不同的东西。
  • “更好”是什么意思?您的代码很容易理解,而空合并运算符可能不是。如果出现以下情况,您也可以使用短路:if (result.Data.Count > 0 && result.Data[0].AdditionalData != null)
  • 谁投票赞成关闭?这是一个完全有效的问题,很容易回答,没有任何意见。

标签: c# asp.net .net null


【解决方案1】:

一个使用System.Linq的班轮。

if (result.Data.FirstOrDefault()?.AdditionalDate != null)
{
 
} 

【讨论】:

    【解决方案2】:

    Null 条件可以与Any 一起工作,并短路下一次检查

    if (result?.Data?.Any() && result.Data[0]?.AdditionalData != null)
    {
        // to do
    }
    

    每个步骤的说明

    result?

    结果不为空吗?

    Data?

    如果是,Data不为空吗?

    Any()

    如果有,Data 是否有任何项目?

    Data[0]?

    如果是这样,第一项不为空吗? (我这里使用index的原因是因为你可能要检查第n项,所以FirstOrDefault可能限制太多了)

    AdditionalData != null

    如果是,附加数据不为空吗?

    当然,如果这些检查中的任何一个是不必要或多余的,您可以从链中删除特定检查(在空条件的情况下删除 ?)。在这里,所有检查都清楚地排在一行中,因此修改逻辑链很简单。

    【讨论】:

    • 投反对票,因为:假设 OP 代码有效,您的代码只需添加 3 个不必要的空条件运算符,并且两个 if 仅使用 && 重写。这几乎没有改善。
    • @Liero OP 从未检查过 Data 是否为空,所以要重新考虑该评论?
    • 但问题不在于如何检查数据或结果是否为空。也许他正在使用可为空的引用类型,所以他实际上知道它不会为空。在这个问题的上下文中并不重要。
    • 好的,我已经删除了反对票
    【解决方案3】:

    就像@Hans Killian 写的一样,尝试使用IEnumerables 的扩展名 在您的情况下,我认为 .ElementAtOrDefault(0)(或者如果您总是想使用索引 0,只需使用 .FirstOrDefault())在这里最适合您。

    if (result?.Data != null)
    {
        /// Expecting 'AdditionalData' is `string`
        if (!string.IsNullOrEmpty(result.Data.ElementAtOrDefault(0)?.AdditionalData))
        {
            Console.WriteLine("Null check working...");
        }
        else
        {
            Console.WriteLine("AdditionalData is null or empty!");
        }
    }
    else
    {
        Console.WriteLine("No data!");
    }
    

    可以在here找到完整的工作示例

    【讨论】:

    • if(result.Data.Any()) 不多余,因为您使用的是 OrDefaultElementAtOrDefault(0)
    • if(result.Data.Any()) 是多余的,因为您使用的是 OrDefault (ElementAtOrDefault(0)),它执行相同的检查但效率更高
    • @Liero 已更正。
    【解决方案4】:

    我认为拥有干净和良好代码的最佳方法是使用 FluentValidation。请注意以下代码sn-p:

    public class RegisterValidator : AbstractValidator<RegisterDTO>
    {
        public RegisterValidator()
        {
            RuleFor(a => a.PhoneNumber).NotNull().WithMessage(Utility.GetEnumTitlePersian(enmErrorMessage.InValidMobileNumber));
            RuleFor(a => a.PhoneNumber).NotEmpty().WithMessage(Utility.GetEnumTitlePersian(enmErrorMessage.InValidMobileNumber));
            RuleFor(a => a.PhoneNumber).MinimumLength(11).WithMessage(Utility.GetEnumTitlePersian(enmErrorMessage.InValidMobileNumber));
            RuleFor(a => a.PhoneNumber).MaximumLength(11).WithMessage(Utility.GetEnumTitlePersian(enmErrorMessage.InValidMobileNumber));
        }
    }
    

    以上代码是验证模型以检查 null、empty 等的示例,此代码必须在业务逻辑中检查验证:

    var validator = new RegisterValidator();
    var validatorResult = await validator.ValidateAsync(register);
    
    if (!validatorResult.IsValid)
        return BadRequest("", validatorResult.Errors[0].ToString());
    

    使用非常简单,非常干净。甚至可以通过错误列表进行多次检查并得到结果

    此链接为FluentValidation的网址

    【讨论】:

    • 您是否将答案发布到无效线程?
    • 我不明白你的意思!
    • 哦,对不起,起初我以为你的回答与这个问题无关。
    • 没问题,我尽力提供了一个非常全面完整的解决方案
    • @MajidGholipour 这个答案与这个问题完全无关。想在你的回答中添加一个处理实际问题的例子吗?
    【解决方案5】:

    您可以在 IEnumerable 上创建扩展方法并使用它

        public static bool HasValue<T>(this IEnumerable<T> source, int index)
        {
            if (source == null)
                return false;
    
            return source.Count() > index && source.ElementAt(index) != null;
        }
    
    // usage
    if(result.Data.HasValue(0))
    {
    }
    

    【讨论】:

    • 也许这应该可行,但这对我来说将是一项长期的努力。
    • 这将重复源两次。完全没有必要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2018-08-24
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多