Переключение между двумя типами перечисления?

Итак, я пишу приложение на C# с использованием Compact Framework 2.0 и хотел узнать, могу ли я сделать что-то более простое, чем я планировал в своей голове.
Есть ли ответы на другие фреймворки, полные или компактные , но не для этого, я все равно хотел бы их услышать, поэтому на данный момент теги не включают компактную платформу 2.0.

По сути, пользователь сможет выбрать, что элемент, для которого он хочет установить настройки, относится к типу A или типу B, а затем какую конкретную настройку он хочет использовать/установить в соответствии с этой классификацией. Я хочу использовать перечисления, в основном, для того, чтобы код оставался разборчивым, так как это для моего рабочего места, и люди должны иметь возможность читать его, если меня нет рядом.

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

enum EnumTypes
{
    A, B,
    Num_Types,
}
enum EnumA
{
    Setting1 = 0, Setting2, Setting3, //and so on...
    Num_A_Settings, //WILL be different from B
}
enum EnumB
{
    Setting1 = 0, Setting2, Setting3, //and so on...
    Num_B_Settings, //WILL be different from A
}

Ниже приведен пример функций/свойств класса, которые будут использовать значения для выполнения своей работы, явно показывая только то, что потребуется другим классам.

public class SettingClass
{
    public EnumTypes TypeUsed {/*basic get/set for property*/}
    public int SelectedSettingIndex {/*basic get/set for property*/}
    private ClassX[][] _settingsData = new ClassX[(int)Num_Types][];

    public SettingClass()
    {
        for(int i = 0; i < (int)EnumTypes.Num_Types;i++)
        {
            if((EnumTypes)i == EnumTypes.A)
            {
                _settingsData[i] = new ClassX[(int)EnumA.Num_A_Settings];
                //for loop for initializing each ClassX instance for A
            }
            else if((EnumTypes)i == EnumTypes.B)
            {
                _settingsData[i] = new ClassX[(int)EnumB.Num_B_Settings];
                //for loop for initializing each ClassX instance for B
            }
    }

    //just an example
    public IncrementSetting()
    {
        if(TypeUsed == EnumTypes.A)
        { /*range checking using Num_A_Settings, increments SelectedSettingIndex*/ }
        else if(TypeUsed == EnumTypes.B)
        { /*range checking using Num_B_Settings, increments SelectedSettingIndex*/ }
    }
}

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

Есть ли способ вместо того, чтобы выставлять только int для «settingIndex», я мог бы выставить перечисление и показать значения EnumA или EnumB всем, кто использует этот класс?

Прямо сейчас все, что должно было получить выбранный индекс настройки, должно было бы в основном сказать: «Какой тип, A или B? .." или аналогичный, который может быстро усложниться ВНЕ этого класса, предназначенного для инкапсуляции всей работы.

Я думал о том, есть ли какое-то наследование, которое я мог бы сделать или подобное, но я сомневаюсь, что есть.


person Peter Lacerenza    schedule 31.07.2012    source источник
comment
Пользователи (программисты) решают, хотят ли они работать с EnumA или EnumB во время написания кода, или это решение во время выполнения?   -  person George Mamaladze    schedule 31.07.2012
comment
Не уверен, что смогу ответить на этот вопрос правильно... Это не его использование, но это хорошая аналогия: представьте себе страницу меню, говорящую, какое меню вы хотите просмотреть, меню A или меню B? затем выбранное меню (просмотр настроек в конкретном меню). Пользователь (т.е. оператор, а не программист) всегда может вернуться и сказать Хорошо, теперь давайте посмотрим на меню B, а затем ему будут показаны настройки для меню B. Опять же, это аналогия, я не уверен, что мне разрешат использовать конкретику.   -  person Peter Lacerenza    schedule 31.07.2012
comment
Другой хорошей аналогией, возможно, более точной, может быть список немецких автомобилей или список японских автомобилей с указанием вверху: «Вы хотите немецкие или японские автомобили?» перед тем, как показать их список, и использовать перечисление двух типов в качестве индекса для получения данных о каждом типе автомобиля, т. е. carData[(int)CarSource.Japanese][(int)GermanCars.ToyotaCarolla].VehicleHeight.   -  person Peter Lacerenza    schedule 31.07.2012


Ответы (2)


Вместо массива вы можете использовать Dictionary<Enum,ClassX>. Затем, пока вы используете Enum вместо int везде, где вы используете свои enum, вы будете иметь полную информацию о типе и сможете различать отдельные значения перечисления.

C# enum имеет интересное свойство, заключающееся в том, что он может действовать как int везде, где вам это нужно из соображений производительности, но он счастлив быть полноценным object, когда вам нужно иметь информацию о типе, прикрепленную к его значению.

Некоторый код LINQPad, который я только что использовал для проверки всего этого:

void Main()
{
  Dictionary<Enum,object> dict = new Dictionary<Enum,object>();
  dict.Add(asdf.lkj,null);
  dict.Add(qwer.oiu,null);
  Console.WriteLine(dict.ContainsKey(qwer.oiu));
  Console.WriteLine(dict.ContainsKey(asdf.lkj));
  Console.WriteLine(dict.ContainsKey(qwer.zxcv));
}

enum asdf {
  lkj
}

enum qwer {
  oiu,
  zxcv
}

и его вывод

True
True
False
person sblom    schedule 31.07.2012

В следующем примере значение перечисления переносится и разворачивается с помощью отражения. Близко ли оно к тому, что вы ищете?

namespace App
{
  class Program
  {
    static void Main(string[] args)
    {
      var val = new EnumWrapper(B.f);
      Enum en = val.EnumVal;
      Console.WriteLine("{0}.{1}",en.GetType().Name,en);
    }
  }
  enum EnumType { A, B }
  enum A { a, b, c = 34, d = 12 }
  enum B { a, b, e = 54, f = 56 }
  class EnumWrapper
  {
    public EnumWrapper(Enum i)
    {
      type = (EnumType) Enum.Parse( typeof(EnumType), i.GetType().Name );
      index = Convert.ToInt32(i);
    }
    public EnumType type;
    public int index;
    public Enum EnumVal {
      get {
        Enum c = (Enum)Enum.ToObject(
          Type.GetType(
            "App." + type
          ), index
        );
        return c;
      }
    }
  }
}
person Julien Ch.    schedule 31.07.2012