2017-02-01 3 views
0

У меня есть две функции с разной функциональностью, и я хочу назвать их на основе некоторого значения. без if else или блока блокировки коммутатора. как я естьВызов двух разных функций, основанных на некотором значении с использованием делегата

Dictionary<string, string> intentMap = new Dictionary<string, string>(); 
intentMap.Add("rootIntent", "TicketbookingInformation"); 
intentMap.Add("rootIntent", "OrderInformation"); 

and i have two function 

public bool BookTicket() 
{ 
    // to do 
} 

public bool BookOrder() 
{ 
    // to do 
} 

Я хочу, чтобы переключить эти функции, если intentMap имеет TicketbookingInformation затем вызвать метод BookTicket или если intentMap имеет OrderInformation затем вызвать метод BookOrder.

Я хочу сделать общий путь с использованием deleagtes, так что в будущем, если у меня есть еще несколько вариантов использования (новый метод), поэтому я могу использовать ту же функцию, не изменяя многое.

+0

С учетом того, что это, вероятно, не производственный код, я по-прежнему чувствую необходимость указать, что добавление двух значений с одним и тем же ключом к «Словарю», как вы делаете, собирается бросить «ArgumentException». – Abion47

ответ

1

Используйте другой словарь, на этот раз типа <string, Func<bool>:

var delegateMap = new Dictionary<string, Func<bool>>() 
{ 
    { "TicketBookingInformation", BookTicket }, 
    { "OrderInformation", BookOrder } 
}; 

foreach (var intent in intentMap) 
{ 
    bool result = delegateMap[intent.Value](); 
} 
+0

Было несколько проблем с 'foreach', я исправил их, пожалуйста, посмотрите –

+0

@ un-lucky Они не были проблемами. Я зацикливал на «aimMap», введенный в вопросе OP, и вызывая «Func» в словаре делегатов, который соответствует значению «KeyValuePair». – Abion47

+0

На самом деле вход Op был неправильным, он содержит тот же ключ для двух разных элементов, что недопустимо. Так что вашего ответа достаточно, чтобы получить то, что он ожидал. –

0

Я не буду отвечать на ваш вопрос напрямую. @ Abion47 ответил отлично, я бы ответил на то же самое.

Но я думаю, что у вас есть два словаря, у которых есть токен, а другой, имеющий делегат, более неясен, тогда есть единственный метод для отправки результата.

Вот моя точка с небольшим кодом.

Эта версия словаря.

var intentMap = new Dicionary<string, string>(); 

var delegateMap = new Dictionary<string, Func<bool>>(); 
delegate.Map.Add("TicketbookingInformation", BookTicket); 
delegateMap.Add("OrderInformation", BookOrder); 

Тогда использование будет что-то вроде этого

var token = ...; 
if(intentMap.ContainsKey(token)) 
{ 
    var delegateToken = intenMap[token]; 
    if(delegateMap.ContainsKey(delegateToken)) 
    { 
     var delegatedMethod = delegateMap(delegateToken); 

     return delegatedMethod(); 
    } 
} 

Поэтому добавление нового маркеров и делегата средства расширения словарей и я не могу видеть, как это отличается, тем расширение переключателя заявления.

Вторая версия, которая, как я думаю, будет достаточно общей и не нуждается в слишком большой модификации, когда используется будет что-то вроде этого.

Сначала я предлагаю использовать "TicketbookingInformation" и "OrderInformation" в качестве типа перечисления. Таким образом, с помощью оператора switch будет полезен компилятор, если у вас есть недостающий код для обработки. Это, конечно, применимо, если вы знаете заранее все возможные значения;]

bool PredicateDispatch(DelegateToken token) 
{ 
     switch(token) 
     { 
      DelegateToken.TicketbookingInformation: return BookTicket(); 
      DelegateToken.OrderInformation: return BookOrder() 
     } 

} 

таким образом, что вам нужно будет продлить этот единственный метод для обработки новых маркеров. Это более читаемый подход, и вы не теряете ничего по сравнению со словарной версией. Поэтому я сделаю это так. Если у вас нет, конечно, более сложного кода, и ваш пример более упрощен;]

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