Значение 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
Ответы
Ответ 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();
}
}
}