我有一个基类,我正在尝试使用Null对象模式来提供默认的记录器实现,然后可以在稍后阶段通过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周围有合同,以确保它永远不会为null。
有没有办法避免在所有派生类中重新提出这个事实,或者这仅仅是静态分析器的限制?
更新:最新版本的CodeContracts中已修复问题。此外,我不再需要抽象基类构造函数中的断言(行“Contract.Assert(Logger!= null);”)
答案 0 :(得分:0)
我刚刚测试了您发布的代码并且工作正常。您使用的是最新版本的Code Contracts(1.4.30707.2)吗?