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?
I think that making it into one method with two parameters would look slightly better:
Or you could create a wrapper with an indexer: