2012-10-15 141 views
1

我有兩種方法幾乎可以做同樣的事情。他們根據州OR狀態和schoolType獲得List<XmlNode>,然後返回一個明確的,有序的IEnumerable<KeyValuePair<string,string>>。我知道它們可以被重構,但我正努力確定該方法返回時linq語句的參數應該是什麼類型(每個方法的最後一行)。將兩種方法重構爲一個

我感謝您的幫助提前。

private IEnumerable<KeyValuePair<string, string>> getAreaDropDownDataSource() { 
    StateInfoXmlDocument stateInfoXmlDocument = new StateInfoXmlDocument(); 
    string schoolTypeXmlPath = string.Format(STATE_AND_SCHOOL_TYPE_XML_PATH, StateOfInterest, ConnectionsLearningSchoolType); 
    var schoolNodes = new List<XmlNode>(stateInfoXmlDocument.SelectNodes(schoolTypeXmlPath).Cast<XmlNode>()); 
    return schoolNodes.Select(x => new KeyValuePair<string, string>(x.Attributes["idLocation"].Value, x.Value)).OrderBy(x => x.Key).Distinct(); 
} 

private IEnumerable<KeyValuePair<string, string>> getStateOfInterestDropDownDataSource() { 
    StateInfoXmlDocument stateInfoXmlDocument = new StateInfoXmlDocument(); 
    string schoolTypeXmlPath = string.Format(SCHOOL_TYPE_XML_PATH, ConnectionsLearningSchoolType); 
    var schoolNodes = new List<XmlNode>(stateInfoXmlDocument.SelectNodes(schoolTypeXmlPath).Cast<XmlNode>()); 
    return schoolNodes.Select(x => new KeyValuePair<string, string>(x.Attributes["stateCode"].Value, x.Attributes["stateName"].Value)).OrderBy(x => x.Key).Distinct(); 
} 

回答

4

提取節點檢索以分離方法/屬性。我還建議具有抽取學校和狀態節點不同的屬性/方法:學校和狀態節點的

private List<XmlNode> GetNodes(string xPath) 
{ 
    XmlDocument stateInfoXmlDocument = new XmlDocument(); 
    return new List<XmlNode>(stateInfoXmlDocument.SelectNodes(xPath) 
               .Cast<XmlNode>()); 
} 

private List<XmlNode> SchoolNodes 
{ 
    get { return GetNodes(String.Format(SCHOOL_PATH, LearningSchoolType)); } 
} 

private List<XmlNode> StateNodes 
{ 
    get { return GetNodes(String.Format(STATE_PATH, StateOfInterest)); } 
} 

使用union檢索區域節點:

private IEnumerable<KeyValuePair<string, string>> GetAreaDropDownDataSource() 
{ 
    return SchoolNodes.Union(StateNodes) 
      .Select(x => new KeyValuePair<string, string>(x.Attributes["idLocation"].Value, x.Value)) 
      .OrderBy(x => x.Key) 
      .Distinct(); 
} 

private IEnumerable<KeyValuePair<string, string>> GetStateOfInterestDropDownDataSource() 
{ 
    return SchoolNodes 
     .Select(x => new KeyValuePair<string, string>(x.Attributes["stateCode"].Value, x.Attributes["stateName"].Value)) 
     .OrderBy(x => x.Key) 
     .Distinct(); 
} 

你也可以使用類型的不同選擇Func<XmlNode, KeyValuePair<string, string>>並傳遞給方法,該方法將創建數據源:

private IEnumerable<KeyValuePair<string, string>> GetDropDownDataSource(
     List<XmlNode> nodes, 
     Func<XmlNode, KeyValuePair<string, string>> selector) 
{ 
    return nodes.Select(selector) 
       .OrderBy(x => x.Key) 
       .Distinct(); 
} 
+0

'schoolTypeXmlPath'是每個兩種方法在OP ... –

+0

@lc的不同。謝謝,沒有注意到。從屬性更改爲方法 –

+0

謝謝,這裏有一些非常棒的點子:) – bflemi3

2

