С # настраиваемый атрибут - отсутствуют логические параметры по умолчанию false?

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

[DBDataTypeAttribute(FieldType = "varchar(1000)",AllowNulls=false)]
public String ERLineID;

У меня есть код, который ищет это, например:

foreach (FieldInfo field in userType.GetFields())
{
    currentDefaultDataType = createtabledefaultdatatype;
    currentDefaultAllowNulls = createtabledefaultallownulls;

    DBDataTypeAttribute attribute =
        (DBDataTypeAttribute)Attribute.GetCustomAttribute(field, typeof(DBDataTypeAttribute));

    if (attribute != null)
    {
        // at least one of createtabledefaultdatatype or createtabledefaultallownulls exists
        if (attribute.FieldType != null)
        {
            currentDefaultDataType = attribute.FieldType;
        }
        if (attribute.AllowNulls != null)
        {
            currentDefaultAllowNulls = attribute.AllowNulls;
        }
...

Значение createtabledefaultallownulls берется из файла конфигурации и имеет значение true. Однако я обнаружил, что когда я оставляю «allownulls» в своем атрибуте, он заменяет мое «истинное» значение по умолчанию на значение false.

Если бы я указал в своем атрибуте только FieldType, я бы ожидал, что if (attribute.AllowNulls! = Null) оценит false. Вместо этого он говорит, что значение не равно нулю, и говорит, что attribute.AllowNulls имеет значение false. Таким образом, он перезаписывает мое значение по умолчанию, даже если значение не было указано. Это как-то связано с тем, что bools не допускают значения NULL? Или, возможно, если вы добавите атрибут, вы должны явно определить все параметры в нем?

Обходной путь, который я рассматриваю, - это просто сделать его строкой и bool.parsing ее, но это звучит не очень элегантно! Есть ли способ лучше?


person Glinkot    schedule 13.06.2011    source источник


Ответы (2)


Вам нужно третье состояние, отличное от истинного или ложного, и оно не будет установлено.

Измените AllowNulls на логическое значение, допускающее значение NULL, bool ?. Затем AllowNulls разрешит значения null, true или false. Если пользователь не укажет его в атрибуте, он будет инициализирован значением NULL. Таким образом, ваш attribute.AllowNulls != null будет делать именно то, что вы хотите, и пользователи по-прежнему смогут устанавливать значение true или false.

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

 private bool? allowNulls = null;
 public bool AllowNulls  {
    get { return allowNulls.GetValueOrDefault(false); }
    set { allowNulls = value; }
 }
 public bool AllowNullsWasSet() { return allowNulls.HasValue; }
person shf301    schedule 13.06.2011
comment
Спасибо. Это то, что я изначально подумал, было бы хорошо, но когда я изменил частные / общедоступные части моих атрибутов на bool? Я получаю сообщение об ошибке «Ошибка 4« AllowNulls »не является допустимым аргументом именованного атрибута, потому что это недопустимый тип параметра атрибута». Это с объявлением атрибута: private bool? allownulls; общественный бул? AllowNulls {получить ... - person Glinkot; 13.06.2011
comment
Вы правы, нулевые значения не допускаются для атрибутов. Не осознавал этого. См. stackoverflow.com/questions/1416126/ - person shf301; 13.06.2011
comment
Интересная альтернатива, спасибо за это. Я отмечу это как ответ, поскольку он предоставляет альтернативный код для достижения желаемого результата. Со своей стороны, я думаю, что выберу веревочку! :) - person Glinkot; 13.06.2011

Если я не неправильно понимаю ваш вопрос, он всегда будет ложным, если вы не инициализируете его иначе. Поскольку bool - это значение, по умолчанию для него установлено значение false. Таким образом, без инициализации он останется таким же. Кроме того, attribute.AllowNulls! = Null не должен компилироваться, поскольку тип значения никогда не может быть нулевым. Null зарезервирован для ссылочных типов, так как это сама ссылка, которую он сравнивает для своей проверки.

person hivie7510    schedule 13.06.2011
comment
Привет, привет, в основном мой оператор if пытался проверить, имеет ли атрибут значение allownulls, указанное для этого поля. Учитывая то, что вы упомянули, есть ли способ определить, существует ли реальное значение, указанное пользователем для логического? Атрибут attribute.AllowNulls! = Null компилируется, но, как вы говорите, не выполняет функцию. - person Glinkot; 13.06.2011
comment
Я думаю, вы упомянули, что загрузили это из конфигурации, поэтому можете сделать это строкой. - person hivie7510; 13.06.2011
comment
Я думаю, вам придется его абстрагировать, а затем использовать конструктор атрибута для его установки. Тогда у вас может быть еще один бит, который показывает, установлен он или нет. Это громоздко, если вы не используете bool, допускающее значение NULL (bool?) - person hivie7510; 13.06.2011
comment
Возможно, это было непонятно, я бы сделал свойство для атрибута, чтобы при его установке вы также могли установить бит, показывающий, что значение установлено, а не просто установлено по умолчанию. Это даст вам три состояния, которые вы ищете (Not Set, False, True). - person hivie7510; 13.06.2011
comment
Спасибо. Я согласен, что логическое значение, допускающее значение NULL, было бы элегантным способом, но, к сожалению, это создает ошибку; возможно, логические значения, допускающие значение NULL, не допускаются в качестве параметров атрибутов. - person Glinkot; 13.06.2011
comment
Какое исключение вы получаете? Мне трудно поверить, что какой-либо тип не разрешен, поскольку атрибут - это просто класс, как и любой другой. Вы используете HasValue до того, как получите доступ к значению? Настоящий вопрос стоит, в чем ошибка, потому что я уверен, что это не проблема. - person hivie7510; 13.06.2011
comment
attribute.AllowNulls! = null компилируется нормально, потому что он заключен в коробку, но, на ваш взгляд, он никогда не будет нулевым. Использование bool не должно быть проблемой? но решение отслеживания, если свойство установлено, все же намного лучше, чем строковый вариант. - person Brian ONeil; 13.06.2011
comment
Взгляните на этот пост, чтобы узнать о типах, допускающих значение NULL. stackoverflow.com/questions/3765339/ - person hivie7510; 13.06.2011
comment
Спасибо за вашу помощь. Думаю, для простоты я использую строку. ваше здоровье - person Glinkot; 13.06.2011
comment
Могу ли я получить одобрение на свой ответ? - person hivie7510; 13.06.2011