2010-04-02 2 views
1

У меня есть 3 участника-структуру, которая состоит из следующих действий:искать константы на основе значения

[StructLayout(LayoutKind.Sequential, Size=1)] 
public struct BigBlueReasonCodes 
{ 
    public const int ABC_REASONCODE_DESCRIPTION001 = 1000; 
    public const int ABC_REASONCODE_DESCRIPTION002 = 1005; 
    public const int ABC_REASONCODE_DESCRIPTION003 = 1010; 
    public const int DEF_REASONCODE_DESCRIPTION004 = 2001; 
    public const int DEF_REASONCODE_DESCRIPTION005 = 2010; 
    public const int DEF_REASONCODE_DESCRIPTION006 = 2013; 
    public const int GHI_REASONCODE_DESCRIPTION007 = 3050; 
    public const int GHI_REASONCODE_DESCRIPTION008 = 3050; 
    public const int GHI_REASONCODE_DESCRIPTION009 = 3052; 
    public const string JKL_REASONCODE_DESCRIPTION010 = "XYZ"; 
    public const string GHI_REASONCODE_DESCRIPTION011 = "ST"; 


    static BigblueReasonCodes(); 
} 

Я пытаюсь посмотреть описание причины (имя поля) на основании кода причины (значение), поэтому мой класс может сделать, как коснуться:

string failureReason = GetReasonDescription(reasoncode); 

Somethings упоминания некоторые имеют ИНТ значения, а некоторые имеют строковые значения. Меня беспокоят только те, у которых есть значения int. Я также хочу только тех, которые начинаются с GHI_, если это возможно, но не большого.

+0

Я вижу, что они были достаточно любезны, чтобы иметь значение, означающее множественные вещи, поэтому 3050 может означать GHI _... 007 и GHI _... 008 man oh man. –

ответ

6

Вы можете решить это с помощью отражения, анализируя-структуру:. пример

public string GetReasonDescription(int reasonCode) 
{ 
    return 
     typeof(BigBlueReasonCodes) 
      .GetFields(BindingFlags.Public | BindingFlags.Static) 
      .Where(field => field.FieldType == typeof(int)) // Filter int values 
      .Where(field => field.Name.StartsWith("GHI")) 
      .Where(field => (int) field.GetValue(null) == reasonCode) 
      .Select(field => field.Name).First(); // Assuming a field must exists 
} 

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

[Test] 
public void GetReasonDescriptionTest() 
{ 
    string reasonDescription = GetReasonDescription(3050); 
    Assert.That(reasonDescription, Is.EqualTo("GHI_REASONCODE_DESCRIPTION007")); 
} 
+0

+1: Вы можете использовать GetFields (BindingFlags.Public | BindingFlags.Static), чтобы просто вернуть статические общедоступные поля ... –

+0

@Reed Copsey, спасибо! Он описывает это лучше, и это безопаснее. Обновил мой ответ соответственно. – Elisha

+0

Отлично! Большое спасибо. Из-за кода, имеющего несколько описаний, я только что вернул IEnumerable и покажу все, что соответствует. Коды действительно были сделаны для потребления, как если бы (rc == REASONCODE_DESCRIPTON), я думаю. –

4

Похоже, что целые константы должны быть enumeration (или несколькими перечислениями) - это также позволит преобразовать в целые числа и из них.

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

+0

перечисление отсутствует, потому что тот же код имеет несколько значений. –

+0

@Joel. Это должно быть толчком относительно того, используете ли вы перечисление или константу, за исключением существующего кода. Так же, как вы не можете иметь две константы с одинаковым именем, у вас не может быть двух перечислений с тем же именем. – Thomas

1

Если вы фаршированные целые значения в перечислении вместо констант, вы могли бы сделать

public enum BigBlueReasonCode 
{ 
    ABC_REASONCODE_DESCRIPTION01 = 1000, 
    ABC_REASONCODE_DESCRIPTION01 = 1005, 
    ABC_REASONCODE_DESCRIPTION01 = 1010, 
    DEF_REASONCODE_DESCRIPTION01 = 2001, 
    DEF_REASONCODE_DESCRIPTION01 = 2010, 
    DEF_REASONCODE_DESCRIPTION01 = 2013, 
    GHI_REASONCODE_DESCRIPTION01 = 3050, 
    GHI_REASONCODE_DESCRIPTION01 = 3051, 
    GHI_REASONCODE_DESCRIPTION01 = 3052 
} 

var failureCode = Enum.GetName(reasoncode) 

(Правда, как этот код не будет работать, потому что у вас есть дубликаты имен, но это не будет компиляции как константы либо)

+0

Почему не 'reasoncode.ToString()'? –

+0

Я предполагаю, что «reasonCode» в этом контексте является числовым. I.e, пользователь прошел в Enum.GetName (2010). – Thomas

+0

, пожалуйста, префикс комментариев с @Steve, чтобы я получил уведомление. Если это перечисление без флага и оно установлено в одно из его определенных значений, то reasoncode.ToString() с возвратом имени. Если это не одно из заданных значений, оно возвращает номер. Для перечислений флагов на самом деле делает удивительно хорошую работу по возврату списка выбранных параметров с разделителями-запятыми. –

Смежные вопросы