Как я могу изменить одноименные внутренние классы, используя цикл? - PullRequest
0 голосов
/ 14 июня 2019

Эта проблема специфична для мобильного разработчика Android Ranorex, которая ограничивает мои настройки, но мне также поможет универсальное решение C #.

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

if (device_name == d1_name)
{
    device_stats.Add("Device Name", d1_name);
    System.Diagnostics.Debug.WriteLine(device_stats["Device Name"]);
    device_stats.Add("Status", repo.Android.Settings.d1.deviceStatus.TextValue);
    System.Diagnostics.Debug.WriteLine("Status:\t" + device_stats["Status"]);

    repo.Android.Settings.d1.screen.Touch();
}
else if(device_name == d2_name)
{
    device_stats.Add("Device Name", d2_name);
    System.Diagnostics.Debug.WriteLine(device_stats["Device Name"]);
    device_stats.Add("Status", repo.Android.Settings.d2.deviceStatus.TextValue);
    System.Diagnostics.Debug.WriteLine("Status:\t" + device_stats["Status"]);

    repo.Android.Settings.d2.screen.Touch();
}
else if (device_name == d3_name)
{
    device_stats.Add("Device Name", d3_name);
    System.Diagnostics.Debug.WriteLine(device_stats["Device Name"]);
    device_stats.Add("Status", repo.Android.Settings.d3.deviceStatus.TextValue);
    System.Diagnostics.Debug.WriteLine("Status:\t" + device_stats["Status"]);

    repo.Android.Settings.d3.screen.Touch();
}

Как видите, единственная разница между падежами - это имя устройства. Я пытался найти способ, которым я могу перебрать небольшую часть кода и заменить d '#' итератором. Как то так.

for (i_device = 0; i_device < n_device; i_device++)
{
    string i_str = int2str(i_device);
    if(device_name == device_name_arr[i_device])
    {
        device_stats.Add("Device Name", device_name_arr[i_device]));
        System.Diagnostics.Debug.WriteLine(device_stats["Device Name"]);
        device_stats.Add("Status", repo.Android.Settings.StringToInnerClass("d" + i_str).deviceStatus.TextValue);
        System.Diagnostics.Debug.WriteLine("Status:\t" + device_stats["Status"]);

        repo.Android.Settings.StringToInnerClass("d" + i_str).screen.Touch();
    }
}

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

Обновление

Я начал строить что-то, что находится далеко от меня, и я даже не уверен, что сейчас это правильный путь. Я думаю, что я в порядке с жестким кодированием этой части, а не сумасшедшим решением. Вот куда я собирался, если вам интересно. (Некоторые классы генерируются автоматически и немного странно). Он даже не компилируется

List<TestRepositoryFolders> device_folder = new List<TestRepositoryFolders>();
device_folder.Add(D5Folder.repo.Android.Settings.d5);
device_folder.Add(D6Folder.repo.Android.Settings.d6);

System.Diagnostics.Debug.WriteLine("please" + (TestRepositoryFolders)device_folder[0].deviceName.TextValue);
System.Diagnostics.Debug.WriteLine("please" + (TestRepositoryFolders)device_folder[1].deviceName.TextValue);

Ответы [ 2 ]

1 голос
/ 14 июня 2019

Звучит так, как будто вы хотите сделать то, что мы называем отражением типа.

var device = typeof(repo.Android.Settings).GetField("d" + i, BindingFlags.Public | BindingFlags.Static).GetValue(null) as TestRepositoryFolders

Этот метод немного сложнее для чтения, но после установки не требуется никаких изменений при добавлении нового устройства.

1 голос
/ 14 июня 2019

Вы могли бы записать StringToInnerClass, который вы имели в своем коде, как метод расширения, который использует отражение, чтобы получить нужный объект настроек конкретного устройства, хотя в этом случае это было бы излишним.

Цикл был хорошей идеей. Вы можете расширить массив имен устройств до массива пар имя / функция для достижения вашей цели, предполагая, что d1, d2 и т. Д. Относятся к одному типу.

Начните с создания метаданных для устройств: они состоят из имени устройства и функции поиска настроек. Я использовал здесь кортежи, чтобы избежать определения типа на данный момент, но вы должны подумать об этом в конце концов.

Поскольку вы не ответили на мой вопрос об именах типов, предполагается, что repo.Android.Settings имеет тип AndroidSettings. d1 и т. Д., По-видимому, относятся к типу TestRepositoryFolders в соответствии с вашими правками. Измените их на фактические типы по мере необходимости, чтобы заставить его работать.

List<(string Name, Func<AndroidSettings, TestRepositoryFolders> GetDeviceSettings)> device_meta =
    new List<(string, Func<AndroidSettings, TestRepositoryFolders>)>()
{
    (d1_name, s => s.d1),
    (d2_name, s => s.d2),
    (d3_name, s => s.d3)
};

Затем измените цикл, чтобы использовать свойство Name для проверки имени устройства и свойство GetDeviceSettings для получения настроек для этого устройства. Вы можете выйти из цикла, как только получите совпадение.

for (int i_device = 0; i_device < device_meta.Count; i_device++)
{
    if (device_name == device_meta[i_device].Name)
    {
        device_stats.Add("Device Name", device_meta[i_device].Name));
        System.Diagnostics.Debug.WriteLine(device_stats["Device Name"]);

        var deviceSettings = device_meta[i_device].GetDeviceSettings();

        device_stats.Add("Status", deviceSettings.deviceStatus.TextValue);
        System.Diagnostics.Debug.WriteLine("Status:\t" + device_stats["Status"]);

        deviceSettings.screen.Touch();

        break;
    }
}

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

...