如何通用地强制转换枚举

本文关键字:转换 枚举 何通用 | 更新日期: 2023-09-27 18:26:01

我试图解决一个简单的解析问题,我选择使用枚举对选项列表进行编码。

输入数据是直接的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=" );
// ...

因此,我们的想法是使用相同的结构(因为输入是相同的),但对输出使用不同的枚举。

我知道我需要在这段代码中添加一些try/catch包装器和一般错误检测,以免时间过长。

如何通用地强制转换枚举

我将忽略所有搜索,并专注于将string转换为enum

首先,我认为您的方法应该返回结果,而不是将其作为参数传递(为此需要out)。

其次,要将枚举的类型传递给方法,您可以使用类型为Type的参数,或者更好的是,使该方法具有泛型并将该类型作为类型参数传递。

方法可能看起来像这样:

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

你可以这样称呼它:

Colors color = ParseEnum<Colors>(someString);

代码中的错误是:

  • Enum是所有enum的公共基类型,它不代表enum的类型。这意味着您不能使用例如Colors作为方法的参数
  • 不能强制转换为仅在运行时已知的类型。换句话说,像(foo.GetType())bar这样的代码永远不会工作
  • 不能使用typeof运算符来获取变量的类型。您可以使用它来获取某些特定类型的Type对象,例如具有类型参数T的泛型方法中的typeof(string)typeof(T)
  • 类型名称(包括enum s)应为单数。这是因为例如Color类型的变量表示一种颜色。尽管这只是一个样式问题,它不会阻止您的代码工作。但这会使您的代码更难理解