Как я могу обобщенно привести перечисление? - PullRequest
2 голосов
/ 29 февраля 2012

Я пытаюсь решить простую проблему синтаксического анализа, и я решил использовать перечисления для кодирования списков вариантов выбора.

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

Выполнение этого со строками не проблема.Я просто передаю список и мы уходим.

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

Вот код, с которым мне трудно работать

private void parseToEnums(Enum returnEnum, string searchBlock, string startIDText,
                          string endIDText, string startText, string endText)
{
    string ourSearchBlock = searchBlock;
    int endIDidx = ourSearchBlock.IndexOf(endIDText);

    while (ourSearchBlock.IndexOf(startText) != -1)
    {
        if (ourSearchBlock.Length == searchBlock.Length)
        {
            // first pass, trim off the region where the start text isn't valid
            ourSearchBlock = ourSearchBlock.Remove(endIDidx, ourSearchBlock.Length - endIDidx);
            // first pass, use the startIDtext to create a valid search zone
            // BROKEN CODE HERE
            // Neither GetType() nor typeof seem to do the right thing
            // I have tried several varieties and have tried casting the LHS in the
            // same sort of way
            // pluckText returns a string that is guaranteed to match an enum name
            returnEnum = (returnEnum.GetType()) System.Enum.Parse(typeof(returnEnum), pluckText(ourSearchBlock, startIDText, startText, endText), false);
            ourSearchBlock = ourSearchBlock.Remove(0, ourSearchBlock.IndexOf(startIDText) + startIDText.Length);
        }
        else
        {
            // this would be similar to the above after it's working
            // and is for the case where the string has multiple matches
            // within the enum, ie "red white"
            //returnList.Add(pluckText(ourSearchBlock, "", startText, endText));
        }
        ourSearchBlock = ourSearchBlock.Remove(0, ourSearchBlock.IndexOf(startText) + startText.Length);
    }

    return;
}

Пример того, что яделать

private enum Colors { red, white, green };
private enum Suits  { spades, clubs, hearts, diamonds };

// ... open files, read data, etc
// so I pass in the enum that I want my result in and some text identifiers

parseToEnum ( Colors, searchBlock, "startColorBlock", "endColorBlock", "id=" );
parseToEnum ( Suits, searchBlock, "startCardSuitsBlock", "endCardSuitsBlock", "<id=" );

// ...

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

Я знаю, что мне нужно добавить некоторыепопробуйте / перехватите обертки и общее обнаружение ошибок в этом коде, прежде чем слишком долго.

1 Ответ

9 голосов
/ 29 февраля 2012

Я собираюсь игнорировать весь этот поиск и сосредоточиться на преобразовании string в enum.

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

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

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

T ParseEnum<T>(string s)
{
    return (T)Enum.Parse(typeof(T), s, false);
}

Затем можно вызвать его так:

Colors color = ParseEnum<Colors>(someString);

Ошибки в вашем коде:

  • Enum - это общий базовый тип всех enum s, он не представляет тип enum.Это означает, что вы не можете использовать, например, Colors в качестве параметра метода.
  • Нельзя приводить к типу, известному только во время выполнения.Другими словами, код типа (foo.GetType())bar никогда не будет работать.
  • Вы не можете использовать оператор typeof для получения типа переменной.Вы можете использовать его для получения объекта Type для определенного типа, например, typeof(string) или typeof(T) в универсальном методе с аргументом типа T.
  • Имена типов (включая enumс) должно быть в единственном числе.Это потому, что, например, переменная типа Color представляет один цвет.Хотя это только вопрос стиля, и он не остановит работу вашего кода.Но это сделает ваш код сложнее для понимания.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...