Подтвердить что ты не робот

Значение Enum для строки

Кто-нибудь знает, как получить значения перечисления в строку?

Пример:

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

Edit:

При попытке использовать ToString(); компилятор жалуется, потому что оператор case ожидает константу. Я также знаю, что ToString() вычеркивается строкой в ​​intellisense

4b9b3361

Ответ 1

Да, вы можете использовать .ToString(), чтобы получить строковое значение для перечисления, однако вы не можете использовать .ToString() в инструкции switch. Операторы 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
    }
}

Ответ 2

Вы идете об этом назад. Не пытайтесь использовать динамические строки в качестве ярлыков case (вы не можете), вместо этого проанализируете строку в значение перечисления:

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");
    } 
} 

EDIT: в принципе, вы можете просто сравнить с жестко закодированными строками в ваших операторах switch (см. ниже), но это наименее целесообразный подход, поскольку он просто сломается, когда вы измените значения, переданные методу, или определение перечисления. Я добавляю это, так как стоит знать, что строки могут использоваться как ярлыки case, если они литералы времени компиляции. Динамические значения не могут использоваться в качестве случаев, поскольку компилятор не знает о них.

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

Ответ 3

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

Нет TryParse для Enum, поэтому, если вы ожидаете ошибок, вам нужно использовать try/catch:

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

Ответ 4

Этот код будет работать.

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

Вы можете использовать другую временную переменную для сохранения класса класса enum, это может повысить производительность.

Ответ 5

Я предлагаю вам пойти другим путем - попробуйте как можно больше использовать фактические значения перечисления (путем преобразования строки в значение перечисления, как только сможете) вместо того, чтобы передавать строки вокруг вашего приложения:

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; это дает понять, что ваш метод действительно должен реализовать свою логику, и соответствует моей первоначальной точке, что вы должны стараться как можно больше не передавать строки вокруг.

Ответ 6

Это просто для удовольствия, но что, если вы использовали словарь делегатов? Я понимаю, что у вас совершенно другой подход, но словарь-словарь может работать лучше для того, что вы пытаетесь выполнить, тем более, что он обеспечивает высокую степень модульности, в отличие от конструкции 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();
        }
    }
}