我知道下面是不可能的,因为枚举的类型必须是int

enum GroupTypes
{
    TheGroup = "OEM",
    TheOtherGroup = "CMB"
}

从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。

我还有其他选择吗?


当前回答

如果不是你的枚举的所有值都有一个字符串,如果你想稍后设置这些值,我使用如下类:

 public class SessionResoult
{
    public enum SessionResoultType
    {
        Success,
        Error,
    }
    public SessionResoult(SessionResoultType sesionResoultType, string value = null)
    {
        Type = sesionResoultType;
        Value = value;
       
    }

    public SessionResoultType Type { get; set; }

    public string Value { get; private set; }
  

    public sealed class Success : SessionResoult
    {
        public Success() : base(SessionResoultType.Success) { }
    }

    public sealed class Error : SessionResoult
    {
        public Error(string value) : base(SessionResoultType.Error, value) { }
    }

    public override string ToString()
    {
        if(this is Success)
        {
            return (SessionResoultType.Success.ToString());
        }else if(this is Error)
        {
            return $"{SessionResoultType.Error}:{this.Value}";
        }
        else { return base.ToString(); }
    }

}

使用的例子:

private SessionResoult ok = new SessionResoult. success ();private SessionResoult错误=新的SessionResoult。错误(“没有可用的网络”);

其他回答

根据其他人的意见,这是我想到的。这种方法避免了在想要获得常量值的地方键入. value。

我有一个基类的所有字符串枚举像这样:

using System;
using Newtonsoft.Json;

[JsonConverter(typeof(ConstantConverter))]
public class StringEnum: IConvertible
{
    public string Value { get; set; }

    protected StringEnum(string value)
    {
        Value = value;
    }

    public static implicit operator string(StringEnum c)
    {
        return c.Value;
    }
    public string ToString(IFormatProvider provider)
    {
        return Value;
    }

    public TypeCode GetTypeCode()
    {
        throw new NotImplementedException();
    }

    public bool ToBoolean(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }
    //The same for all the rest of IConvertible methods
}

JsonConverter是这样的:

using System;
using Newtonsoft.Json;

class ConstantConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            serializer.Serialize(writer, null);
        }
        else
        {
            serializer.Serialize(writer, value.ToString());
        }
    }
}

一个实际的string enum是这样的:

public sealed class Colors : StringEnum
{
    public static Colors Red { get { return new Catalog("Red"); } }
    public static Colors Yellow { get { return new Catalog("Yellow"); } }
    public static Colors White { get { return new Catalog("White"); } }

    private Colors(string value) : base(value) { }
}

有了这个,你可以使用颜色。红色甚至序列化到json而不使用Value属性

下面是我对这个问题的看法,使用c# 9.0语法来保持整洁。我为枚举定义了一个基类:

public class StringEnum
{
    protected StringEnum(string value) { Value = value; }
    public string Value { get; }
    public override string ToString() => Value;
}

创建新的枚举样式类型是简单而紧凑的:

public class GroupTypes : StringEnum
{ 
    private GroupTypes(string value) : base(value) {}

    public static readonly GroupTypes TheGroup = new("OEM");
    public static readonly GroupTypes TheOtherGroup = new("CMB");
}

像这样使用它:

void Example(GroupTypes groupType)
{
    Console.WriteLine(groupType); // Will print "OEM" or "CMB"
    if (groupType == GroupTypes.TheGroup) { ... }
}

你也可以给StringEnum添加更多的功能,这样你的所有子类都可以使用(例如,实现IComparable和重写Equals和GetHashCode)

摘自@EvenMien,并添加了一些评论。(也适用于我自己的用例)

public struct AgentAction
{
    private AgentAction(string value) { Value = value; }

    public string Value { get; private set; }

    public override string ToString() { return this.Value; }
    
    public static AgentAction Login = new AgentAction("Login");
    public static AgentAction Logout = new AgentAction("Logout");

    public static implicit operator string(AgentAction action) { return action.ToString(); }
}

我只需创建一个字典,并使用代码作为键。

编辑:为了解决关于执行反向查找(查找键)的注释,这将不是非常有效。如果有必要,我将编写一个新类来处理它。

为你的DB创建第二个枚举,包含以下内容:

enum DBGroupTypes
{
    OEM = 0,
    CMB = 1
}

现在,您可以使用Enum。解析以从字符串“OEM”和“CMB”中检索正确的DBGroupTypes值。然后,您可以将这些值转换为int,并从您希望在模型中进一步使用的正确枚举中检索正确的值。