枚举值为字符串

时间:2010-06-25 18:25:39

标签: c#

有谁知道如何将枚举值转换为字符串?

示例:

private static void PullReviews(string action, HttpContext context)
{
    switch (action)
    {
        case ProductReviewType.Good.ToString():
            PullGoodReviews(context);
            break;
        case ProductReviewType.Bad.ToString():
            PullBadReviews(context);
            break;
    }
}

编辑:

尝试使用ToString()时;编译器抱怨因为case语句期望一个常量。我也知道ToString()是用intellisense中的一行删除的

6 个答案:

答案 0 :(得分:39)

是的,您可以使用.ToString()获取枚举的字符串值,但不能在switch语句中使用.ToString()。 Switch语句需要常量表达式,而.ToString()直到运行时才会计算,因此编译器会抛出错误。

要获得所需的行为,只需对方法稍作更改,就可以使用enum.Parse()action字符串转换为枚举值,然后切换该枚举值。从.NET 4开始,您可以使用Enum.TryParse()并预先进行错误检查和处理,而不是在交换机体中进行。

如果是我,我会将字符串解析为枚举值并打开它,而不是打开字符串。

private static void PullReviews(string action, HttpContext context)
{
    ProductReviewType review;

    //there is an optional boolean flag to specify ignore case
    if(!Enum.TryParse(action,out review))
    {
       //throw bad enum parse
    }


    switch (review)
    {
        case ProductReviewType.Good:
            PullGoodReviews(context);
            break;
        case ProductReviewType.Bad:
            PullBadReviews(context);
            break;
        default:
            //throw unhandled enum type
    }
}

答案 1 :(得分:13)

你正在倒退。不要尝试使用动态字符串作为案例标签(你不能),而是将字符串解析为枚举值:

private static void PullReviews(string action, HttpContext context) 
{ 
    // Enum.Parse() may throw if input is invalid, consider TryParse() in .NET 4
    ProductReviewType actionType = 
        (ProductReviewType)Enum.Parse(typeof(ProductReviewType), action);

    switch (actionType) 
    { 
        case ProductReviewType.Good: 
            PullGoodReviews(context); 
            break; 
        case ProductReviewType.Bad: 
            PullBadReviews(context); 
            break; 
        default: // consider a default case for other possible values...
            throw new ArgumentException("action");
    } 
} 

编辑:原则上,您可以只比较switch语句中的硬编码字符串(见下文),但这是最不可取的方法,因为当您更改传入方法的值时它会简单地中断,或枚举的定义。我正在添加这个,因为值得知道字符串可以用作案例标签,只要它们是编译时文字。动态值不能用作案例,因为编译器不知道它们。

// DON'T DO THIS...PLEASE, FOR YOUR OWN SAKE...
switch (action) 
{ 
    case "Good": 
        PullGoodReviews(context); 
        break; 
    case "Bad": 
        PullBadReviews(context); 
        break; 
} 

答案 2 :(得分:5)

public enum Color
{
    Red
}

var color = Color.Red;
var colorName = Enum.GetName(color.GetType(), color); // Red

编辑:或许你想要......

Enum.Parse(typeof(Color), "Red", true /*ignorecase*/); // Color.Red

Enum没有TryParse,所以如果你期望错误,你必须使用try / catch:

try
{
  Enum.Parse(typeof(Color), "Red", true /*ignorecase*/);
}
catch( ArgumentException )
{
  // no enum found
}

答案 3 :(得分:2)

这段代码可行。

private enum ProductReviewType{good, bad};

private static void PullReviews(string action)
{
    string goodAction = Enum.GetName(typeof(ProductReviewType), ProductReviewType.good);
    string badAction = Enum.GetName(typeof(ProductReviewType), ProductReviewType.bad);
    if (action == goodAction)
    {
        PullGoodReviews();
    }
    else if (action == badAction)
    {
        PullBadReviews();
    }
}

public static void PullGoodReviews()
{
    Console.WriteLine("GOOD Review!");
}

public static void PullBadReviews()
{
    Console.WriteLine("BAD Review...");
}

由于解析后的字符串不是常量,因此Switch语句不能使用它。 在VS2005中编译

您可以使用另一个临时变量来保存枚举类的类型,这可以提高性能。

答案 4 :(得分:1)

我建议你走另一条路 - 尝试尽可能多地使用实际的枚举值(通过将字符串转换为枚举值,只要你能),而不是通过应用程序周围的字符串:

ProductReviewType actionType = (ProductReviewType)Enum.Parse(typeof(ProductReviewType), val);
// You might want to add some error handling here.
PullReviews(actionType);

private static void PullReviews(ProductReviewType action, HttpContext context)
{
    switch (action)
    {
        case ProductReviewType.Good:
            PullGoodReviews(context);
            break;
        case ProductReviewType.Bad:
            PullBadReviews(context);
            break;
    }
}

请注意,我已将方法签名更改为接受ProductReviewType参数;这清楚地说明了你的方法实现其逻辑所需的实际内容,并且符合我的原始观点,即你应该尽量不要传递字符串。

答案 5 :(得分:1)

这只是为了它的乐趣,但是如果你使用了代表词典呢?我意识到你有一个完全不同的方法,但字典化实际上可能更适合你想要完成的事情,特别是因为它提供了高度的模块化,而不是mondo-switch结构(尽管我必须承认,你的枚举只有2个成员所以它是一个有争议的问题)。无论如何,我只是想以不同的方式做事......

基于字典的方法看起来像这样:

namespace ConsoleApplication1
{
    public enum ProductReviewType
    {
        Good,
        Bad
    }

    public static class StringToEnumHelper
    {
        public static ProductReviewType ToProductReviewType(this string target)
        {
            // just let the framework throw an exception if the parse doesn't work
            return (ProductReviewType)Enum.Parse(
              typeof(ProductReviewType), 
              target);
        }
    }

    class Program
    {

        delegate void ReviewHandler(HttpContext context);

        static readonly Dictionary<ProductReviewType, ReviewHandler> 
            pullReviewOperations = 
              new Dictionary<ProductReviewType, ReviewHandler>()
            {
                {ProductReviewType.Good, new ReviewHandler(PullGoodReviews)},
                {ProductReviewType.Bad, new ReviewHandler(PullBadReviews)}
            };

        private static void PullGoodReviews(HttpContext context)
        {
            // actual logic goes here...
            Console.WriteLine("Good");
        }

        private static void PullBadReviews(HttpContext context)
        {
            // actual logic goes here...
            Console.WriteLine("Bad");
        }

        private static void PullReviews(string action, HttpContext context)
        {
            pullReviewOperations[action.ToProductReviewType()](context);
        }

        static void Main(string[] args)
        {
            string s = "Good";
            pullReviewOperations[s.ToProductReviewType()](null);

            s = "Bad";
            pullReviewOperations[s.ToProductReviewType()](null);

            // pause program execution to review results...
            Console.WriteLine("Press enter to exit");
            Console.ReadLine();
        }
    }
}