2012-06-06 2 views
1

Я все еще пытаюсь обернуть голову функциями делегата и методами расширения. Я создал метод расширения для 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 подпись ...

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

ответ

6

Вы должны удалить () после getDropDownDataSource при вызове:

myDropDownList.populateDropDownList(getDropDownDataSource); 

EDIT: группы методов могут быть неявно преобразованы в делегаты с совместимой сигнатурой. В этом случае getDropDownDataSource соответствует подписи Func<IOrderedEnumerable<KeyValuePair<string,string>>> поэтому компилятор применяет преобразование для вас, эффективно делать

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

lol, да, это было. Теперь он компилируется. – bflemi3

+0

И, возможно, добавить его в 'source.DataSource = delegateAction', что делает его' source.DataSource = delegateAction() ' –

+1

или использовать синтаксис lamba' myDropDownList.populateDropDownList (() => getDropDownDataSource()); ' – asawyer

0

Да, в строке myDropDownList.populateDropDownList(getDropDownDataSource()); вы звоните getDropDownDataSource(), которые returs 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); 
} 

Но это немного некрасиво. :-)

Смежные вопросы