2009-05-22 56 views
101

tôi thấy đoạn mã này:C# HttpWebRequest vs WebRequest

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

Tại sao bạn cần phải cast (HttpWebRequest)? Tại sao không chỉ sử dụng HttpWebRequest.Create? Và tại sao HttpWebRequest.Create tạo một WebRequest, không phải là HttpWebRequest?

+0

bài liên quan: http://stackoverflow.com/q/8209781/274502 – cregox

Trả lời

130

Phương thức Create là tĩnh và chỉ tồn tại trên WebRequest. Gọi nó là HttpWebRequest.Create có thể trông khác, nhưng thực sự được biên dịch xuống để gọi WebRequest.Create. Nó chỉ xuất hiện trên HttpWebRequest vì thừa kế.

Phương thức Create nội bộ, sử dụng mẫu nhà máy để thực hiện tạo đối tượng thực tế, dựa trên Uri bạn chuyển vào đó. Bạn có thể thực sự lấy lại các vật thể khác, chẳng hạn như FtpWebRequest hoặc FileWebRequest, tùy thuộc vào Uri.

+3

Điều này đúng. Nó sẽ được tốt đẹp nếu có một cách để có được một HttpWebRequest từ HttpWebRequest.Create hoặc một cái gì đó như HttpWebRequest.CreateHttp mà không cần đúc. Đầu tiên sẽ là một cái gì đó giống như công khai mới HttpWebRequest Tạo (chuỗi url). Dù bằng cách nào, nếu url không phải là HTTP (s), nó chỉ cần ném một số InvalidArgumentException. –

+4

Một lời giải thích rất hay về một quyết định thiết kế rất lạ (tôi dám nói sai?) Bởi những người sáng tạo .NET. –

+2

@ I.J.Kennedy Tôi hoàn toàn đồng ý, một quyết định thiết kế rất kỳ lạ, vô lý và không thực tế. – Aidiakapi

27

WebRequest là lớp trừu tượng, có phương thức nhà máy Create, tùy thuộc vào URL được truyền vào, tạo một phiên bản của lớp con cụ thể. Cho dù bạn cần hoặc muốn HttpWebRequest httpreq = (HttpWebRequest)WebRequest.Create(strUrl); thay vì WebRequest req = WebRequest.Create(strUrl); phụ thuộc vào nhu cầu của bạn, và trên loại URL bạn vượt qua trong

Nếu bạn chỉ vượt qua trong HTTP:. URL, sau đó mã cũ cho phép bạn truy cập vào các thuộc tính và phương thức phân lớp HttpWebRequest thực hiện ngoài các phương thức được xác định trên lớp cơ sở WebRequest. Nhưng nếu bạn chuyển vào một FTP: URL thì nỗ lực truyền tới HttpWebRequest sẽ thất bại.

Sau này là chung và sẽ không thất bại trên bất kỳ loại URL nào được hỗ trợ nhưng tất nhiên mà không truyền tới bất kỳ lớp con nào, bạn chỉ có thể truy cập thuộc tính và phương thức mà lớp cơ sở xác định.

- qua Martin Honnen

10

Dàn diễn viên chỉ cần thiết khi bạn cần truy cập vào các thành viên duy nhất để HttpWebRequest. Ý tưởng là nếu các thuộc tính/phương thức được hỗ trợ trên WebRequest là đủ, thì bạn có thể viết một ứng dụng sẽ làm việc với nhiều loại giao thức yêu cầu/đáp ứng. Trong trường hợp này URI có thể là một cái gì đó được đưa ra bởi người dùng bằng cách sử dụng bất kỳ giao thức nào được hỗ trợ bởi các giao thức có thể cắm được. Các giao thức mới thậm chí có thể được hỗ trợ mà không thay đổi phần mềm gốc.

Nếu ứng dụng của bạn cần kiểm soát nhiều hơn đối với các tính năng cụ thể cho giao thức cụ thể thì bạn có thể hạn chế requestUri cho (các) lược đồ được hỗ trợ của bạn và truyền WebRequest đến lớp con giao thức cụ thể thích hợp. Điều này giới hạn các giao thức được hỗ trợ bởi ứng dụng của bạn, nhưng cho phép bạn tinh chỉnh các tính năng giao thức cụ thể.

Các vấn đề liên quan