我有一个基类,我在其中尝试使用 Null Object 模式来提供默认记录器实现,然后可以在稍后阶段通过 IoC setter 注入进行更改。
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 属性值,我也有围绕 setter 的合同,以确保它永远不会为空。
有什么办法可以避免在所有派生类中重新证明这一事实,或者这只是静态分析器的限制?
更新:问题已在最新版本的 CodeContracts 中得到修复。此外,我不再需要抽象基类构造函数中的断言(“Contract.Assert(Logger != null);”行)