C # HttpWebRequest vs WebRequest

112

Eu vi este trecho de código:

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

Por que você precisa lançar (HttpWebRequest)? Por que não apenas usar HttpWebRequest.Create? E por que HttpWebRequest.Createfaz um WebRequest, não um HttpWebRequest?

Desconhecido
fonte
post-related: stackoverflow.com/q/8209781/274502
cregox

Respostas:

134

O Createmétodo é estático e existe apenas em WebRequest. Chamar como HttpWebRequest.Createpode parecer diferente, mas na verdade é compilado para chamar WebRequest.Create. Só parece estar HttpWebRequestativado por causa de herança.

O Createmétodo, internamente, usa o padrão de fábrica para fazer a criação real de objetos, com base no que Urivocê passa para ele. Você pode realmente recuperar outros objetos, como um FtpWebRequestou FileWebRequest, dependendo do Uri.

David Wengier
fonte
3
Isso está certo. Teria sido bom se houvesse uma maneira de obter um HttpWebRequest de HttpWebRequest.Create ou algo como HttpWebRequest.CreateHttp sem lançar. O primeiro seria algo como criar um novo HttpWebRequest público estático (url da string). De qualquer maneira, se o url não fosse HTTP (s), ele deveria apenas lançar alguma InvalidArgumentException.
Matthew Flaschen
4
Uma explicação muito boa de uma decisão de design muito estranha (ouso dizer errado?) Pelos criadores do .NET.
IJ Kennedy
2
@IJKennedy Eu concordo totalmente, uma decisão de design muito estranha, ilógica e pouco prática.
Aidiakapi,
8
HttpWebRequest.CreateHttp existe e cria uma instância HttpWebRequest.
Peter Meinl
4
@Bobson WebRequest.CreateHttpestá em 4,5
Marcos
31

WebRequesté uma classe abstrata, que possui um método de fábrica Createque, dependendo da URL passada, cria uma instância de uma subclasse concreta. Se você precisa ou deseja, em HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl);vez de WebRequest req = WebRequest.Create(strUrl);depende de suas necessidades e dos tipos de URLs que você passa.

Se você passar apenas HTTP: URL's, o código anterior permitirá que você acesse as propriedades e métodos que a subclasse HttpWebRequestimplementa além daqueles definidos na classe base WebRequest. Mas se você transmitisse um FTP: URL, a tentativa de transmitir para HttpWebRequestfalharia.

O último é genérico e não falhará em nenhum dos tipos de URL suportados, mas é claro, sem lançar para qualquer subclasse, você só pode acessar as propriedades e métodos que a classe base define.

- via Martin Honnen

Orhan Cinar
fonte
12

O elenco é necessário apenas quando você precisa de acesso a membros exclusivos do HttpWebRequest. A ideia é que, se as propriedades / métodos suportados no WebRequest forem suficientes, você poderá escrever um aplicativo que funcionará em muitos tipos de protocolos de solicitação / resposta. Nesse caso, o URI pode ser algo fornecido pelo usuário usando qualquer protocolo compatível com protocolos conectáveis. Novos protocolos podem até ser suportados sem alterar o software original.

Se seu aplicativo precisa de mais controle sobre os recursos específicos de um protocolo específico, você pode restringir requestUri aos seus esquemas suportados e lançar WebRequest para a subclasse específica do protocolo apropriada. Isso limita os protocolos suportados pelo seu aplicativo, mas permite que você ajuste os recursos específicos do protocolo.

Kevin
fonte