0

好吧,我有以下查询,用于搜索包含用户填写的文本的 LIST。

它只是一个在下面所有这些字段中搜索的文本框,它正在工作,但是当这些字段之一为空时,它会引发空引用异常,我该如何避免这种情况?

List<REP_MEDIDORDISPLAY> SearchFiltered = new List<REP_MEDIDORDISPLAY>();
            if (filter != String.Empty)
            {
                SearchFiltered.Clear();
                foreach (String Item in filter.Split(';').ToList<String>())
                {
                    SearchFiltered.AddRange(Medidores.Where(x => x.Data_TOI.Contains(Item.Trim()) ||
                        x.Elemento.ToUpper().Contains(Item.Trim()) ||
                        x.Fase.ToUpper().Contains(Item.Trim()) ||
                        x.ID.ToUpper().Contains(Item.Trim()) ||
                        x.KdKe.ToUpper().Contains(Item.Trim()) ||
                        x.N_Equipamento.ToUpper().Contains(Item.Trim()) ||
                        x.Status.ToUpper().Contains(Item.Trim()) ||
                        x.Tensao.ToUpper().Contains(Item.Trim())));

                }
            }

我希望你们能帮助我。谢谢。

4

4 回答 4

2

通过首先检查null

(x.Elemento != null && x.Elemento.ToUpper().Contains(Item.Trim())) ||
// etc

当然,您还应该Item.Trim()只计算一次并将该值重复用于所有测试,而不是修剪与字段一样多的次数。

于 2013-10-07T13:46:12.193 回答
2

您可以为每个属性添加空检查。例子:

x.Fase.ToUpper().Contains(Item.Trim()) || 

 (x.Fase != null && x.Fase.ToUpper().Contains(Item.Trim())) ||
于 2013-10-07T13:46:23.347 回答
0

也许你应该引入类似空对象的东西。这个对象是空的,因此在每次查询它时总是返回 false。

如果您为该对象上的每个属性实现 nullchecks,您的代码将随着时间的推移而腐烂。你会过得很糟糕。

于 2013-10-07T14:07:44.173 回答
0

有很多方法可以做你正在做的事情,也许有些更优雅。

一种简单的方法是覆盖序列ToString中对象中的方法Medidores并将其用于比较。

像这样的东西:

class Medidor {
    ... properties

    public override string ToString() {
        return Data_TOI + Elemento ... etc
    }
}

然后你可以与之比较。

SearchFiltered.AddRange(
  Medidores.Where(x => 
    x.ToString()
     .IndexOf(Item.Trim(), 0, StringComparison.InvariantCultureIgnoreCase) != -1
);

我正在使用IndexOf它,因为它有一个过载StringComparison.InvariantCultureIgnoreCase,它忽略了大小写等。

我认为这种方法比您现在拥有的方法更受欢迎的原因是Meridor对象本身负责ToString方法中包含哪些字段。也许它可以提高可读性和可维护性。

于 2013-10-07T14:10:24.373 回答