Использование надежного RequiredIf с Enum

Мы пытаемся использовать аннотацию проверки Foolproof [RequiredIf], чтобы проверить, нужен ли адрес электронной почты. Мы также создали перечисление, чтобы избежать использования идентификатора таблицы поиска в ViewModel. Код выглядит следующим образом:

public enum NotificationMethods {
        Email = 1,
        Fax = 2
}

Затем в ViewModel:

[RequiredIf("NotificationMethodID", NotificationMethods.Email)]
public string email {get; set;}

В этом сценарии мы не получаем ошибку, когда электронная почта не заполнена, но выбрана в качестве типа уведомления. И наоборот, это работает так, как ожидалось:

[RequiredIf("NotificationMethodID", 1)]
public string email {get; set;}

Единственная другая ссылка на это, которую я нашел, находится здесь: https://foolproof.codeplex.com/workitem/17245


person Matthew    schedule 03.12.2014    source источник
comment
Можете ли вы показать нам, как выглядит это свойство "NotificationMethodID"?   -  person dbc    schedule 14.12.2014
comment
Это целое - public int NotificationMethodID {get; set;}   -  person Matthew    schedule 14.12.2014


Ответы (1)


Учитывая, что ваш метод NotificationMethodID возвращает int, причина сбоя вашей проверки заключается в том, что в c# каждый enum — это собственный тип, унаследованный от System.Enum. т.е. если ты сделаешь

var value = NotificationMethods.Email;
string s = value.GetType().Name;

Вы увидите, что s имеет значение "NotificationMethods", а не "Int32".

Если вы попытаетесь проверить равенство int с enum напрямую, вы получите ошибку компилятора:

var same = (1 == NotificationMethods.Email); // Gives the compiler error "Operator '==' cannot be applied to operands of type 'int' and 'NotificationMethods'"

Если вы сначала упаковываете значения enum и int (что происходит, когда они передаются в конструктор RequiredIfAttribute), то ошибки компилятора нет, но Equals() возвращает false, так как типы различаются:

var same = ((object)1).Equals((object)NotificationMethods.Email);
Debug.WriteLine(same) // Prints "False".

Чтобы проверить равенство базовых целочисленных значений, вы можете явно привести NotificationMethods.Email к целому числу перед упаковкой:

var same = ((object)1).Equals((object)((int)NotificationMethods.Email));
Debug.WriteLine(same); // Prints "True"

И в приложении атрибута:

[RequiredIf("NotificationMethodID", (int)NotificationMethods.Email)]
public string email {get; set;}

Вы также можете рассмотреть возможность использования значений const int вместо перечислений:

public static class NotificationMethods
{
    public const int Email = 1;
    public const int Fax = 2;
}
person dbc    schedule 14.12.2014
comment
Я дошел до вашего ответа, учитывая, что ваш метод NotificationMethodID возвращает int, прежде чем я понял свою ошибку новичка, спасибо. Я должен был уловить это по твоему комментарию. - person Matthew; 15.12.2014