С#: Добавляем управляемые константы

среда, 3 июня 2009, Oleksandr Reminnyi

Представте ситуацию, когда в вашем приложении есть наборы чисел, представляющих собой некоторые константы. Они являються частью конфигурационного класса.

Какова стандартная реализация?

Конечно что-то типа:

class MyConstatInts
{
    public static readonly int value1 = 1;
    public static readonly int value2 = 2;
    public static readonly int value3 = 3;
   
    //...
}

Ситуация проста и хороша, но это если у нас будет только один файл констант. Все новые значения придеться добавлять в него же. А если добавлять в другой даже класс, нужно будет следить, чтобі значения констант не повторялись.
   
И тут можно столкнуться с ситуацией, когда файл будет
    а - ужасно переполнен.
    б - практически не структуризирован.
    в - можно случайно неправильно присвоить значение константе и будет value3 == value17.

Такое часто достигаеться при архитектуре, построенной на сообщениях
Теперь рассмотрим такой вариант:
   
class MyConstatInts
{
    public static int value1;
    public static int value2;
    public static int value3;
}

class MyConstatInts2
{
    public static int value4;
    public static int value5;
    public static int value6;
}

А значений внутри нету. Да, действительно нет.


Для начала создадим некоторый атрибут... 

    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class MyAttribute : Attribute

    {
    };


и добавим этот атрибут к нашим константам:  

[MyAttribute]

class MyConstatInts
{
    public static int value1;
    public static int value2;
    public static int value3;
}

Инициализация:

Используем частично модифицированный хелпер, описаный здесь

Добавлем к нему функцию Init:

 private static int _id;

      public static void Init()
      {
          //iterate all assemblies
          foreach (Assembly assembly in assemblies)
          {
              Type[] types = assembly.GetTypes();
              foreach (Type type in types)
              {
                  if (IsMyClass(type))
                  {
                      FieldInfo[] fields = type.GetFields();
                      foreach (FieldInfo fieldInfo in fields)
                      {
                          if (fieldInfo.FieldType == typeof(int))
                          {
                              int newID = System.Threading.Interlocked.Increment(ref _id);
                              fieldInfo.SetValue(null, _id);
                          }
                      }
                  }
              }
          }
      }


      private static bool IsMyClass(Type type)
      {
          object[] attributes = type.GetCustomAttributes(typeof(MyAttribute), true);
          return (null != attributes && attributes.Length > 0);
      }

Для тестирования:

static void Main(string[] args)
        {
            ParseAssemblyList();
            Init();

            Console.WriteLine(MyConstatInts.value2.ToString());
            Console.ReadLine();
        }

На экране появиться 2 :). А кто не верит - смотрите приложеный файл ;).

Таким образом в классах даже и имена переменых могут быть одинаковыми (в разных классах), и... много еще чего... но значения будут разные.

This is some text! This is some text! This is some text! This is some text!


Ищите нас в интернетах!

Комментарии

Свежие вакансии