【问题标题】:C# HttpWebRequest vs WebRequestC# HttpWebRequest 与 WebRequest
【发布时间】:2023-04-04 05:34:01
【问题描述】:

我看到了这段代码:

var request = (HttpWebRequest) WebRequest.Create("http://www.google.com");

为什么需要投射(HttpWebRequest)?为什么不直接使用HttpWebRequest.Create?为什么HttpWebRequest.CreateWebRequest,而不是HttpWebRequest

【问题讨论】:

标签: c# httpwebrequest


【解决方案1】:

Create 方法是静态的,只存在于WebRequest。将其称为HttpWebRequest.Create 可能看起来不同,但实际上它被编译为调用WebRequest.Create。由于继承,它似乎只在 HttpWebRequest 上。

Create 方法在内部使用工厂模式来执行对象的实际创建,基于您传递给它的Uri。您实际上可以取回其他对象,例如 FtpWebRequestFileWebRequest,具体取决于 Uri

【讨论】:

  • 这是对的。如果有一种方法可以从 HttpWebRequest.Create 或类似 HttpWebRequest.CreateHttp 的东西中获取 HttpWebRequest 而无需强制转换,那就太好了。第一个类似于 public new static HttpWebRequest Create(string url)。无论哪种方式,如果 url 不是 HTTP(s),它应该只是抛出一些 InvalidArgumentException。
  • .NET 创建者对一个非常奇怪的设计决定(我敢说错吗?)的很好解释。
  • @I.J.Kennedy 我完全同意,这是一个非常奇怪、不合逻辑且不切实际的设计决定。
  • HttpWebRequest.CreateHttp 确实存在并创建了一个 HttpWebRequest 实例。
  • @Bobson WebRequest.CreateHttpin 4.5
【解决方案2】:

WebRequest 是一个抽象类,它有一个工厂方法Create,它根据传入的 URL 创建一个具体子类的实例。无论您需要还是想要 HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl); 而不是 WebRequest req = WebRequest.Create(strUrl); 取决于您的需求,以及您传入的 URL 类型。

如果您只传入 HTTP: URL,那么除了在基类 WebRequest 上定义的属性和方法之外,之前的代码还允许您访问子类 HttpWebRequest 实现的属性和方法。但是如果你传入一个 FTP: URL,那么转换为 HttpWebRequest 的尝试将会失败。

后者是通用的,不会在任何受支持的 URL 类型上失败,但当然如果不强制转换为任何子类,您只能访问基类定义的属性和方法。

-- 通过 Martin Honnen

【讨论】:

    【解决方案3】:

    只有当您需要访问 HttpWebRequest 独有的成员时才需要强制转换。这个想法是,如果 WebRequest 支持的属性/方法足够,那么您可以编写一个适用于多种类型的请求/响应协议的应用程序。在这种情况下,URI 可以是用户使用可插入协议支持的任何协议给出的东西。甚至可以在不更改原始软件的情况下支持新协议。

    如果您的应用程序需要对特定协议的特定功能进行更多控制,那么您可以将 requestUri 限制为您支持的方案,并将 WebRequest 转换为适当的协议特定子类。这会限制您的应用程序支持的协议,但允许您调整协议特定的功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 2011-05-26
      • 1970-01-01
      • 2016-09-19
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多