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

发布于 2024-11-14 21:44:57 字数 1453 浏览 2 评论 0原文

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

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

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

Dictionary<string, DataNode> Codes;

:特定 Attribute 值如下所示:

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);

...哪个更好,但我有一种感觉,我错过了一些东西。


这种方法有问题吗?有没有一种我没有想到的更好、更干净的方法,也许可以更好地利用索引器,或者也许是一个流畅的界面?

I have a hierarchical data tree containing objects of a class called DataNode.

Each DataNode contains a collection of Attribute objects. Each Attribute is essentially a key/value pair, with some helper methods attached. For example, there is a helper method called EqualsCodeIndex(x) that matches a small collection x of int values to this attribute and returns true or false. All keys and values are strings, because the whole thing is based on a key/value store contained in a text file.

To simplify access to a particular DataNode, there is a dictionary in the DataTree class that maps all of the nodes in the tree to a unique code:

Dictionary<string, DataNode> Codes;

The resulting Linq statement to get to a specific Attribute value looks like this:

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

This is not too bad if I only have to retrieve one or two attributes by code and code index, but it's not so good if I have to retrieve ten or more.

To attempt to simplify the statement, and allow for the possibility of EqualsCodeIndex returning false for all attributes in the collection, I added an extension method:

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;
}

This simplifies the original linq statement down to:

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

...which is better, but I have a feeling I'm missing something.


Are there problems with this approach? Is there a better, cleaner approach I haven't thought of, maybe making better use of indexers, or perhaps a fluent interface?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝眼泪 2024-11-21 21:44:58

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

请小心 SingleOrDefault() 之后的链接语句,因为它可能会返回 null。如果您绝对确定它始终具有单个值,也许只需调用 Single() 并在发生时处理错过的期望,而不是更通用的 NullReferenceException

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

I don't have a direct answer to your whole question, but to the "problems with this approach" section I have a suggestion.

Be careful chaining statements after a SingleOrDefault() as it could potentially return null. If you are absolutely sure it will always have a single value, maybe just call Single() and deal with that missed expectation should it ever happen instead of a more generic NullReferenceException.

EDIT
While writing the above post you made the same changes. Carry on...

疯狂的代价 2024-11-21 21:44:58

您是否考虑过构建一个扩展方法数据树?

这样

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...

Have you considered building an Extension Method of DataTree?

like

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

      }
   }

This will allow you to reuse "FetchByAttribute" at will as:

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

Edited: changed from DataNode to DataTree...

冰雪之触 2024-11-21 21:44:57

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

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

或者您可以创建一个带有索引器的包装器:

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

I think that making it into one method with two parameters would look slightly better:

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

Or you could create a wrapper with an indexer:

CodesWrapper[@"R-1\CHE", codeIndex]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文