Как мне сказать в кодовых контрактах С#, что внешний метод никогда не возвращает значение null?

У меня есть следующий фрагмент кода С#:

myClaimsIdentity.FindFirst(ClaimTypes.NameIdentifier).Value;

CodeContract знает, что myClaimsIdentity никогда не имеет значение null. Но он жалуется, что метод FindFirst(string) может возвращать значение null:

Предупреждение CodeContracts: возможен вызов метода для нулевой ссылки. Ожидаете ли вы, что System.Security.Claims.ClaimsIdentity.FindFirst(System.String) вернет ненулевое значение?

Я ожидаю этого, но как я могу сообщить об этом CodeChecker? Конечно, я не могу изменить FindFirst(string), так как он взят из внешней библиотеки.


person Rufus Buschart    schedule 11.05.2015    source источник
comment
Я бы пошел с Contract.Assume   -  person CodesInChaos    schedule 11.05.2015
comment
Как бы вы сделали это с результатом метода? У вас есть пример?   -  person Rufus Buschart    schedule 12.05.2015


Ответы (1)


Простой подход:

var nameIdentifier = myClaimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
Contract.Assume(nameIdentifier != null);
nameIdentifier.Value;

Контракты кода не будут пытаться доказать условие Assume, но будут использовать его при доказательстве других требований.

Вероятно, можно создать эталонную сборку контракта для внешнего кода с соответствующими Ensures пост-условиями. Группа кодовых контрактов делает это для типов BCL. Но я не знаю, как это сделать.

person CodesInChaos    schedule 12.05.2015
comment
Но помещать такое в контрактную сборку было бы ужасно неправильно. ClaimsIdentity.FindFirst может< /i> возвращает null, и в документации это разъясняется: или null, если совпадений не найдено. Но в конкретном приложении для определенного типа утверждения вы можете знать, что оно не вернет null. Contract.Assume — правильный инструмент для этой работы. - person ; 12.05.2015
comment
@hvd Я не знаком с этой библиотекой, поэтому не знаю, при каких обстоятельствах она может возвращать значение null. Если ClaimTypes.NameIdentifier всегда существует, можно написать Contract.Ensures(type != ClaimTypes.NameIdentifier || result != null). Если OP знает только, что оно не равно нулю, потому что значение всегда будет установлено в их приложении, тогда Contract.Assume будет правильным подходом. - person CodesInChaos; 12.05.2015
comment
Вы абсолютно правы - я должен сделать эту проверку здесь, чтобы быть на безопасном сайте. - person Rufus Buschart; 12.05.2015