接受委托函数的扩展方法

本文关键字:方法 扩展 函数 接受委托 | 更新日期: 2023-09-27 18:36:31

我仍在尝试将我的头包裹在委托函数和扩展方法上。我已经为DropDownList创建了一个扩展方法。我想在我的扩展方法中传递要调用的函数,但我收到错误Argument type 'IOrderedEnumerable<KeyValuePair<string,string>>' is not assignable to parameter type 'System.Func<IOrderedEnumerable<KeyValuePair<string,string>>>'

public static class DropDownListExtensions {
    public static void populateDropDownList(this DropDownList source, Func<IOrderedEnumerable<KeyValuePair<string, string>>> delegateAction) {
        source.DataValueField = "Key";
        source.DataTextField = "Value";
        source.DataSource = delegateAction;
        source.DataBind();
    }
}

被这样称呼...

myDropDownList.populateDropDownList(getDropDownDataSource());

getDropDownDataSource signature...

protected IOrderedEnumerable<KeyValuePair<string,string>> getDropDownDataSource() {
    StateInfoXmlDocument stateInfoXmlDocument = new StateInfoXmlDocument();
    string schoolTypeXmlPath = string.Format(STATE_AND_SCHOOL_TYPE_XML_PATH, StateOfInterest, SchoolType);
    var nodes = new List<XmlNode>(stateInfoXmlDocument.SelectNodes(schoolTypeXmlPath).Cast<XmlNode>());
    return nodes.Distinct().Select(x => new KeyValuePair<string, string>(x.Attributes["area"].Value, x.Attributes["area"].Value)).OrderBy(x => x.Key);
}

接受委托函数的扩展方法

调用时,您应该在getDropDownDataSource后删除()

myDropDownList.populateDropDownList(getDropDownDataSource);

编辑:方法组可以隐式转换为具有兼容签名的委托。在这种情况下,getDropDownDataSource匹配Func<IOrderedEnumerable<KeyValuePair<string,string>>>的签名,因此编译器会为您应用转换,从而有效地执行

Func<IOrderedEnumerable<KeyValuePair<string,string>>> func = getDropDownDataSource;
myDropDownList.populateDropDownList(func);

是的,在您调用myDropDownList.populateDropDownList(getDropDownDataSource()); getDropDownDataSource()的行中,它会恢复IOrderedEnumerable<KeyValuePair<string,string>>。 因此,编译器说您无法将IOrderedEnumerable<KeyValuePair<string,string>>转换为 Func。 要传递 Func,您可以删除括号,以便像下面这样传递指针myDropDownList.populateDropDownList(getDropDownDataSource);或者可以直接传递数据源:

myDropDownList.populateDropDownList(() => {
    StateInfoXmlDocument stateInfoXmlDocument = new StateInfoXmlDocument();
    string schoolTypeXmlPath = string.Format(STATE_AND_SCHOOL_TYPE_XML_PATH, StateOfInterest, SchoolType);
    var nodes = new List<XmlNode>(stateInfoXmlDocument.SelectNodes(schoolTypeXmlPath).Cast<XmlNode>());
    return nodes.Distinct().Select(x => new KeyValuePair<string, string>(x.Attributes["area"].Value, x.Attributes["area"].Value)).OrderBy(x => x.Key);
}

但这有点丑。