类;结构体;枚举的混淆,哪个更好?

3
我有46行信息,每行有2列(“代码编号”、“描述”)。这些代码根据客户端的初始提交请求的成功或失败而返回给客户端。我不想使用数据库文件(csv、sqlite等)进行存储/访问。我认为最接近我想要向客户端显示这些代码的类型是异常类。如果我错了,请纠正我,但从我所能看到的来看,枚举类型不允许字符串,尽管这种结构似乎是基于它的工作方式(例如100 =“请求中缺少名称”)更好的选择。
考虑一下,创建一个类可能是最好的操作方式。然而,我希望得到更有经验的建议或指导,并从那些可能处于类似情况的人那里获得输入。
目前这就是我拥有的:
    class ReturnCode
{
    private int _code;
    private string _message;

    public ReturnCode(int code)
    {
        Code = code;
    }

    public int Code
    {
        get
        {
            return _code;
        }
        set
        {
            _code = value;
            _message = RetrieveMessage(value);
        }
    }

    public string Message { get { return _message; } }

    private string RetrieveMessage(int value)
    {
        string message;

        switch (value)
        {
            case 100:
                message = "Request completed successfuly";
                break;
            case 201:
                message = "Missing name in request.";
                break;
            default:
                message = "Unexpected failure, please email for support";
                break;
        }

        return message;
    }

}
5个回答

4
最好的方法是同时使用类和枚举。这样你就能够有比 “201” 更具描述性的标识符。 虽然结构体也可以,但是它们难以正确实现,所以除非你特别需要结构体,否则应该坚持使用类。 你不需要在类中存储消息的引用,你可以在需要时通过“Message”属性获取它。“Switch”是使用哈希表实现的(如果有五个或更多值),因此查找速度非常快。
public enum ReturnIdentifier {
  Success = 100,
  MissingName = 201;
}

public class ReturnCode {

  public ReturnIdentifier Code { get; private set; }

  public ReturnCode(ReturnIdentifier code) {
    Code = code;
  }

  public string Message {
    get {
      switch (Code) {
        case ReturnIdentifier.Success:
          return "Request completed successfuly.";
        case ReturnIdentifier.MissingName:
          return "Missing name in request.";
        default:
          return "Unexpected failure, please email for support.";
      }
    }
  }

}

使用方法:

ReturnCode code = new ReturnCode(ReturnIdentifier.Success);

如果您从某个地方得到一个整数代码,您仍然可以将其用作枚举器值与代码相对应:

int error = 201;
ReturnCode code = new ReturnCode((ReturnIdentifier)error);

如果整数代码不对应枚举中的任何标识符,进行转换仍然是完全有效的。在获取“Message”值时,它将以“default”情况结束,因为该值与其他情况不匹配。

这正是我一直在寻找的。你的论述清晰明了,提供了简单明了的例子。我再也无法期待更好的回答了。非常感谢你的帮助。 - Riana

3

我认为选择类(就像你所做的)是一个很好的决定。如果您使用Dictionary<int,string>将代码映射到描述中,则可以使代码更加紧凑和易读。

_dict.Add(100, "Description1");
_dict.Add(201, "Description2");
...............................

关于 RetrieveMessage

return _dict[value];

0
也许基于字典的方法看起来更优雅。
    private static Dictionary<int, string> errorCodes = 
    new Dictionary<int, string>()
    {
        {100, "Request completed successfuly"},
        {200, "Missing name in request."}
    };

    private string RetrieveMessage(int value)
    {
        string message;
        if (!errorCodes.TryGetValue(value, out message))
            message = "Unexpected failure, please email for support";

        return message;
    }

0

这样做肯定会更慢(因为它使用了反射),但是如果考虑到紧凑性,我认为带有自定义属性的枚举是适合这种需求的。请继续阅读评论,因为DescriptionAttribute在那里提到了。类似于:

public enum ErrorMessage
{
    [System.ComponentModel.Description("Request completed successfuly")]
    Success = 100,
    [System.ComponentModel.Description("Missing name in request.")]
    MissingName = 201
};

public static string GetDescription(this Enum en)
{
    Type type = en.GetType();

    System.Reflection.MemberInfo[] memInfo = type.GetMember(en.ToString());

    if (memInfo != null && memInfo.Length > 0)
    {
        object[] attrs = memInfo[0].GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute),
                false);

        if (attrs != null && attrs.Length > 0)
            return ((System.ComponentModel.DescriptionAttribute)attrs[0]).Description;
    }  

    return en.ToString();
}

static void Main(string[] args)
{
    ErrorMessage message = ErrorMessage.Success;
    Console.WriteLine(message.GetDescription());
}

0

你可以考虑从Dictionary派生,或者使用一个可以索引的Dictionary字段在代码中存储数据表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接