Сохранение списка действий с параметрами и последующее их выполнение - PullRequest
0 голосов
/ 11 июня 2018

У меня есть перечисление действий, которые я хочу запустить:

public enum theActions
{
    action1,
    action2
}

Я хочу сохранить их в словаре:

public Dictionary<theActions, Action> _theActions { get; }

_theActions = new Dictionary<theActions, Action>
{
    [theActions.action1] = () => action1Func()
};

Я бы имел свои функции, для каждого действия:

public void action1Func(int inParam)
{
    //do whatever
}

Позже мне нужно будет вызвать одну из функций:

public void execAction(int inVar, Action action) 
{ 
    //inVar isn't the parameter I want to pass to the action. It's used, for something else.
    action(); 
}

execAction(1, _theActions[theActions.action1]);

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

Я получил это до сих пор:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public enum theActions
        {
            action1,
            action2
        }

        public Dictionary<theActions, Action<int>> _theActions { get; }

        public void execAction(int inVar, Action<int> action)
        {
            //inVar isn't the parameter I want to pass to the action. It's used, for something else.
//            action();
        }

        public Form1()
        {
            InitializeComponent();

            _theActions = new Dictionary<theActions, Action<int>>
            {
                [theActions.action1] = (Action<int>)((int x) => action1Func(x))
            };

        }

        public void action1Func(int inParam)
        {
            //do whatever
            MessageBox.Show($"Hello ... inParam : {inParam}");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //This works manually
            _theActions[theActions.action1].Invoke(12);

            //But, I want the execAction to work
            //execAction(1, _theActions[theActions.action1]);
        }
    }
}

Он работает, вызывая его вручную.Мне просто нужна помощь, чтобы войти в execAction () и запустить его.Итак, закройте.

Ответы [ 2 ]

0 голосов
/ 12 июня 2018
public void execAction(int someInt, Action action)
{
    action();

    // or: action.Invoke();
}

Вы должны иметь возможность удалить всю лямбду в инициализации, так как у вас уже есть метод с одним параметром int прямо здесь:

public Form1()
{
    InitializeComponent();

    _theActions = new Dictionary<theActions, Action<int>>
    {
        [theActions.action1] = action1Func
    };
}

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

int yourParameter = 12345;
execAction(42, () => (_theActions[theActions.action1]).Invoke(yourParameter));
0 голосов
/ 11 июня 2018

Попробуйте удалить словарь и использовать вместо этого:

public void action1Func(int p1) //action 1 has one int parameter
{
}
public void action2Func() //let's consider action 2 takes no parameters
{
}
public void action3Func(int p1, int p2, int p3)
{
}
// Order of parameters was changed to leverage implicit null parameters for convenience
// See invocations below
public void execAction(theActions action, 
                       int? inVar1 = null, int? inVar2 = null, int? inVar3 = null) 
{
    switch (action) // Based on action kind, invoke the right function.
    {               // The mapping is now coded in a switch statement 
                    // instead of a Dictionary declaration
        case theActions.action1: action1Func(inVar1.Value); break;
        case theActions.action2: action2Func(); break;
        case theActions.action3: action3Func(inVar1.Value, inVar2.Value, inVar3.Value); break;
    }
}
// Invocations
execAction(theActions.action1, 1);
execAction(theActions.action2);
execAction(theActions.action3, 1, 3, 5);

Вы можете вызывать методы с произвольным числом параметров, если вы правильно используете неявное объявление параметров для execAction.

Вы можетевыполнить проверку параметров (например, выше, вы можете проверить, что inVar1.HasValue == true перед вызовом), в противном случае код не будет работать быстро, если вы пропустите параметр (Nullable.Value выдает InvalidOperationException, если HasValue равен false).

Если числопараметров растет и становится неуправляемым, вы можете поместить их в класс параметров пакета и проверить их инициализацию с помощью конструктора.

Вы можете получить больше безопасности (проверки времени компиляции), если определите следующие перегрузки:

public void execAction1(int p1)
    => execAction(theActions.action1, p1);
public void execAction2()
    => execAction(theActions.action2);
public void execAction3(int p1, int p2, int p3)
    => execAction(theActions.action3, p1, p2, p3);

// Invocations will be
execAction1(1);
execAction2();
execAction3(1, 3, 5);

но этот последний шаг побеждает цель.Вместо этого вы можете вызвать оригинальные методы:).

...