2011-06-09 50 views
2

我有一個分層數據樹,它包含一個名爲DataNode的類的對象。如何提高這些linq語句的可讀性?

每個DataNode包含一個Attribute對象的集合。每個Attribute本質上是一個鍵/值對,並附有一些輔助方法。例如,有一種稱爲EqualsCodeIndex(x)的幫助方法,其與值的小集合x匹配到thisattribute並且返回truefalse。所有的鍵和值都是字符串,因爲整個事情都是基於文本文件中包含的鍵/值存儲。

爲了簡化訪問特定DataNode,有在DataTree類樹中的所有節點映射到一個唯一的代碼字典:

Dictionary<string, DataNode> Codes; 

所得的LINQ語句獲取到一個特定的Attribute值如下:

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

這是不是太糟糕,如果我只需要通過檢索代碼和代碼索引的一個或兩個屬性,但它不是那麼好,如果我個人有T ο檢索十個或更多。

爲了嘗試簡化聲明,並允許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); 

......這是更好的,但我有一種感覺,我失去了一些東西。


這種方法有問題嗎?有沒有更好,更清潔的方法我沒有想到,也許更好地使用索引器,或者一個流暢的接口?

+1

是不是跟着'.SingleOrDefault'跟'.Value'請求一個NRE? – 2011-06-09 20:41:15

+0

@Kirk:通過擴展方法封裝的更好理由。我已經解決了示例代碼中的問題,雖然最終結果看起來不像這樣。 – 2011-06-09 20:42:13

+0

你是什麼意思檢索二十或三十?創建20個新的不同變量? – svick 2011-06-09 20:49:45

回答

1

我想使它成爲一個方法有兩個參數看起來稍微好一點:

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

或者你可以創建一個包裝有一個索引:

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

我沒有直接回答你的整個問題,但對「這種方法的問題」一節我有一個建議。

SingleOrDefault()之後要小心地鏈接語句,因爲它可能會返回null。如果你完全確定它會始終有一個單一的價值,也許只需撥打Single()並處理錯過的預期,而不是更通用的NullReferenceException

編輯 在寫上述文章時,您做了相同的更改。繼續...

1

你有沒有考慮建立一個0123T 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"); 

編輯:從數據管理部改爲的Datatree ...

+0

由於'DataNode'不擁有'Codes'字典,因此這不起作用。 'DataTree'確實。但是它*可以通過修改成爲DataTree對象的普通方法。 – 2011-06-09 21:14:09

+0

我在尋找,並且我將dataTree作爲DataNode的一個實例。我編輯了我的回覆,並認爲這會做你想做的事。 – 2011-06-09 21:15:47

+0

它很接近,但我不認爲它需要是一個擴展方法,因爲我必須在任何情況下引用樹。我已經在我原來的問題中提出了一個擴展方法解決方案,所以我認爲你和@svick所說的是,只是將技術移到我的對象層次結構中。 – 2011-06-09 21:20:59