首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用标记接口代替属性的令人信服的理由

使用标记接口代替属性的令人信服的理由
EN

Stack Overflow用户
提问于 2010-01-18 21:57:28
回答 6查看 7.1K关注 0票数 58

marker interfaces (没有任何成员的接口)相比,我们应该更喜欢属性( attributes ),这已经是discussed before on Stack Overflow了。Interface Design article on MSDN也断言了这个建议:

避免使用标记接口(没有成员的接口)。

自定义属性提供了标记类型的方法。有关自定义属性的更多信息,请参见编写自定义属性。如果可以将对属性的检查推迟到代码执行时,则首选自定义属性。如果您的场景需要编译时检查,则不能遵循此准则。

甚至有一个FxCop rule来执行这个建议:

避免空接口

接口定义提供行为或使用约定的成员。接口所描述的功能可由任何类型采用,而不管该类型出现在继承层次结构中的什么位置。类型通过提供接口成员的实现来实现接口。空接口不定义任何成员,因此也不定义可以实现的协定。

如果您的设计包含期望类型实现的空接口,则可能将接口用作标记或标识一组类型的一种方式。如果此标识将在运行时发生,则完成此操作的正确方法是使用自定义属性。使用属性的存在或不存在或属性的属性来标识目标类型。如果标识必须在编译时进行,则可以使用空接口。

本文只说明了您可能忽略该警告的一个原因:当您需要类型的编译时标识时。(这与界面设计文章是一致的)。

如果接口用于在编译时标识一组类型,则从该规则中排除警告是安全的。

这里有一个实际的问题:微软在框架类库的设计中没有遵守他们自己的建议(至少在一些情况下是这样):IRequiresSessionState interfaceIReadOnlySessionState interface。ASP.NET框架使用这些接口来检查是否应该为特定的处理程序启用会话状态。显然,它不用于类型的编译时标识。他们为什么不这么做?我能想到两个潜在的原因:

  1. Micro-optimization:检查对象是否实现了接口(obj is IReadOnlySessionState)比使用反射检查属性(type.IsDefined(typeof(SessionStateAttribute), true))更快。在大多数情况下,这种差异可以忽略不计,但对于ASP.NET运行时中的性能关键型代码路径,这种差异实际上可能很重要。但是,他们可以使用一些变通方法,比如缓存每个处理程序类型的结果。有趣的是,ASMX Web服务(具有类似的性能特征)实际上使用WebMethod attributeEnableSession property来实现此目的。

与第三方.NET语言使用属性修饰类型相比,更有可能支持

  1. Implementing接口。由于ASP.NET被设计为语言不可知的,并且ASP.NET根据<%@ Page %> directiveEnableSessionState属性为实现上述接口的类型(可能在CodeDom的帮助下使用第三方语言)生成代码,因此使用接口而不是属性可能更有意义。

使用标记接口而不是属性的有说服力的理由是什么?

这仅仅是一种(过早的)吗?是优化还是框架设计中的一个小错误?(他们认为是reflection is a "big monster with red eyes"吗?)有什么想法?

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2086451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档