2

我有一个基类,我在其中尝试使用 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);”行)

4

1 回答 1

0

我刚刚测试了您发布的代码,它运行良好。您是否使用最新版本的代码合同 (1.4.30707.2)?

于 2010-08-18T21:09:06.073 回答