Null Objectパターンを使用して、後の段階でIoCセッターインジェクションによって変更できるデフォルトのロガー実装を提供しようとしている基本クラスがあります。
public interface ILog
{
void Log(string message);
}
public class NoOpLogger: ILog
{
public void Log(string message)
{ }
}
public abstract class ClassWithLogger
{
private ILog _logger = new NoOpLogger();
protected ClassWithLogger()
{
Contract.Assert(Logger != null);
}
public ILog Logger
{
get { return _logger; }
set
{
Contract.Requires(value != null);
_logger = value;
Contract.Assert(Logger != null);
}
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(Logger != null);
}
}
public sealed class DerivedClass : ClassWithLogger
{
private readonly string _test;
public DerivedClass(string test)
{
Contract.Requires<ArgumentException>(!String.IsNullOrWhiteSpace(test));
_test = test;
// I get warning at end of ctor: "invariant unproven: Logger != null"
}
public void SomeMethod()
{
Logger.Log("blah");
}
}
コードで示しているように、私の問題は、派生クラスのコンストラクターの最後に、基本クラスから不変の「Logger!= null」オブジェクトが証明されていないという警告が表示されることですが、何も変更されていないことは明らかです。 Loggerプロパティ値と私は、セッターの周りにも契約を結んでおり、とにかくnullにならないようにしています。
すべての派生クラスでこの事実を反証する必要を回避する方法はありますか、それともこれは静的アナライザーの単なる制限ですか?
更新:CodeContractsの最新バージョンで問題が修正されました。また、抽象基本クラスコンストラクターのassertはもう必要ありません( "Contract.Assert(Logger!= null);"という行)