gpt4 book ai didi

.net - 使用标记接口(interface)而不是属性的令人信服的理由

转载 作者:行者123 更新时间:2023-12-03 05:52:27 24 4
gpt4 key购买 nike

已经discussed before on Stack Overflow我们应该更喜欢属性而不是 marker interfaces (没有任何成员的接口(interface))。 Interface Design article on MSDN也主张这一建议:

Avoid using marker interfaces (interfaces with no members).

Custom attributes provide a way to mark a type. For more information about custom attributes, see Writing Custom Attributes. Custom attributes are preferred when you can defer checking for the attribute until the code is executing. If your scenario requires compile-time checking, you cannot comply with this guideline.

甚至还有一个 FxCop rule执行此建议:

Avoid empty interfaces

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 probably 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.

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

It is safe to exclude a warning from this rule if the interface is used to identify a set of types at compile-time.

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

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

  2. 第三方 .NET 语言实现接口(interface)可能比使用属性修饰类型更受支持。由于 ASP.NET 被设计为与语言无关,并且 ASP.NET 生成基于 EnableSessionState 实现所述接口(interface)的类型代码(可能在 CodeDom 的帮助下使用第三方语言)。 <%@ Page %> directive 的属性,使用接口(interface)而不是属性可能更有意义。

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

这只是一个(不成熟的?)优化还是框架设计中的一个小错误? (他们认为reflection is a "big monster with red eyes"?)想法?

最佳答案

我通常会避免使用“标记接口(interface)”,因为它们不允许您取消标记派生类型。但除此之外,以下是我见过的一些具体情况,其中标记接口(interface)比内置元数据支持更可取:

  1. 运行时性能敏感的情况。
  2. 与不支持注释或属性的语言的兼容性。
  3. 感兴趣的代码可能无法访问元数据的任何上下文。
  4. 支持通用约束和通用方差(通常是集合)。

关于.net - 使用标记接口(interface)而不是属性的令人信服的理由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2086451/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com