2012-10-15 92 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); 
}