2016-08-19 5 views
1

У меня есть программа, которая должна выполнять функции acording к Enum и мне интересно, если есть другой способ, чем это:C# Действие/Список функций

enum FunctionType 
{ 
Addition = 0, 
Substraction = 1, 
Mutiplication = 2, 
Division = 3 
} 
void ExecuteFunction(FunctionType Function) 
{ 
    switch(Function) 
    { 
    case FunctionType.Addition: Addition(); 
    break; 
    case FunctionType.Substraction: Subsctration(); 
    break;  
    ... 
    default: ... 
    } 
} 

(Это не код я «Я использую это, это просто представление того, что я хочу делать». Этот подход должен работать нормально, но что происходит, когда у вас гораздо больше функций? Я не хочу иметь 50 линейных переключателей. Так что я хочу знать, если есть способ, чтобы упростить его, что-то вроде этого, может быть:

enum FunctionType : Action 
{ 
Addition = new Action(Addition); 
Substraction = new Action(Substraction); 
.... 
} 
void ExecuteFunction(FunctionType Function) 
{ 
(Action)Function.Invoke(); 
} 

Нет переключателя не требуется, и что может быть 50 строк превращаются в 1 строку. Но это невозможно сделать, только числовые типы используются как перечисления. Я думаю, что возможно иметь List<T> действий, но для этого потребуется добавить каждое действие в список во время выполнения.

EDIT: Я нашел в исходном коде способ, которым это делается, но я не могу это понять. Это то, что я получаю: Они создают обычай Attribute, содержащий string (название метода) и на методах, которые они делают:

[CustomAtrribute("name")] 
void Method() 
{  
} 

Тогда я не знаю, как это называется по его имени, я угадайте какое-то отражение, бу, я не знаю, как найти информацию об этом.

EDIT2: Я нашел способ, которым я хочу это сделать. Я добавлю интерфейс с функцией, а затем реализую этот интерфейс с кодом внутри функции и использую Dictionary<Enum, Interface> для его вызова. Я не знаю. Если я должен ответить на свой вопрос, так или иначе, спасибо всем, кто помог мне.

+4

Ну вы могли бы иметь 'Dictionary ' ... но опять же, вы должны построить его во время выполнения. Если имена методов совпадают с именами значений enum, вы можете сделать это через отражение. –

+0

Вы можете запустить действие, просто добавив '()', не нужно делать '.Invoke()'. Просто fyi – vrwim

+0

@Jon Skeet Может быть, словарь отлично работает, но добавление не все звучит неплохо. Тем не менее, все же лучше, чем гигантский переключатель. Создание каждого имени метода соответствует каждому имени переименования звучит немного опасно при добавлении новых вещей. – null

ответ

3

Не могу сказать, что я бы рекомендовал делать это, но:

public static class Functions 
{ 
    public static Func<int, int, int> Add = (x, y) => { return x + y; }; 
} 

Тогда вы просто позвоните Functions.Add(1,1)

Если вы действительно имеют использовать перечисление для него, то вы можете сделать:

public static class Functions 
{ 
    public static void Add() 
    { 
     Debug.Print("Add"); 
    } 

    public static void Subtract() 
    { 
     Debug.Print("Subtract"); 
    } 

    public enum Function 
    { 
     Add, 
     Subtract 
    } 

    public static void Execute(Function function) 
    { 
     typeof(Functions).GetMethod(function.ToString()).Invoke(null, null); 
    } 
} 

Затем Functions.Execute(Functions.Function.Add) (дополнительные функции связаны с тем, что мое перечисление находилось внутри класса Function).

+0

Это выглядит интересно, но может ли это повлиять на производительность при вызове много раз? Также почему '.Invoke (null, null);'? – null

+0

Я протестировал это, и влияние производительности довольно большое. Требуется x30 раз, если я буду вводить функцию имени в виде строки и x133, если я выполняю '.ToString()' сравнение обычного вызова функции. Если я сначала загружаю methodInfo, это занимает время x20. – null

+0

@null '.Invoke (null, null)' для вызова статического метода без аргументов, вам может потребоваться изменить его для вашей вещи. Эффективность с использованием отражения будет сильно затронута. Я сказал, что предлагаю вам этого не делать. Возможно, стоит рассмотреть, правильно ли вы делаете это, если чувствуете, что вам нужно размышление. Я могу ответить только на ваш вопрос, потому что я не знаю, чего вы пытаетесь достичь. Все, что сказано, штраф за исполнение может быть приемлемым в зависимости от вашей ситуации. Не оптимизируйте преждевременно. –

0

Если функции содержат одинаковый signature, то вы можете сделать что-то вроде этого

enum FunctionType 
{ 
Addition = 0, 
Substraction = 1, 
Mutiplication = 2, 
Division = 3 
} 
void ExecuteFunction(FunctionType Function) 
{ 
    //variable will contain function to execute 
    public Func<int, int, int> functionToExecute= null; 

    switch(Function) 
    { 
    case FunctionType.Addition: functionToExecute=Addition; 
    break; 
    case FunctionType.Substraction: functionToExecute=Subsctration; 
    break;  
    ... 
    default: ... 
    } 

    //Checking if not reached default case 
    if(functionToExecute!=null) 
    { 
    var result= functionToExecute(para1,para2); 
    ............... 
    } 


} 
+0

Я пытаюсь избежать переключения, это проблема в первую очередь. Если у меня много функций, код будет слишком длинным. – null

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

  • Нет связанных вопросов^_^