我感覺,而他們都返回一個IEnumerable<KeyValuePair<string,string>>這些方法在內容上在語義上有很大不同。因此,我會保留這兩種方法,並只提取重複的代碼到第三個。喜歡的東西:

private List<XmlNode> getSchoolNodes(string xmlPath, params object[] values) 
{ 
    StateInfoXmlDocument stateInfoXmlDocument = new StateInfoXmlDocument(); 
    string schoolTypeXmlPath = string.Format(xmlPath, values); 
    return new List<XmlNode>(stateInfoXmlDocument.SelectNodes(schoolTypeXmlPath).Cast<XmlNode>()); 
} 

private IEnumerable<KeyValuePair<string, string>> getAreaDropDownDataSource() { 
    var schoolNodes = getSchoolNodes(STATE_AND_SCHOOL_TYPE_XML_PATH, StateOfInterest, ConnectionsLearningSchoolType);   
    return schoolNodes.Select(x => new KeyValuePair<string, string>(x.Attributes["idLocation"].Value, x.Value)).OrderBy(x => x.Key).Distinct(); 
} 

private IEnumerable<KeyValuePair<string, string>> getStateOfInterestDropDownDataSource() { 
    var schoolNodes = getSchoolNodes(SCHOOL_TYPE_XML_PATH, ConnectionsLearningSchoolType); 
    return schoolNodes.Select(x => new KeyValuePair<string, string>(x.Attributes["stateCode"].Value, x.Attributes["stateName"].Value)).OrderBy(x => x.Key).Distinct(); 
} 

你可以去儘可能下面,但我不知道這是過度設計的問題,併產生額外開銷調用兩個Func秒。

private IEnumerable<KeyValuePair<string, string>> getSchoolNodeDataSource(Func<XmlNode, string> keyFunc, Func<XmlNode, string> valueFunc, string xmlPath, params object[] values) 
{ 
    StateInfoXmlDocument stateInfoXmlDocument = new StateInfoXmlDocument(); 
    string schoolTypeXmlPath = string.Format(xmlPath, values); 
    var schoolNodes = new List<XmlNode>(stateInfoXmlDocument.SelectNodes(schoolTypeXmlPath).Cast<XmlNode>()); 
    return schoolNodes.Select(x => new KeyValuePair<string, string>(keyFunc(x), valueFunc(x))).OrderBy(x => x.Key).Distinct(); 
} 

private IEnumerable<KeyValuePair<string, string>> getAreaDropDownDataSource() { 
    return getSchoolNodeDataSource(x => x.Attributes["idLocation"].Value, x => x.Value, 
     STATE_AND_SCHOOL_TYPE_XML_PATH, StateOfInterest, ConnectionsLearningSchoolType);   
} 

private IEnumerable<KeyValuePair<string, string>> getStateOfInterestDropDownDataSource() { 
    return getSchoolNodeDataSource(x => x.Attributes["stateCode"].Value, x => x.Attributes["stateName"].Value, 
     SCHOOL_TYPE_XML_PATH, ConnectionsLearningSchoolType); 
} 
0
private IEnumerable<KeyValuePair<string, string>> Foo(
    string schoolTypeXmlPath, 
    Func<T, string> keySelector, 
    Func<T, string> valueSelector) 
{ 
    return (
     from XmlNode x in StateInfoXmlDocument().SelectNodes(schoolTypeXmlPath) 
     orderby x.Key 
     select new KeyValuePair<string, string>(keySelector(x), valueSelector(x))) 
     .Distinct() 
} 

private IEnumerable<KeyValuePair<string, string>> getAreaDropDownDataSource() { 
    return Foo(
     string.Format(STATE_AND_SCHOOL_TYPE_XML_PATH, StateOfInterest, ConnectionsLearningSchoolType), 
     x => x.Attributes["idLocation"].Value, 
     x => x.Value); 
} 

private IEnumerable<KeyValuePair<string, string>> getStateOfInterestDropDownDataSource() { 
    return Foo(
     string.Format(SCHOOL_TYPE_XML_PATH, ConnectionsLearningSchoolType), 
     x => x.Attributes["stateCode"].Value, 
     x => x.Attributes["stateName"].Value); 
}