【问题标题】:How can I use enum in C# for storing string constants? [duplicate]如何在 C# 中使用枚举来存储字符串常量? [复制]
【发布时间】:2010-12-23 12:30:00
【问题描述】:

可能重复:
Enum with strings

枚举中是否可以有如下字符串常量?

      enum{name1="hmmm" name2="bdidwe"}

如果不是,最好的方法是什么?

我试过了,但它不适用于字符串,所以现在我将所有相关常量分组到一个类中,例如

      class operation
      {
          public const string  name1="hmmm";
          public const string  name2="bdidwe"
      }

【问题讨论】:

  • string[] Days = { "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنج شنبه", "جمعه", "شنبه", }; int i =(int) obj.GetDayOfWeek(dt);字符串 DayName = Days[i];

标签: .net string constants enums


【解决方案1】:

枚举常量只能是序数类型(默认为int),所以枚举中不能有字符串常量。

当我想要“基于字符串的枚举”之类的东西时,我会像您一样创建一个类来保存常量,但我将其设为静态类以防止不需要的实例化和不需要的子类化。

但是,如果您不想在方法签名中使用字符串作为类型,并且希望使用更安全、限制性更强的类型(如 Operation),则可以使用安全枚举模式:

public sealed class Operation
{
    public static readonly Operation Name1 = new Operation("Name1");
    public static readonly Operation Name2 = new Operation("Name2");

    private Operation(string value)
    {
        Value = value;
    }

    public string Value { get; private set; }
}

【讨论】:

  • 这个看起来真的很棒。谢谢
  • +1 完美契合。再加上隐式操作,你就很成功了:public static implicit operator string(Operation op) { return op.Value; },因为这样你就可以将它用作强类型参数或字符串。
  • 但是不能在需要字符串常量的地方使用上述模式,例如在 switch..case 语句中
  • @ghanashyaml 我相信这依赖于反射。无论如何它都很慢。
  • @Janis 如答案所述:“如果您不想使用字符串作为方法签名中的类型,并且您更喜欢更安全、更严格的类型”
【解决方案2】:

您可以使用DescriptionAttribute 执行此操作,但是您必须编写代码才能将字符串从属性中取出。

public enum YourEnum
{
    [Description("YourName1")]
    Name1,

    [Description("YourName2")]
    Name2
}

【讨论】:

  • +1 第一次遇到描述属性。谢谢:)
  • 如何从属性中取出字符串?
  • +1 唯一的答案已经采取了 OP 的意图是拥有具有 Enum 类型的全部可能性的东西。
  • 如果你用谷歌搜索“枚举描述属性”,会有很多例子。这是一个:weblogs.asp.net/grantbarrington/archive/2009/01/19/…
  • 这是对问题 +1 的一个很好的回答,但在实践中,这个属性对其功能非常模糊,在实践中可能没有那么有用
【解决方案3】:

枚举的全部意义在于成为序数常数。
但是,您可以通过使用扩展方法来实现您想要的:

  enum Operation
  {
      name1,
      name2
  }

  static class OperationTextExtender
  {
        public static String AsText(this Operation operation)
        {
              switch(operation)
              {
                    case Operation.name1: return "hmmm";
                    case Operation.name2: return "bdidwe";
                    ...
              }
        }
  }

  ...
  var test1 = Operation.name1;
  var test2 = test1.AsText();   

【讨论】:

  • 我真的很想知道你是否会在现实世界的代码中使用这样的一次性扩展方法? (这个问题没有讽刺意味)。知道可以做到这一点很有趣。
  • 我有一个 sn-p,它使用包含标志枚举的包含和删除方法创建扩展类。我不希望它成为公共 API 的一部分,所以它是内部的。但我相当频繁地使用它,并且也用于内置标志,尤其是“包含”。
  • @RobertGiesecke 只是想给你这个解决方案的荣誉。扩展方法对我来说是一种完美而优雅的方式!其他解决方案是避免枚举,但这个解决方案允许我扩展并且它工作得很好,而不必像大多数解决方案那样过度复杂化任务..
【解决方案4】:

您的 operation 类不会按原样编译...您没有声明 name1 和 name2 的类型...

但这是我会采取的方法......是的。

如果你把它变成一个结构,那么它就会变成一个值类型,它可能是你想要的,也可能不是你想要的......

【讨论】:

  • 我忘了在这里输入,否则没问题。我只是关心保持字符串常量的正确方法。
  • 是的,我也可能会按照这些思路做一些事情。
猜你喜欢
  • 2017-07-03
  • 2015-06-16
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
相关资源
最近更新 更多