C # HttpWebRequest vs WebRequest

我看到一段代码:

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

为什么你需要铸造 (HttpWebRequest)?为什么不用 HttpWebRequest.Create呢?为什么 HttpWebRequest.CreateWebRequest而不是 HttpWebRequest

87801 次浏览

Create方法是静态的,只存在于 WebRequest上。调用它作为 HttpWebRequest.Create可能看起来不同,但它实际上编译成调用 WebRequest.Create。因为遗传,它只出现在 HttpWebRequest上。

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

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

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

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

通过 Martin Honnen

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

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

We will be using WebRequest method because it will work as generic method for transparently retriving file from

  • 网络服务器,
  • FTP 伺服器及
  • 文件服务器

那么

var httpRequest = WebRequest.Create("http://somedomain.com");       // return an instance of type(HttpWebRequest)
var ftpRequest = WebRequest.Create("ftp://ftp.somedomain.com");     // return an instance of type(FtpWebRequest)
var fileRequest = WebRequest.Create("file://files.somedomain.com"); // return an instance of type(FileWebRequest)

Return Type of all three methods (HttpWebRequest, FtpWebRequest, FileWebRequest) all drive from base class WebRequest which is return type of WebRequest.Create(string). Now which subclass to instantiate is determined using the protocol prefixes (http:, https:, ftp:, file:)

So, any URI string (with any of these four prefixes) you pass to the Create method will be transparently handled by the WebRequest base class so you don't even have to know specifically what sub-class was returned