C # HttpWebRequest vs WebRequest

112

Widziałem ten fragment kodu:

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

Dlaczego musisz rzucać (HttpWebRequest)? Dlaczego po prostu nie użyć HttpWebRequest.Create? A dlaczego robi HttpWebRequest.Createa WebRequest, a nie a HttpWebRequest?

Nieznany
źródło
post-related: stackoverflow.com/q/8209781/274502
cregox

Odpowiedzi:

134

CreateMetoda jest statyczna, a istnieje tylko na WebRequest. Nazywanie go tak, jak HttpWebRequest.Createmogłoby wyglądać inaczej, ale w rzeczywistości sprowadza się do wywołania WebRequest.Create. Wygląda na to, że jest włączony tylko z HttpWebRequestpowodu dziedziczenia.

CreateMetoda wewnętrznie, wykorzystuje wzorzec fabryki zrobić rzeczywiste tworzenie obiektów, na podstawie Uriprzechodzą w niej. W rzeczywistości możesz odzyskać inne obiekty, takie jak FtpWebRequestlub FileWebRequest, w zależności od Uri.

David Wengier
źródło
3
To prawda. Byłoby miło, gdyby istniał sposób na pobranie HttpWebRequest z HttpWebRequest.Create lub czegoś takiego jak HttpWebRequest.CreateHttp bez rzutowania. Pierwszym byłoby coś w rodzaju public new static HttpWebRequest Create (string url). Tak czy inaczej, jeśli adres URL nie był HTTP (s), powinien po prostu zgłosić wyjątek InvalidArgumentException.
Matthew Flaschen
4
Bardzo ładne wyjaśnienie bardzo dziwnej decyzji projektowej (czy ośmielę się powiedzieć źle?) Twórców .NET.
IJ Kennedy
2
@IJKennedy Całkowicie się zgadzam, bardzo dziwna, nielogiczna i niepraktyczna decyzja projektowa.
Aidiakapi
8
HttpWebRequest.CreateHttp istnieje i tworzy wystąpienie HttpWebRequest.
Peter Meinl
4
@ Bobson WebRequest.CreateHttpjest w 4.5
Mark
31

WebRequestjest klasą abstrakcyjną, która ma metodę fabryczną, Createktóra w zależności od przekazanego adresu URL tworzy instancję konkretnej podklasy. To, czy potrzebujesz lub chcesz HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl);zamiast, WebRequest req = WebRequest.Create(strUrl);zależy od twoich potrzeb i od rodzaju przekazywanych adresów URL.

Jeśli przekazujesz tylko adresy HTTP: URL, to poprzedni kod umożliwia dostęp do właściwości i metod HttpWebRequestimplementowanych przez podklasę, oprócz tych zdefiniowanych w klasie bazowej WebRequest. Ale jeśli przekazałeś FTP: URL, próba przesłania HttpWebRequestzakończy się niepowodzeniem.

Ta ostatnia jest ogólna i nie zawiedzie na żadnym z typów obsługiwanych adresów URL, ale oczywiście bez rzutowania na żadną podklasę możesz uzyskać dostęp tylko do właściwości i metod zdefiniowanych w klasie bazowej.

- przez Martina Honnena

Orhan Cinar
źródło
12

Rzutowanie jest konieczne tylko wtedy, gdy potrzebujesz dostępu do członków unikalnych dla HttpWebRequest. Chodzi o to, że jeśli właściwości / metody obsługiwane przez WebRequest są wystarczające, możesz napisać aplikację, która będzie działać z wieloma typami protokołów żądań / odpowiedzi. W tym przypadku URI może być czymś podanym przez użytkownika przy użyciu dowolnego protokołu obsługiwanego przez protokoły podłączane. Nowe protokoły mogą być obsługiwane nawet bez zmiany oryginalnego oprogramowania.

Jeśli Twoja aplikacja wymaga większej kontroli nad funkcjami specyficznymi dla określonego protokołu, możesz ograniczyć requestUri do obsługiwanych schematów i przesłać WebRequest do odpowiedniej podklasy specyficznej dla protokołu. Ogranicza to protokoły obsługiwane przez aplikację, ale umożliwia modyfikowanie funkcji specyficznych dla protokołu.

Kevin
źródło