4

我有一个这样的基类:

 public class BaseModalCommand
 {

    protected object m_commandArgument;
    protected int m_commandID;
    protected int m_enableUIFlags;

    public virtual void OnIdle()
    {
    }

    public virtual void OnResume()
    {
    }

    public virtual void OnStart(int commandID, object argument)
    {
    }

    public virtual void OnStop()
    {
    }



    public virtual int EnableUIFlags
    {
        get
        {
            return this.m_enableUIFlags;
        }
    }
}

虚拟方法将在派生类型中被覆盖。如果我通过 FxCop 运行它,它会抱怨没有声明可见的实例字段,并建议将其更改为私有并将其公开为受保护的属性。

有什么想法吗?我认为可以忽略此消息。

4

6 回答 6

12

对于任何类,客户端代码都有两种用途:引用您的类的代码和继承您的类的代码。人们普遍认为第二种使用是迄今为止最紧密耦合的。你班级的变化直接影响他们的内部机制。像这样暴露受保护的成员意味着基类中的更改将影响派生类的工作方式,如果不比较每个基类和派生类的代码,则无法预测。同样糟糕的是,您的派生类可以修改基类的内部结构。

如果您真的想像这样公开内部数据成员,请将私有数据成员包装在受保护的属性中(如 gisresearch 建议的那样)。这些属性(以及任何受保护的方法)构成了类的继承接口。与暴露给外部客户端的任何接口一样(无论是通过定义公共方法和属性,还是通过显式接口实现),这个接口是您需要管理的,尤其是在较大的代码库中。界面可以更改,但应作为有意识的决定进行更改。

如果直接使用受保护的数据成员,则对基类和派生类之间的依赖关系的控制要少得多。相信我:甚至无法确定更改可能产生的影响可能是一件非常不愉快的事情。

于 2009-04-22T19:32:05.343 回答
7

作为最佳实践,您的类字段应标记为私有并包含在 getter/setter 属性中

所以而不是

protected object m_commandArgument;

采用

private object m_commandArgument;

protected object CommandArgument {get; set;}

这样做有几个优点,但一个简单的用法是在你的 setter 中进行异常处理/验证。

例如

private string _email;
protected string Email
{ 
   get { return _email; }
   set 
   {
       if(value.IndexOf("@") > 0)
           _email = value;
       else
            throw new ArgumentException("Not a valid Email");
   }
}
于 2009-04-22T19:31:43.083 回答
6

FxCop 的建议是合理的。您不想将受保护的字段直接暴露给派生类。由基类管理的状态应该由基类管理——决不能被任何派生类直接修改。

于 2009-04-22T19:27:14.217 回答
1

使用属性。将成员变量更改为私有,然后为每个成员变量设置受保护的属性。

问候,
弗兰克

于 2009-04-22T19:30:51.930 回答
0

基本上,FxCop 建议您应该这样做

private object m_commandArgument;

protected object CommandArgument
{
   get { return m_commandArgument; }
   set { m_commandArgument =value}
}

这是基于 OO 封装规则(三个 OO 规则之一)。您可能希望在分配之前检查该值,并且您希望确保这不是由派生类直接操作的。

于 2009-04-22T19:30:21.917 回答
0

Paul Alexander 是正确的,FxCop 也是如此。

您希望将字段设为私有并通过属性公开它们,以防止派生类自行更改变量。强制它们通过属性使基类有机会验证和/或拒绝任何修改。

于 2009-04-22T19:32:12.287 回答