在条件编码中太多"&&#;;" s。更好的代码?

时间:2017-06-05 23:51:19

标签: c# linq

以下代码按预期工作,但似乎不够优雅。

.Where(x =>     x.Attributes().Contains(x.Attribute("Quick"))
            && !x.Attributes().Contains(x.Attribute("Brown"))
            && !x.Attributes().Contains(x.Attribute("Fox"))
            && !x.Attributes().Contains(x.Attribute("Jumps"))
            && !x.Attributes().Contains(x.Attribute("Lazy"))
            && !x.Attributes().Contains(x.Attribute("Dogs")))

如您所见,我正在检查是否

  • XElement只有一个属性
  • 此属性具有指定的名称

[编辑]我的目的是......我想确保元素只有一个属性。我只是说" Quick"在这种情况下的属性。我知道计数风格,计数不区分它的名字。[/ Edit]

[Edit2]我想要元素,只要它有sigle属性,没有别的。[/ Edit2]

[EDIT3]" X"是一个元素,例如..

<mySeg Quick="1" Brown="Two" Fox="None" Jumps="2016_En" Lazy="100" Dogs="Source">  //  I do not want this XElement

<mySeg Quick="2" Brown="Ten">  //  Nah.

<mySeg Quick="3">  // yes, this is one I'm looking for.

[EDIT3]

[Edit4] 我想,我必须使用这个。实际上,这是我在这篇文章之前使用的那个。我一眼就好了。

x.Attributes().Contains(x.Attribute("Quick")) && x.Attributes().Count() == 1 //thanks Ryan

[Edit4]

2 个答案:

答案 0 :(得分:7)

如果你想确保它只包含一个属性列表,并且你可以创建你关心的属性列表,你可以将它与你正在检查的对象相交,看看交集是否是只有一个项目:

var attributesICareAbout = new List<Attribute>
{
    AllAttributes.Attribute("Quick"),
    AllAttributes.Attribute("Brown"),
    AllAttributes.Attribute("Fox"),
    AllAttributes.Attribute("Jumps"),
    AllAttributes.Attribute("Lazy"),
    AllAttributes.Attribute("Dogs")
};

// To get all items that have only a single attribute from our list and no others:
.Where(x => x.Attributes().Intersect(attributesICareAbout).Count == 1);

获取具有特定属性但没有其他属性的项目:

// To get all the items who have only a single "Quick" attribute:
.Where(x => x.Attributes().Count(a => a == AllAttributes.Attribute("Quick")) == 1);

答案 1 :(得分:0)

首先是光泽,你正在测试

  1. 存在特定项目
  2. none 存在一组其他项目
  3. 具体来说,您正在寻找一种简洁的方式来表达“没有这些”。

    鲁弗斯几乎回答了这个问题。使用他的方法设置列表。

    var exclusions = new string[] { "Brown", "Fox" , "Jumps", "Lazy", "Dogs" };
    

    现在你可以测试整套的缺席。请记住,“没有”与“不是任何”相同。我们将一组属性名称与排除集相交,并使用!.Any()检查它是否为空。

    .Where(x => x.Attributes().Contains(x.Attribute("Quick"))
      && !a.Attributes().Select(a => a.Name).Intersect(exclusions).Any())
    

    然而

    您澄清了

    的要求
    • XElement只有一个属性
    • 此属性具有特定名称

    因为你已经把“Ryan”归功于这个更简单问题的明显解决方案,所以我会停下来。

    您正在进行基于集合的比较。这是一些功课。

    Join as a lambda expression很乱。我更喜欢连接的内联语法。

    您可能还会发现,您可以将Count与Where结合使用这一事实很有用 - Count可以采用解析为布尔值的lambda表达式,就像Where一样,结果就是满足条件的项目数。您可以使用它来计算单个复合条件下的几个不同维度。