Заставить разработчика использовать строку из специального класса

#c#

#c#

Вопрос:

У меня есть ObjectResult , который вернет сообщение об ошибке, если произойдет ошибка. Я бы хотел, чтобы разработчик не мог вводить в это свое собственное сообщение; им нужно использовать одну из набора предопределенных строк сообщений в специальном классе (просто для управления сообщением).

Например, я не хочу, чтобы это было возможно:

 ObjectResult obj = new ObjectResult() {Message = "xxx"};
  

Разработчик должен написать:

 ObjectResult obj = new ObjectResult() {Message = MessagesStore.SomeMessage};
  

Как я могу реализовать что-то подобное?

Ответ №1:

Вы могли бы объявить MessagesStore типа Enum внутри класса ObjectResult,

 enum MessagesStore
    {
    None,
    Error,
    ok,      
    };
  

Ответ №2:

Я предпочитаю использовать так:

     public class MessagesStore
    {
        public class Error
        {
            public const string Error1= "Error1";
            public const string Error2= "Error2";
        }
        public class Warning
        {
            public const string Warning1 = "Warning1";
            public const string Warning2 = "Warning2";
        }
    }
  

и тогда вы можете получить доступ к сообщению :

 ObjectResult obj = new ObjectResult() {Message = MessagesStore.Error.Error1};
  

Комментарии:

1. Пользовательский класс — гораздо лучшая идея. Перечисления не могут содержать строковые значения. 1

2. @LolCoder. Можем ли мы получить доступ MessagesStore к такому классу, не объявляя его статическим?

3. @LolCoder consts — хороший способ хранения строк, но это не решит проблему t4nhpt, потому что вы все равно можете назначить все, что захотите Message

4. @Dima: Извините, если я неправильно понял вопрос. Но, насколько я понимаю, операторы просто хотят получить доступ к сообщению из специального класса (содержит все сообщения), не вставляя сообщение напрямую, верно?

5. @LolCoder перечитайте вопрос еще раз, и, похоже, я могу ошибаться 🙂

Ответ №3:

Вы можете поместить коллекцию доступных строк в enum

 public enum MessageString
{
  [Description("Message one")]
  Message1,
  [Description("Message two")]
  Message2,
}
  

а затем либо измените Message свойство на возвращаемый MessageString тип, либо удалите конструктор по умолчанию и требуйте передачи MessageString параметра:

 public class ObjectResult
{
  public MessageString Message { get; set;}  
}

public class ObjectResult
{
  public string Message { get; private set;}  

  public ObjectResult(MessageString message)
  {
    Message = message.GetDescription();
  }
}
  

Ответ №4:

Объявите перечисление и украсьте записи атрибутами описания

 public enum MessagesStore
{ 
    [Description("Everything is Ok")]
    Ok,
    [Description("Everything is not Ok")]
    NotOk
}
  

Используйте следующий метод расширения

  public static class EnumExtensions
{
    public static string GetEnumDescription(this Enum value)
    {
        var fi = value.GetType().GetField(value.ToString());

        var attributes =
            (DescriptionAttribute[])fi.GetCustomAttributes(
            typeof(DescriptionAttribute),
            false);

        if (attributes != null amp;amp;
            attributes.Length > 0)
        {
            return attributes[0].Description;
        }

        return value.ToString();
    }
}
  

И пример использования:

 var ms = MessagesStore.Ok;
var desc = ms.GetEnumDescription();
  

desc с надписью «Все в порядке»

Комментарии:

1. Есть ли другой способ решить эту проблему? Потому что, если мы используем перечисление, это постоянная строка, которую нельзя изменить во время выполнения. Decription Например, если мне нужно указать путь к файлу на сообщение «Файл ‘abc.jpg » не существует» (abc.jpg предоставляется во время выполнения), это можно сделать с помощью расшифровки перечисления

Ответ №5:

Я бы объединил оба strings и enums , чтобы заставить пользователя использовать уже указанный текст. Это лишь немного другой подход, без использования Attributes :

Добавить в ObjectResult класс:

 public enum InfoMessages
{
   Error1,
   Error2,
   Warning1,
   Warning2
};
  

Затем отредактируйте ObjectResult конструктор класса с Messages параметром:

 public ObjectResult(InfoMessages message)
{
   SetMessage(message);
}
  

Затем создайте метод для установки правильной строки в соответствии с заданным перечислением:

 public void SetMessage(InfoMessages message)
{
    switch (message)
    {
       case InfoMessages.Error1: this.Message = "Error message for Error1"; break;
       case InfoMessages.Error2: this.Message = "Error message for Error2"; break;
       // ...
    }
}