Учебный класс; Struct; Перечень путаницы, что лучше? - PullRequest
3 голосов
/ 11 мая 2010

У меня 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 голосов
/ 11 мая 2010

Лучше всего будет и класс, и перечисление. Тогда у вас может быть больше описательных идентификаторов, чем «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 как значение не соответствует ни одному из других случаев.)

3 голосов
/ 11 мая 2010

Я думаю, что выбор класса (как вы сделали) является хорошим решением. Вы можете сделать код немного более компактным и читабельным, если вы используете Dictionary<int, string> для отображения кодов на описания.

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

А RetrieveMessage:

return _dict[value];
0 голосов
/ 11 мая 2010

Это определенно будет медленнее (поскольку он использует Reflection), но говоря о компактности, я думаю, Перечисления с пользовательскими атрибутами подходит для этой потребности. Пожалуйста, продолжайте читать комментарии, так как там упоминается 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 голосов
/ 11 мая 2010

Возможно, подход на основе словаря будет выглядеть более элегантно.

    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 голосов
/ 11 мая 2010

Как насчет получения из словаря или сохранения таблицы данных в коде с использованием поля словаря, в которое можно индексировать?

...