1

我有两种方法几乎可以做同样的事情。他们得到一个List<XmlNode>基于 state OR state 和 schoolType 的数据,然后返回一个不同的有序的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

3 回答 3

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

使用学校和州节点的联合来检索区域节点:

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();
}
于 2012-10-15T15:24:38.150 回答
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();
}

你可以做到以下几点,但我想知道这是否是过度设计问题并产生调用两个Funcs 的开销。

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);
}
于 2012-10-15T15:28:49.077 回答
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);
}
于 2012-10-15T15:44:40.503 回答