C#HttpWebRequest与WebRequest


112

我看到了这段代码:

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

为什么需要投射(HttpWebRequest)?为什么不只是使用HttpWebRequest.Create?为何HttpWebRequest.Create制作一个WebRequest而不是一个HttpWebRequest


Answers:


134

Create方法是静态的,仅存在于WebRequest。调用它的HttpWebRequest.Create外观可能有所不同,但实际上已编译为call WebRequest.Create。它似乎仅HttpWebRequest由于继承而启用。

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


3
这是对的。如果有一种方法可以从HttpWebRequest.Create或类似HttpWebRequest.CreateHttp的方法中获取HttpWebRequest而不进行强制转换,那就太好了。第一个是类似于public new static HttpWebRequest Create(string url)的东西。无论哪种方式,如果url不是HTTP(s),它都应该抛出一些InvalidArgumentException。
马修·弗莱申

4
.NET创建者对一个非常奇怪的设计决策(敢说我错了吗?)的很好解释。
IJ肯尼迪

2
@IJKennedy我完全同意,这是一个非常奇怪,不合逻辑且不切实际的设计决策。
2011年

8
HttpWebRequest.CreateHttp确实存在并且确实创建了HttpWebRequest实例。
Peter Meinl

4
@Bobson WebRequest.CreateHttp在4.5
马克

31

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

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

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

-通过马丁·洪恩(Martin Honnen)


12

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

如果您的应用程序需要对特定协议特定功能的更多控制,则可以将requestUri限制为受支持的方案,并将WebRequest强制转换为适当的特定于协议的子类。这限制了应用程序支持的协议,但是使您可以调整协议特定的功能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.