Допустим, у меня есть метод public void Foo(string bar)
, который вызывающий не должен вызывать с нулевым значением bar
. Допустим, у меня также есть метод, называемый private void FooImpl(string bar)
, который выполняет фактическую работу Foo
. Это, конечно, FooImpl
, что на самом деле требует ненулевого значения bar
, хотя Foo
является общедоступным интерфейсом. Допустим, я хочу применить ненулевое значение с помощью контрактов кода .NET 4.0.
Куда мне положить контракт?
Если я сделаю это:
public void Foo(string bar)
{
this.FooImpl(bar);
}
private void FooImpl(string bar);
{
Contract.Requires<ArgumentNullException>(bar != null);
// Something that requires non-nullness, e.g.:
bar.Contains("test");
}
затем статический контролер жалуется, что Foo
вызывает FooImpl
с возможно нулевым значением, и предлагает добавить ненулевой контракт к Foo
. Итак, я полагаю, я не могу делегировать свою проверку контракта / создание исключений методам реализации.
Но если я попытаюсь поместить его в общедоступный интерфейс, т.е.
public void Foo(string bar)
{
Contract.Requires<ArgumentNullException>(bar != null);
this.FooImpl(bar);
}
private void FooImpl(string bar);
{
bar.Contains("test");
}
тогда статический контролер жалуется, что FooImpl
вызывает Contains
для возможно нулевого значения - хотя единственное место, из которого FooImpl
когда-либо вызывается в коде, это Foo
, который сам по себе гарантирует, что он никогда не будет вызывать FooImpl
с нулевым значением.
Итак, мне нужно включить один и тот же контракт дважды? Или я должен просто игнорировать статическую проверку? Я знаю, что это своего рода источник напряженной работы, и на него нельзя полагаться, но я надеюсь, что у него был какой-то способ справиться с этим базовым и, по-видимому, распространенным сценарием.