【问题标题】:In C#, how do I use struct like an enum?在 C# 中,如何像枚举一样使用结构?
【发布时间】:2012-05-22 19:10:01
【问题描述】:

我有一个我想像枚举一样使用的结构:

public struct SQLDS_statementTypes
{
    public static string Select = "Select", 
        Update = "Update", Insert = "Insert", Delete = "Delete";
}

但它会抛出错误:“运算符'=='不能应用于'SQLDS_statementTypes'和'string'类型的操作数”在此语句上:

if (statement == SQLDS_statementTypes.Update)

有没有办法解决这个问题?

【问题讨论】:

  • 为什么要将结构体视为枚举...?
  • 为什么您要尝试使用像枚举这样的结构?你明白SQLDS_statementTypes.Update是一个字符串,而不是SQLDS_statementTypes类型的值吗?
  • 我正在尝试使用它,所以我可以拥有 STRING ENUM,据我所知,这在 C# 中是不可能的。
  • 这个 MS 链接展示了如何从一个类中创建一个枚举:docs.microsoft.com/en-us/dotnet/architecture/microservices/…

标签: c#


【解决方案1】:

有人正在寻找的东西看起来或多或少是你一段时间前正在寻找的东西(我懒得找到链接),我当时写了这篇文章。您可能希望更改类名以更符合您的要求。我希望添加/删除值的配置简单明了,如果不是我可以详细说明。

public struct Group
{
    #region Code that is to be configured
    public static readonly Group Alpha = new Group("Group Alpha");
    public static readonly Group Beta = new Group("Group Beta");
    public static readonly Group Invalid = new Group("N/A");


    public static IEnumerable<Group> AllGroups
    {
        get
        {
            yield return Alpha;
            yield return Beta;
            yield return Invalid;
            //...
            //add a yield return for all instances here.
        }
    }

    #endregion
    private string value;

    /// <summary>
    /// default constructor
    /// </summary>
    //private Group()
    //{
    //    //you can make this default value whatever you want.  null is another option I considered, but you 
    //    //shouldn't have this me anything that doesn't exist as one of the options defined at the top of 
    //    //the page.
    //    value = "N/A";
    //}
    /// <summary>
    /// primary constructor
    /// </summary>
    /// <param name="value">The string value that this is a wrapper for</param>
    private Group(string value)
    {
        this.value = value;
    }

    /// <summary>
    /// Compares the Group to another group, or to a string value.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public override bool Equals(object obj)
    {
        if (obj is Group)
        {
            return this.value.Equals(((Group)obj).value);
        }

        string otherString = obj as string;
        if (otherString != null)
        {
            return this.value.Equals(otherString);
        }

        throw new ArgumentException("obj is neither a Group nor a String");
    }

    public override int GetHashCode()
    {
        return value.GetHashCode();
    }

    /// <summary>
    /// returns the internal string that this is a wrapper for.
    /// </summary>
    /// <param name="group"></param>
    /// <returns></returns>
    public static implicit operator string(Group group)
    {
        return group.value;
    }

    /// <summary>
    /// Parses a string and returns an instance that corresponds to it.
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static Group Parse(string input)
    {
        return AllGroups.Where(item => item.value == input).FirstOrDefault();
    }

    /// <summary>
    /// Syntatic sugar for the Parse method.
    /// </summary>
    /// <param name="other"></param>
    /// <returns></returns>
    public static explicit operator Group(string other)
    {
        return Parse(other);
    }

    public override string ToString()
    {
        return value;
    }
}

【讨论】:

    【解决方案2】:

    你不能。如果你想做这样的字符串比较,为什么不使用带有公共成员的静态类呢?

    static class StatementTypes
    {
        public static Select
        {
            get { return "Select"; }
        }
    }
    

    然后您可以使用 StatementTypes.Select 进行比较。

    【讨论】:

      【解决方案3】:

      为什么不使用常规枚举? http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

      【讨论】:

      • 常规枚举受限于它们可以表示的基础类型。在某些情况下,它们也可能很笨重。
      • 因为我的枚举类型是String,而不是int。
      • 您可以轻松地将枚举转换为字符串。只需使用 -ToString 方法:msdn.microsoft.com/en-us/library/16c1xs4z.aspx
      • @Adam 如果您希望枚举表示的字符串是一个有效的变量名(即没有空格,不能以数字开头,不能包含许多特殊字符,应该' 不会很长,等等),并且您不希望变量名称与它所代表的字符串值不同。
      • @Servy 当然,但在这种情况下,最简单的解决方案似乎还可以。
      【解决方案4】:

      错误是正确的,我认为(从错误中)statement 的类型为 SQLDS_statementTypes,但 SQLDS_statementTypes.Update 的类型为 string,因此您试图将结构与字符串进行比较,这使得默认情况下对 C# 没有意义。

      statement 设为string 类型,如果你真的想这样做,它将编译,但我不确定你为什么不首先使用常规的enum

      您是否尝试获取枚举的string 值?默认情况下,C# 已经这样做了:

      public enum Coordinates
      {
          Cartesian,
          Polar
      }
      
      ...
      
      // x will contain the string "Cartesian"
      var x = Coordinates.Cartesian.ToString();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-15
        • 1970-01-01
        • 2020-07-30
        • 1970-01-01
        • 2019-02-21
        • 2014-06-21
        • 2012-07-03
        • 1970-01-01
        相关资源
        最近更新 更多