[FxCop.设计规则] 3. 避免定义空的接口
2005-05-24 21:38 Colin Han 阅读(1273) 评论(0) 编辑 收藏 举报3. 避免定义空的接口
原文引用:
Avoid empty interfaces
Rule Description Interfaces define members that provide a behavior or usage contract. The functionality described by the interface can be adopted by any type, regardless of where the type appears in the inheritance hierarchy. A type implements an interface by providing implementations for the interface's members. An empty interface does not define any members, and as such, does not define a contract that can be implemented. If your design includes empty interfaces that types are expected to implement, you are most likely using an interface as a marker, or a way of identifying a group of types. If this identification will occur at runtime, the correct way to accomplish this is to use a custom attribute. Use the presence or absence of the attribute, or the attribute's properties, to identify the target types. If the identification must occur at compile time, then using an empty interface is acceptable. How to Fix Violations Remove the interface or add members to it. If the empty interface is being used to label a set of types, replace the interface with a custom attribute. When to Exclude Messages It is safe to exclude a message from this rule if the interface is used to identify a set of types at compile-time. Example Code The following example shows an empty interface. [C#] ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
|
引起的原因:
一个Interface没有定义任何接口,并且没有从任何接口继承。
描述:
一个接口提供了一组行为和使用契约(usage contract),任何一个类型都可以实现这个Interface, 而不需要考虑这个类型的继承层次。一个类型通过实现接口的成员而实现这个接口。一个空的接口没有定义任何成员,因此,也就没有任何契约能够被实现。
如果你的设计包含一个空的接口,并且希望一些类型实现这个接口,你很可能希望使用这个接口作为一个标记来标示一组类型。如果你只需要区分这些类型在运行时,一个更佳的解决方式是使用自定义属性(attribute)。使用有或没有一个属性或通过属性的字段(Property)去标示一组类型。如果你希望这种标示能够被使用在编译时,就只好使用空接口了。
修复:
移除这个接口或添加必要的成员到这个接口。如果这个接口被用来在运行时标示一组类型,将它替换为自定义属性。
译注:
自定义属性是.NET新引入的一种开发元素,通过将自定义属性和应用程序元数据保存在一起,开发人员可以获得类似自定义关键字的能力。以下是MSDN中对于属性的描述:
如果您使用过 C++,您或许对包含关键字(如 public 和 private)的声明比较熟悉。这些关键字提供有关类成员的附加信息,还通过描述类成员对其他类的可访问性来进一步定义类成员的行为。由于编译器被显式设计为识别预定义关键字,因此传统上您没有机会创建自己的关键字。但是,公共语言运行库允许您添加类似关键字的描述性声明(称为属性)来批注编程元素,如类型、字段、方法和属性。 为运行库编译代码时,该代码被转换为 Microsoft 中间语言 (MSIL),并同编译器生成的元数据一起被放到可移植可执行 (PE) 文件的内部。属性使您得以向元数据中放置额外的描述性信息,并可使用运行库反射服务提取该信息。当您声明从 System.Attribute 派生的特殊类的实例时,编译器创建属性。 .NET Framework 出于多种原因使用属性并通过它们解决若干问题。属性可以描述如何序列化数据,指定用于强制安全性的属性,以及限制实时 (JIT) 编译器的优化以使代码易于调试。属性还可以记录文件名或代码作者,或在窗体开发阶段控制控件和成员的可见性。 可使用属性以几乎所有可能的方式描述代码,并以富有创造性的新方式影响运行库行为。属性允许您向 C#、C++ 托管扩展、Microsoft Visual Basic .NET 或其他任何以运行库为目标的语言添加自己的描述性元素,而不必重新编写编译器。 |
使用属性可以获得很大的开发灵活性,并且可以提供很多非常清晰易读的代码,笔者看到的在NUnit中的一段代码可以作为使用属性的很好例子:























上面的例子中,基类里通过自定义属性分析命令行参数,并将他们分别填充到字段中。例如用户输入下面的命令行参数:
NUnit-Console.exe /config:a.cfg |
基类就会将“a.cfg”填充到config变量中。
相关的代码可以参考NUnit/nunit.util.dll/CommandLineOption.cs 和 NUnit/nunit.util.dll/ConsoleOption.cs。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix