如何提高这些linq语句的可读性?

时间:2011-06-09 20:37:49

标签: c# linq refactoring

我有一个分层数据树,其中包含一个名为DataNode的类的对象。

每个DataNode都包含Attribute个对象的集合。每个Attribute本质上是一个键/值对,附加了一些辅助方法。例如,有一个名为EqualsCodeIndex(x)的辅助方法,它将xint个值的小集合与this attribute匹配,并返回truefalse。所有键和值都是字符串,因为整个事物都基于文本文件中包含的键/值存储。

为了简化对特定DataNode的访问,DataTree类中有一个字典,它将树中的所有节点映射为唯一代码:

Dictionary<string, DataNode> Codes;

获得特定Attribute值的结果Linq语句如下所示:

string AttributeValue = dataTree
    .Codes[@"R-1\CHE"]
    .Attributes
    .Single(x => x.EqualsCodeIndex(parentAttribute.CodeIndex))
    .Value.Trim();

如果我只需要通过代码和代码索引检索一个或两个属性,这不是太糟糕,但如果我必须检索十个或更多,那么就不那么好。

为了尝试简化语句,并允许EqualsCodeIndex为集合中的所有属性返回false,我添加了一个扩展方法:

public static string AttributeValueMatching
    (this KeyValuePair<string, DataNode> pair, List<int> codeIndex)
{
    var attribute = pair.Value.Attributes
        .Single(x => x.EqualsCodeIndex(codeIndex))

    return attribute == null ? string.Empty : value;
}

这将原来的linq语句简化为:

string attributeValue
    = dataTree.Codes[@"R-1\CHE"].AttributeValueMatching(codeIndex);

......哪个更好,但我有一种感觉我错过了什么。


这种方法有问题吗?是否有一种更好,更清洁的方法,我没有想到,可能更好地使用索引器,或者可能是一个流畅的界面?

3 个答案:

答案 0 :(得分:1)

我没有直接回答你的整个问题,但对于“这种方法的问题”部分,我有一个建议。

SingleOrDefault()之后小心链接语句,因为它可能会返回null。如果您完全确定它总是只有一个值,那么可以只调用Single()并处理错过的期望,如果它发生而不是更通用的NullReferenceException

修改的 在撰写上述帖子时,您进行了相同的更改。继续...

答案 1 :(得分:1)

我认为将它变成一个带有两个参数的方法看起来会稍微好一些:

Codes.AttributeValueMatching(@"R-1\CHE", codeIndex)

或者您可以使用索引器创建包装器:

CodesWrapper[@"R-1\CHE", codeIndex]

答案 2 :(得分:1)

您是否考虑过构建 Extension Method 的DataTree?

public static class DataTreeExtensions
   {
      public static string FetchByAttribute(this DataTree d, string Attribute)
      {
         string AttributeValue = d
                         .Codes[Attribute]
                         .Attributes
                         .Single(x => x.EqualsCodeIndex(parentAttribute.CodeIndex))
                         .Value.Trim();

            return AttributeValue

      }
   }

这将允许您随意重用“FetchByAttribute”:

string myValue = myTree.FetchByAttribute(@"R-1\CHE");

已编辑:已从DataNode更改为DataTree ...