2016-09-01 2 views
0

У меня есть приложение C#, над которым я хочу работать. В основном это командная работа, и я имею в виду, что пользователь вводит какую-то команду, и приложение просто выполняет какую-то задачу.Создание командного приложения без обширного использования If-Else Statement

Например: Пользователь может ввести команду, например getdate, приложение считывает эту команду и просто отображает дату.

ПРИМЕЧАНИЕ: Его решение будет основано на консоли, но моя проблема: фактическое приложение имеет около 80-100 команд, и мой вопрос заключается в том, как прочитать эту команду, не полагаясь на некоторое подробное выражение if-else, чтобы проверить, какая команда была введена в

Есть ли способ, которым я могу это сделать, или мне просто нужно пойти с некоторыми длинными операторами if-else.

+2

Это не обязательно будет менее многословным, но вы можете посмотреть на использовании 'switch' заявление. Возможно, вы сможете использовать что-то вроде словаря ', но я не уверен, как вы могли бы подключить это к логике логического кода элегантным способом, если только значения не были' Func' какого-либо типа. – Tim

ответ

0

Вы можете использовать переключатель, или вы можете создать словарь с вопросом в качестве ключа и команды в качестве значения. Предложите, чтобы вы делали ToLower() на обоих ключах и входах, чтобы сделать регистр нечувствительным к регистру, так как полагаться на то, что пользователь будет правильно набирать, будет сложно.

private Dictionary<string,object> commandList = new Dictionary<string,object>(); 
private void processCommand(){ 
commandList.Add("showdate",DateTime.Now); 
string command = Console.ReadLine(); 
if(command.Length>0){ 
    if(commandList.ContainsKey(command); 
     object o = commandList[command.ToLower()]; 
     //do something 
    } 
} 
} 
+0

См. Http://stackoverflow.com/questions/4233536/c-sharp-store-functions-in-a-dictionary для хранения функций. –

2

Используйте простую форму Command Pattern и некоторую коллекцию команд.

Простой способ построить это будет:

public class MyApp 
{ 
    private readonly Dictionary<string, Action> _commands = new Dictionary<string, Action>(); 

    public static void Main() 
    { 
     var program = new MyApp(); 
     // Run Console Stuff 
    } 

    public MyApp() 
    { 
     SetupCommands(); 
    } 

    public void SetupCommands() 
    { 
     _commands.Add("PrintDate",() => Console.WriteLine(DateTime.Now)); 
     _commands.Add("PrintMaxOf3And7",() => Console.WriteLine(Math.Max(3, 7))); 
    } 

    public void ExecuteCommand(string commandName) 
    { 
     _commands[commandName].Invoke(); 
    } 
} 
2

Использование делегата:

public delegate void CommandDelegate(string input); 

public Dictionary<string, CommandDelegate> Commands { get; set; } 

/// usage 
public void InitCommands() 
{ 
    Commands.Add("showdata", (input) => Console.WriteLine(....)); 
    ... // other commands 
} 

public void ExecuteCommand(string userInput) 
{ 
    var firstWord = userInput.Substring(0, userInput.IndexOf(" ")); 
    if (Commands.ContainsKey(firstWord)) 
    { 
     var command = Commands[firstWord]; 
     command(userInput); 
    } 
} 
3

Есть несколько вариантов, вы можете взять с собой:

  • Вы могли бы hastable команд, которые соответствуют типу для инициализации.

    Dictionary<string, Type> Где типы карт для класса, который вы инициализируете.

  • Использование Reflection непосредственно на карту команду на объект для инициализации (с помощью имени объекта или атрибута.

    [Command(Name = "update")] 
    public class RunUpdates : ICommand { 
    
    } 
    
    [Command(Name = "restart")] 
    public class RestartServer : ICommand { 
    
    } 
    

Затем с помощью отражения, чтобы найти объект, который реализует ICommand с соответствующим атрибутом имя команды.

1

Вы можете использовать словарь, который использует string как ключи и методы (как Action, Func, так и пользовательский делегат) в качестве значения, тогда вам просто нужно использовать вход пользователя и использовать его чтобы получить соответствующее действие. Если в команде могут быть такие параметры, как этот command param1, используйте string.Split, чтобы отделить команду от параметра, затем используйте командную строку как ключ, а при выполнении метода передайте другую строку в качестве параметра (в зависимости от типа данных параметра чтобы, возможно, придется разобрать параметр команды из строки к чему-то еще)

код будет выглядеть следующим образом:

Использование Func:

Примечание: Func требует, по меньшей мере, один параметр и возвращаемое значение.

void Main() 
{ 
    public Dictionary<string, Func<string, int>> commands = 
            new Dictionary<string, Func<string, int>>(); 
    commands.Add("getdate", GetDate); 

    Console.WriteLine("Enter a command"); 
    string input = Console.ReadLine(); //<-- Try typing "getdate" 
    commands[input].Invoke(); 
} 

public int GetDate(string someParameter) 
{ 
    Console.WriteLine(DateTime.Today); 
    return 0; 
} 

Использование Действие:

Примечание: Action требует, по меньшей мере, один параметр.

void Main() 
{ 
    public Dictionary<string, Action<string>> commands = new Dictionary<string, Action>(); 
    commands.Add("getdate", GetDate); 

    Console.WriteLine("Enter a command"); 
    string input = Console.ReadLine(); //<-- Try typing "getdate" 
    commands[input].Invoke(); 
} 

public void GetDate(string someParameter) 
{ 
    Console.WriteLine(DateTime.Today); 
} 

Использование пользовательского делегата:

public delegate double YourDelegate(string param); 

void Main() 
{ 
    public Dictionary<string, YourDelegate> commands = 
             new Dictionary<string, YourDelegate>(); 
    commands.Add("getdate", GetDate); 

    Console.WriteLine("Enter a command"); 
    string input = Console.ReadLine(); //<-- Try typing "getdate" 
    commands[input].Invoke(); 
} 

public double GetDate(string someParameter) 
{ 
    Console.WriteLine(DateTime.Today); 
    return 0.0; 
} 
+0

Ни «Func», ни «Action» не требуют как минимум 1 параметра. Оба работают отлично, без каких-либо параметров. Однако в этом конкретном случае, вероятно, нужно передать оставшуюся команду в виде строки. – Phil1970

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