FxCop - CA1034 错误 - 为啥?

Posted

技术标签:

【中文标题】FxCop - CA1034 错误 - 为啥?【英文标题】:FxCop - CA1034 error - WHY?FxCop - CA1034 错误 - 为什么? 【发布时间】:2009-07-22 20:43:10 【问题描述】:

我正在使用 FxCop 1.36 运行静态代码分析,并且不断收到 warning CA1034: NestedTypesShouldNotBeVisible。

如果父类被声明为内部或私有,我会理解,但它是公共的。为什么 TimerReset 被宣布为 public 会不好?

是我遗漏了什么,还是可以忽略?

感谢您的任何意见!

以下是导致此警告的代码摘录:

namespace Company.App.Thing

    public partial class Page : XtraPage
    
        public delegate void TimerResetDelegate(object sender, EventArgs e);
        private TimerResetDelegate _timerReset;

        public Page()
        
            InitializeComponent();
        

        public TimerResetDelegate TimerReset
        
            set
            
                if (null != (_timerReset = value))
                
                    checkBox.Click += new EventHandler(_timerReset);
                    textField.Click += new EventHandler(_timerReset);
                    textField.KeyDown += new KeyEventHandler(_timerReset);
                    TimeField.Click += new EventHandler(_timerReset);
                    TimeField.KeyDown += new KeyEventHandler(_timerReset);
                
            
        
    

【问题讨论】:

你为什么不使用EventHandler 这也是我的问题。 仅供任何好奇的读者参考:不要在这种“纯技术”属性TimerReset 上定义setget/set,最好将其写为event add/remove。 see MSDN 【参考方案1】:

一般来说,嵌套类型更难“发现”。

例如要使用您的嵌套类型,我将不得不编写以下内容

Page.TimerResetDelegate timer = new Page.TimerResetDelegate();

尽管上面是有效的 C# 代码,但它不像通常的类型用法那样读取。

当你想定义一个在内部使用的类型并且你会避免使用上面的代码时,通常会使用嵌套类型。这就是 FxCop 向您发出警告的原因。如果你愿意,你可以忽略它。就个人而言,我会将我的嵌套类型保持为私有。如果我希望调用者使用该类型,我会将它们移动到适当的名称空间。

【讨论】:

【参考方案2】:

为什么将 TimerReset 声明为 public 会很糟糕?

就像description states:

嵌套类型对于封装包含类型的私有实现细节很有用。用于此目的,嵌套类型不应在外部可见。

既然你用TimerReset 公开暴露TimerResetDelegate,我想这不是一个实现细节。

不要使用外部可见的嵌套类型进行逻辑分组或避免名称冲突;而是使用命名空间。

这使您看起来像是在使用嵌套类型进行分组。正如 FxCop 所说,请改用命名空间。

嵌套类型包括成员可访问性的概念,一些程序员并不清楚。

由于TimerResetDelegate 是代表,这并不真正适用。

TimerResetDelegate 移动到它自己的 TimeResetDelegate.cs 文件中,并将其放入您的 Company.App.Thing 命名空间中。然后,它不再嵌套。

当然,最好只使用EventHandler 而不是定义自己的委托类型。

【讨论】:

【参考方案3】:

这是因为您的委托是一种类型,但它是在 Page 类中定义的。我只是在 Company.App.Thing 命名空间中定义它,但这不是问题。如果你正在编写一个 API,它只会让它有点混乱,仅此而已。

另外,这样返回委托有点奇怪,但我想我真的不知道你想要完成什么。

【讨论】:

它不是返回代表。这是一个仅限设置的属性,用于设置/注册处理程序。 Page.TimerReset = new handler(...)。我想 OP 不知道可以在事件中编写添加/删除,这就是他决定使用属性设置器的原因。【参考方案4】:

恕我直言,这是一个可以忽略的 FxCop 规则。

从 CLR 级别来看,拥有嵌套类并没有错。它只是添加到 FxCop 中的一个指导性规则,因为作者认为与使类不嵌套相比,它更不可用或设计更差。

【讨论】:

FxCop 警告说嵌套类型是公开的,而不是使用嵌套类型。【参考方案5】:

显然它不喜欢嵌套类的想法,因为它们可能会在您的 Page 类的上下文之外使用。

我个人原则上同意这一点,尽管我可以想象一些可能需要的例外情况。

【讨论】:

这没有回答问题。 这没有回答问题。基本上,它只是总结了问题。

以上是关于FxCop - CA1034 错误 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 FxCop 不报告 CA2000 对于这种未处置的类实例的琐碎情况?

.NET Framework FxCop 规则 CA1401 PInvokesShouldNotBeVisible 规则 - 为啥存在此规则?

FxCop VS2013 有人知道警告标识符是啥吗?

代码分析 (FXCop) 命令行差异

FxCop 自定义规则文档。为啥找不到我的网址?

FXCop 违规 CA1716 IdentifiersShouldNotMatchKeyword