【问题标题】:Storing string values as constants in the same manner as Enum以与 Enum 相同的方式将字符串值存储为常量
【发布时间】:2009-06-05 23:48:57
【问题描述】:

我知道有一种方法可以使枚举适用于具有大量转换的字符串类型 - 代码看起来并不漂亮。

有没有人知道有这样的方法:

    public SOMESTRUCTURE SessionKeys : string
{
    value1 = "value1key",
    value2 = "value2key",
    name = "name"
}

所以稍后在我的代码中我可以将其称为:

SessionKeys.value1

【问题讨论】:

    标签: c# .net .net-2.0 enums constants


    【解决方案1】:

    这是我想出的最好的。 (我还没有编译,所以语法可能是关闭的。)

    public static class SessionKeys
    {
        public const string Value1 = "Value1";
        public const string Value2 = "Value2";
        ...
    }
    

    【讨论】:

    • 是的,我正在考虑使用静态类。干净多了。只是想也许还有其他一些我不知道的选择。
    • 这里的问题是要将这些值之一传递给函数,您必须使用普通的旧字符串参数,因此编译器当然会允许 any 字符串用于该功能。
    • @Joel Coehoorn, gnomixa:您可以创建自己的类型,尽管这要麻烦得多。您还可以提供一个字典来验证它是否是有效的“SessionKey”。 @gnomixa:另外,请参阅有关您的命名的链接:stackoverflow.com/questions/1405851/…
    【解决方案2】:

    使用 C# 2.0 - 我认为最好的选择是使用带有常量的静态类作为您的值,正如 John Fisher 所建议的那样。

    如果您可以使用 C# 3.0,您可以使用标准枚举和简单的扩展方法来以一种不那么令人反感的方式处理转换。

    【讨论】:

      【解决方案3】:

      在这里查看我的答案:
      Getting static field values of a type using reflection

      这与 John Fisher 的回答的区别在于,您可以将 SessionKeys 作为函数参数传递,并获得您想要的类似枚举的语义。

      上一个问题询问的是 VB.Net,但 C# 端口应该没有那么难。事实上,这里(未经测试):

      public interface ICustomEnum<T>
      {
          ICustomEnum<T> FromT(T value);
          T Value { get; }
      
          // Implement using a sealed class with a private constructor 
          // that accepts and sets the Value property, 
          // one shared readonly property for each desired value in the enum,
          // and implicit conversions to and from T.
          // Then see this link to get intellisense support
          // that exactly matches a normal enum:
          // https://stackoverflow.com/questions/102084/hidden-features-of-vb-net/102217#102217
          // Note that the completion list only works for VB.
      }
      
      /// <completionlist cref="SessionKeys"/>
      public sealed SessionKeys: ICustomEnum<string>
      {
          private string _value;
          public string Value { get { return _value; } } 
      
          private SessionKeys(string value)
          {
              _value = value;
          }
      
          private static SessionKeys _value1 = new MyStringEnum("value1key");
          public static SessionKeys value1 { get { return _value1;} } 
      
          private static MyStringEnum _value2 = new MyStringEnum("value2key");
          public static MyStringEnum value2 { get { return _value2;} } 
      
          public static ICustomEnum<string> FromString(string value) 
          {
              // use reflection or a dictionary here if you have a lot of values
              switch( value )
              {
                  case "value1key":
                      return value1;
                  case "value2key":
                      return value2;
                  default:
                      return null; //or throw an exception
              }
          }
      
          public ICustomEnum<string> FromT(string value) 
          {
              return FromString(value);
          }
      
          public static implicit operator string(SessionKeys item)
          {
              return item.Value;
          }
      
          public static implicit operator SessionKeys(string value)
          {
              return FromString(value);
          }
      }
      

      您并不真的需要接口,但我保留它以提醒我如何实现它们。

      【讨论】:

        【解决方案4】:

        问题是枚举不仅仅是一个带有一堆公共数字常量的静态类。枚举是一种类型。使用常量,您将失去类型安全性。如果使类的静态成员与类的类型相同,则可以实现类型安全。

        public sealed class SessionKey
        {
            private _value; 
            private SessionKey( string value )
            {
                _value = value;
            }
        
            public string Value { get return _value; }
        
            public static readonly SessionKey Value1 = new SessionKey( "Value1" );
            public static readonly SessionKey Value2 = new SessionKey( "Value2" );
        }
        
        public class Something
        {
            /* stuff */
            public void Foo( SessionKey sessionKey )
            {
                switch( sessionKey.Value )
                {
                    case SessionKey.Value1.Value:
                        DoBaz();
                        break;
                    case SessionKey.Value2.Value:
                        DoBop();
                        break;
                    default:
                        DoBar();
                }
            }   
        
            /* other stuff */
        }
        

        【讨论】:

          猜你喜欢
          • 2012-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多