C#使用冗余代码契约-先决条件

C# Usage of Redundant Code Contract-Preconditions

我没有通过阅读使用指南找到信息,所以我在这里问我的问题: 假设以下情况:

    /// <summary>
    /// Initalisiert eine neue Instanz des SettingsManager
    /// </summary>
    /// <param name="settingsRepo">Das SettingsRepository welches die Einstellungen enthält</param>
    public SettingsManager(ISettingsRepository settingsRepo)
    {
        Contract.Requires<ArgumentNullException>(settingsRepo != null, "The parameter settingsRepo cant be null");

        _settingsRepo = settingsRepo;
    }

    /// <summary>
    /// Lädt alle Einstellungen
    /// </summary>
    public void Load()
    {
        Contract.Requires<NullReferenceException>(_settingsRepo != null, "The repository cant be null");
        .
        .
        .
    }

其中 _settingsRepo 是 class SettingsManager 的全局私有字段。在构造函数中,我定义了 precondition,即参数 settingsRepo 不为 null。所以当 settingsRepo 等于 null 时抛出异常。但是方法 Load() 使用的字段 _settingsRepo 在实例化 期间肯定不是 null 。但是,我不知道_settingsRepo是否等于null,当Load()被使用时,我在方法Load()中定义的前提是否被认为是多余的,或者我应该休息一下。

尽管您没有向方法传递参数,但值得一提的是,一般规则是验证 public 方法的参数。

All reference arguments that are passed to externally visible methods should be checked against null. If appropriate, throw a ArgumentNullException when the argument is null.

If a method can be called from an unknown assembly because it is declared public or protected, you should validate all parameters of the method. If the method is designed to be called only by known assemblies, you should make the method internal and apply the InternalsVisibleToAttribute attribute to the assembly that contains the method.

这属于代码分析:CA1062:验证 public 方法的参数

但是由于您已经在 Load 函数存在所必需的不同位置验证了 _settingsRepo,因此您可以省略验证。但这可能会在发布时触发警告,我的建议是运行在发布代码之前进行代码分析

Read more

正如我在问题评论中提到的。您可以从 Load 方法中删除验证。 您正在使用的模式称为 Constructor Injection。 C'tor 注入背后的想法是您尝试创建的对象需要依赖项,如果您不提供依赖项,则不会有任何 default/alternative 行为。在您的情况下,情况似乎确实如此。

总结: 您在 C'tor 中验证了 _settingsRepo 不为空,因此您不需要在 [=13= 中再次验证它] 方法。

This is a very good book about DI,推荐大家阅读