C#HttpWebRequest vs WebRequest

Unk*_*own 110 c# httpwebrequest

我看到了这段代码:

var request = (HttpWebRequest) WebRequest.Create("http://www.google.com");
Run Code Online (Sandbox Code Playgroud)

你为什么要演员(HttpWebRequest)?为什么不用HttpWebRequest.Create?为什么HttpWebRequest.Create要做一个WebRequest,而不是一个HttpWebRequest

Dav*_*ier 133

Create方法是静态的,仅存在于WebRequest.调用它HttpWebRequest.Create看起来可能看起来不一样,但它实际上编译为调用WebRequest.Create.它似乎只是HttpWebRequest因为继承而开启.

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

  • HttpWebRequest.CreateHttp确实存在并且确实创建了一个HttpWebRequest实例. (8认同)
  • .NET创建者对一个非常奇怪的设计决策(我敢说错了?)的一个非常好的解释. (4认同)
  • @Bobson`WebRequest.CreateHttp`是[4.5](https://msdn.microsoft.com/en-us/library/ff382776(v = vs.110).aspx) (4认同)
  • 这是正确的.如果有一种方法可以从HttpWebRequest.Create或类似HttpWebRequest.CreateHttp获取HttpWebRequest而不进行强制转换,那将是很好的.第一个是像public new static HttpWebRequest Create(string url).无论哪种方式,如果url不是HTTP(s),它应该抛出一些InvalidArgumentException. (3认同)
  • @IJKennedy我完全同意,这是一个非常奇怪,不合逻辑,不切实际的设计决定. (2认同)

Orh*_*nar 31

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


Kev*_*vin 12

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

如果应用程序需要在特定于某个特定协议,那么你可以限制requestUri到支持的方案(S)和流延WebRequest的,以适当的协议特定的子功能的更多控制.这限制了应用程序支持的协议,但允许您调整协议特定的功能.