Динамически вызывать функцию в Windows форме - PullRequest
2 голосов
/ 30 января 2020

Я создаю приложение для тестирования некоторого оборудования, и приложение будет иметь 43 шага (от Step01.cs до Step43.cs). (тесты огромны и должны быть разделены на отдельные файлы)

В каждом файле .cs есть функция public static void Test(){}.

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

if (currentStep < maxStep )
{ 
    for(int i = currentStep; i < maxStep; i++)
    {
        _form1.testNumberComboBox.SelectedIndex = i - 1;

        if (MessageBox.Show($"{_form1.testNameComboBox.SelectedItem.ToString()} has already been tested.\nWould you like to retest?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
        {
            Step02.Test(_form1, sensor);
            return;
        }
    }
    _form1.testNumberComboBox.SelectedIndex = maxStep - 1;
}

Мой вопрос: возможно ли сделать что-то подобное Step{i}.Test(_form1, sensor);, чтобы вызвать то, что мне нужно, так как я этого не делаю? я действительно не хочу делать if(i == 2){Step02.Test(_form1, sensor);}...if(i == 40){Step40.Test(_form1, sensor);}, если пользователь ответит Да.

Я сделал нечто подобное в PHP некоторое время назад. Имел переменные $acc1, $acc2 ... $accX и смог вызвать их в for(i) loop with ${"acc$i"}.

Я не уверен, возможно ли это в C#, и поэтому я спрашиваю. (Я новичок в C#)

1 Ответ

2 голосов
/ 30 января 2020

Вы можете использовать Отражение или Dictionary<string, Action>.

Предполагая, что у вас есть такие тестовые классы:

namespace MyTests
{    
    public class Test1
    {
        public static void Test() { }
    }
}

Вызовите тест, используя Reflection:

Найдите класс и метод, используя отражение, и назовите его:

Assembly.GetExecutingAssembly().GetType("MyTests.Test1")
    .GetMethod("Test").Invoke(null, null);

Вызовите тест, используя словарь :

Инициализируйте Dictionary<string, Action>() следующим образом:

Dictionary<string, Action> tests = new Dictionary<string, Action>();
tests.Add("Test1", () => Test1.Test());
tests.Add("Test2", () => Test2.Test());

Затем вызывайте по имени, когда вам нужно:

tests["Test1"]();

Объедините оба отражение и словарь :

Или вы можете комбинировать как для повышения производительности, так и для упрощения инициализации. Найти все тесты при запуске, используя отражение один раз:

Dictionary<string, Action> tests = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t.FullName.StartsWith("MyTests.Test"))
    .Select(t => t.GetMethod("Test"))
    .ToDictionary(m => m.DeclaringType.Name,
        m => new Action(() => m.Invoke(null, null)));

Запускать, когда вам нужно:

tests["Test1"]();
tests["Test2"]();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...