CA1033 with Properties

本文关键字:Properties with CA1033 | 更新日期: 2023-09-27 18:09:55

当我使用'Microsoft管理的推荐规则'规则集运行代码分析(VS2013)时,我为类库获得的唯一警告类型为CA1033: '接口方法应该由子类型调用'。但是我不明白这种情况下的规则:

/// An object that has a chemical formula
public interface IChemicalFormula
{ 
    /// The chemical formula of the object
    ChemicalFormula ChemicalFormula {get;}       
}
public class ChemicalFormula: IChemicalFormula
{         
    ChemicalFormula IChemicalFormula.ChemicalFormula
    {
        get { return this; }
    }
}

文档建议使用相同的名称创建受保护的方法,以便派生类型可以访问它,但不能将方法命名为与封闭类型相同的方法。他们还建议将类设置为密封的,但在这种情况下我不希望它被密封。这是一个忽略这条规则的时候,还是有一个适当的方法来处理它?

编辑

为了澄清为什么类/接口是这样设计的,我有另一个类,Peptide,它包含一个IChemicalFormula[]数组来存储修改。并非所有的修改都必须直接来自ChemicalFormula,但它们需要实现IChemicalFormula接口。因此,如果我用一些分子(例如H2O)修改肽的实例,那么ChemicalFormula类也需要实现IChemicalFormula

CA1033 with Properties

规则的描述:

考虑一个显式实现公共接口的基类型方法。派生自基类型的类型可以访问继承的接口方法只能通过引用当前实例(c#中的),它被强制转换为接口。如果推导出类型重新实现(显式地)继承的接口方法不能再访问基实现。通过电话当前实例引用将调用派生实现;这会导致递归并最终导致堆栈溢出。

我认为你应该考虑评估一下这个属性的用途。这是一个很好的例子,可以使用TDD来找出接口。下面有一些可能的用法(以及一些无效的用法)。我还不知道你想通过看这些来达到什么目的。

在您的示例中,假设另一个类NewChemicalForumla派生自ChemicalForumula,并引用ChemicalFormula,这意味着什么?

public class NewChemicalFormula: ChemicalFormula
{         
    public void Method()
    {
        Console.WriteLine("{0}", ChemicalFormula.GetType());       // Compile error
        Console.WriteLine("{0}", this.ChemicalFormula.GetType());  // Effectively same as above, compile error
        Console.WriteLine("{0}", ((IChemicalFormula)this).ChemicalFormula.GetType()); // Works, is that what you intend?
    }
}

现在从类外部来看,有两种可能:

  1. 当你有一个派生类的句柄时:

    new NewChemicalFormula().ChemicalFormula.GetType() // Error
    

    // This works, is that what you intend to achieve?
    ((IChemicalFormula)new NewChemicalFormula()).ChemicalFormula.GetType()  
    
  2. 当您已经拥有IChemicalFormula的句柄时。在这种情况下,ChemicalFormula似乎是多余的:

    IChemicalFormula formula = new NewChemicalFormula();
    Console.WriteLine("{0}", formula.GetType());                 // Works, returns NewChemicalFormula
    Console.WriteLine("{0}", formula.ChemicalFormula.GetType()); // Works, returns NewChemicalFormula
    Console.WriteLine("{0}", formula.ChemicalFormula.Method());  // Compile error
    

formula.ChemicalFormula.Method()会导致错误,因为在使用Method()之前必须将其强制转换为NewChemicalFormula。仅仅因为属性返回this并不能帮助解决这个问题。

所以FXCop警告是值得考虑和评估的设计。