我看到了这段代码:
var request = (HttpWebRequest) WebRequest.Create("http://www.google.com");
为什么需要投射(HttpWebRequest)
?为什么不使用HttpWebRequest.Create
?为什么HttpWebRequest.Create
会成为WebRequest
,而不是HttpWebRequest
?
答案 0 :(得分:131)
Create
方法是静态的,仅存在于WebRequest
上。将其称为HttpWebRequest.Create
可能看起来有所不同,但实际上编译为调用WebRequest.Create
。由于继承,它似乎只在HttpWebRequest
上。
内部的Create
方法,使用工厂模式根据您传入的Uri
来实际创建对象。您实际上可以取回其他对象,例如FtpWebRequest
或FileWebRequest
,具体取决于Uri
。
答案 1 :(得分:30)
WebRequest
是一个抽象类,它有一个工厂方法Create
,它根据传入的URL创建一个具体子类的实例。无论您需要还是想要
HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl);
代替
WebRequest req = WebRequest.Create(strUrl);
取决于您的需求以及您传入的网址类型。
如果您只传入HTTP:URL,那么前一代码允许您访问子类HttpWebRequest
实现的属性和方法,以及基类WebRequest
上定义的属性和方法。但是,如果您传入了FTP:URL,那么转换为HttpWebRequest
的尝试将失败。
后者是通用的,不会在任何类型的受支持的URL上失败,但当然不会转换为任何子类,您只能访问基类定义的属性和方法。
- 来自Martin Honnen
答案 2 :(得分:11)
只有当您需要访问HttpWebRequest特有的成员时才需要强制转换。我们的想法是,如果WebRequest上支持的属性/方法足够,那么您可以编写一个适用于许多类型的请求/响应协议的应用程序。在这种情况下,URI可以是用户使用可插拔协议支持的任何协议给出的东西。甚至可以支持新协议而无需更改原始软件。
如果您的应用程序需要更多地控制特定协议的特定功能,那么您可以将requestUri限制为支持的方案,并将WebRequest强制转换为适当的协议特定子类。这限制了应用程序支持的协议,但允许您调整协议特定的功能。