C # предотвратить преобразование перечисления в int - PullRequest
1 голос
/ 14 января 2010

У меня есть перечисление, которое перечисляет целочисленные значения, возвращаемые из внешнего API для более легкого использования в моем коде. Но я не обязательно знаю целочисленные значения во время компиляции, поэтому у меня есть код, который подключает их при запуске программы и сохраняет их в словаре.

Я определил некоторые методы расширения для преобразования в / из целочисленных кодов, но эти целочисленные коды не совпадают с тем, что будет возвращено из преобразования в int. Если бы другой программист программировал с моим enum, я боюсь, что он попытался бы приводить к целым числам из целой привычки. И программа просто молча примет плохой код.

Есть ли способ предотвратить явное преобразование моего перечисления в / из int? Если нет, есть ли способ вызвать исключение, если кто-то попытается? Или подключите мои собственные функции преобразования? Или изменить базовое значение перечисления во время выполнения?

Ответы [ 2 ]

10 голосов
/ 14 января 2010

То, что вы пытаетесь, очень "грязно".

Используйте статический класс со значениями только для чтения вместо перечислений. Затем вы можете инициализировать значения в инициализаторе типа (или статическим методом):

public static class Foos
{
    public static readonly int First;
    public static readonly int Second;

    //...

    static Foos()
    {
        //For Example:
        First = DateTime.Now.Day;
        First = DateTime.Now.Month;
    }
}
1 голос
/ 14 января 2010

Другой способ сделать это, который может иметь смысл: определить Enum в вашей программе и сопоставить значения внешнего API с Enum в частных методах. Другими словами, не раскрывайте тип внешнего API где-либо внутри вашей объектной модели. Например:

public enum MyEnum { First, Second, Third };

public class MyApiWrapper
{
   private Dictionary<int, int> ExternalToInternal = new Dictionary<int, int>();
   private Dictionary<int, int> InternalToExternal = new Dictionary<int, int>();

   public MyApiWrapper(List<int> externalApiEnumValues)
   {
      foreach (int i = 0; i < externalApiEnumValues.Count; i++)
      {
         ExternalToInternal[externalApiEnumValues[i]] = i;
         InternalToExternal[i] = externalApiEnumValues[i];
      }
   }

   // obviously, your real method for calling the external API 
   // will do more than this.
   public void CallApi()
   {
      CallExternalApi(_EnumValue);
   }

   private MyEnum _ExternalEnumValue;
   public MyEnum EnumValue
   {
      get { return ExternalToInternal[_ExternalEnumValue]; }
      set { _ExternalEnumValue = InternalToExternal[value]; }
   }
}

Пока весь доступ к API осуществляется через этот класс (можно надеяться, что вы уже инкапсулировали доступ к внешнему API в классе), вы можете свободно использовать MyEnum везде внутри своего приложения, не заботясь о том, что другое программисты делают со значениями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...