【问题标题】:Why is System.Net.Http.HttpMethod a class, not a struct?为什么 System.Net.Http.HttpMethod 是一个类,而不是一个结构?
【发布时间】:2019-02-06 13:22:20
【问题描述】:

之前有一个与 .Net 标准的 System.Net 中的实现点相关的问题,关于为什么 HttpMethod 仍然不是枚举。

Why is System.Net.Http.HttpMethod a class, not an enum?

它对可扩展性有很好的回答。

但是,正如我在标题中所说,为什么它不是结构?

It seems to pass all the tests according to microsofts guidelines? 这是一些在 Web 应用程序中被大量抛出的信息,我“认为”DELETE 是最长的动词,低于推荐的 16 个字节。

这是否与字符串作为 .Net 中的中途之家有关?我知道收益可能是微不足道的,但我只是想更好地理解。

【问题讨论】:

  • 16 字节不是(唯一)指示何时使用一个而不是另一个。实际上,您可以拥有具有更高内存分配的结构或具有更低内存分配的类。这只是一个指南,你可以打破它。
  • 可以说可能是,但事实并非如此。它实现了IEquatable<>,在早期版本的 JIT 中,由于装箱,它本身就是结构上的一个性能陷阱(新版本在可能的情况下可以更好地避免这种情况)。这是否是一个问题,或者作者是否只是没有认真考虑它,这是一个悬而未决的问题。我怀疑HttpMethod 被“扔”到足以真的 重要:它是复制引用而不是...复制引用(内部的string),因为它是@ 的集合987654329@s 分配无所谓。
  • @JeroenMostert 我想我想不出在域(HTTP)方面null 方法的用途,不管计算机科学原因如何。如果只有 C# 有固定长度的字符串,我们就不必每次都去堆,因为可变大小。
  • 堆在这个讨论中几乎是无关紧要的:假设你没有自定义方法,但只使用HttpMethod 上的静态字段(我想最常见),你只是获取预分配的实例,每个实例都引用一个实习字符串。从这个意义上说,C# 确实 有“固定长度的字符串”——文字是字符串实习池的一部分,在那里分配不是问题。类或结构,HttpMethod不复制方法中的实际字符。在 unsafe 上下文中,您可以在结构中包含 char[16] 字段,但这很少是合适的。
  • 在这种情况下,唯一要优化的堆分配是在服务器端通过解析请求形成的HttpMethod(和随附的字符串)。如果事实证明有必要进行优化(这不太可能,因为每个请求只发生一次),那么完全不使用 HttpMethod 并直接比较字符(来自 @987654337 @, 甚至)。不过,这已经深入到微优化中,并且可能会取得更大的胜利。

标签: c# asp.net-core .net-core .net-standard


【解决方案1】:

struct 相对于 class 不会有太多优势。

结构非常适合 memcpy / memcmp 类型的实现,如果是 HttpMethod,则没有必要。

如果您查看 .net 核心实现 https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpMethod.cs,您会发现它使用引用相等检查来比较实例,这比字符串比较稍快。使用结构是不可能的......因为大多数结构实例实际上是不同的实例,它们必须比较字符串值。

鉴于 HTTP 方法的字符串值不是很长,因此这里的 struct 确实没有其他好处,因为它只携带一个字符串引用,并且大多数 HttpMethod 实例将是 HttpMethod 类的静态字段的实例。

它也可以是一个纯字符串,但在编译等过程中它不会帮助方法解析。

【讨论】:

  • 谢谢。我认为这是一个很好的推理。也许这些考虑比空引用类型问题更重要。
猜你喜欢
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 2017-11-14
  • 2015-08-02
  • 1970-01-01
  • 2014-07-31
  • 2011-10-06
  • 2014-08-05
相关资源
最近更新 更多