От RFC 3986 :
URI А может быть далее классифицирован как локатор, имя или оба. Термин "Унифицированный указатель ресурсов" (URL) относится к подмножеству URIs, которые, в дополнение к идентификации ресурса, обеспечивают средство определения местоположения ресурса путем описания его основного механизма доступа (например, его сетевое "местоположение"). Термин "Унифицированное имя ресурса" (УРНА) был использован исторически для обращения и к URIs в соответствии со схемой [RFC2141] "урны", которые требуются, чтобы оставаться глобально уникальными и персистентными, даже когда ресурс прекращает существование или становится недоступным, и к любому другому URI со свойствами имени.
, Таким образом, все URL являются URIs (на самом деле не совсем - видят ниже), и все УРНЫ являются URIs - но УРНЫ и URL отличаются, таким образом, Вы не можете сказать, что всеми URIs являются URL.
РЕДАКТИРОВАНИЕ: Я ранее думал, что все URL являются допустимым URIs, но согласно комментариям:
Не "все URL являются URIs". Это зависит от интерпретации RFC. Например, в Java синтаксическому анализатору URI не нравится
[
или]
, и поэтому спецификация говорит, "не должен", и не "не буду".
Так, чтобы пачкал воды далее, к сожалению.
, Если бы Вы уже не читали ответ Roger Pate , я советовал бы делать так также.
It ' s почти всегда ошибочно устанавливать для локальных переменных значение null, если только вы не захотите использовать это значение позже. Он не вызывает принудительную сборку мусора раньше - если вы не собираетесь читать из переменной позже, сборщик мусора может игнорировать ссылку (когда не в режиме отладки).
Однако почти всегда правильно закрывать потоки - в идеале в операторе using
для простоты.
Это также почти всегда неправильно иметь такой голый блок "catch". Вы действительно хотите обработать что-нибудь , идущее не так, в том числе такие вещи, как OutOfMemoryException
?
Я бы переписал ваш код следующим образом:
HttpWebRequest req = (HttpWebRequest) WebRequest.Create("someUrl"));
req.Credentials = CredentialCache.DefaultCredentials;
req.Method = "GET";
using (WebResponse response = req.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(),
Encoding.Default))
{
return reader.ReadToEnd();
}
}
Теперь, если что-то пойдет не так, исключение будет передается вызывающему. Возможно, вам захочется поймать несколько конкретных исключений, но это ' Как правило, не рекомендуется представлять ошибки с помощью значения, которое могло бы быть допустимым «нормальным» ответом.
Наконец, действительно ли вы уверены, что хотите Encoding.Default
? Это кодировка по умолчанию для локального компьютера - обычно вам нужна кодировка, указанная в самом ответе.
Он должен иметь с использованием
[который вызывает Dispose ()
].
Да, Dispose () их.
Еще лучше сделать что-то вроде
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse() )
using (Stream receiveStream = response.GetResponseStream() )
using (readStream = new StreamReader(receiveStream, Encoding.Default) )
{
return readStream.ReadToEnd();
}
A using (x) Блок {}
будет перезаписан (компилятором )
как try {} finally {x.Dispose ();}
Обратите внимание, что WebRequest не является IDisposable.
Также обратите внимание, что следующие строки выполняют то же самое, что и весь ваш код:
using (var client = new System.Net.WebClient())
{
client.Encoding = ...;
client.Credentials = ...;
return client.DownloadString("SomeUrl");
}
Да. Практически все, что реализует метод Dispose (), должно иметь вызываемый метод Dispose (). Вы можете неявно вызвать его с помощью оператора using:
using(StreamReader stream = GetStream())
{
stream.DoStuff();
}
Да.
Когда вы установлено значение null, он обнуляет только ссылку. Он не запускает никакого кода очистки, написанного создателем класса Stream.
Вы также можете рассмотреть оператор using () {}
, который обрабатывает это за вас для типов IDisposable.
Пример:
using (MyDisposableObject mdo = new MyDisposableObject)
{
// Do some stuff with mdo
// mdo will automatically get disposed by the using clause
}
Самый безопасный метод:
try {
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("someUrl");
request.Credentials = CredentialCache.DefaultCredentials;
request.Method = "GET";
using (HttpWebResponse response = (HttpWebResponse) request.GetResponse()) {
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default)) {
return reader.ReadToEnd();
}
}
} catch {
return "Error";
}
Нет необходимости явно удалять поток response.GetResponseStream ()
, потому что присоединенный StreamReader
удалит его для вы.
РЕДАКТИРОВАТЬ: Я согласен с другими ответами - перехват таких исключений - очень плохая практика. Я просто оставил это для сравнения. : -)
Да - вы должны явно вызывать Dispose () для классов, реализующих IDisposable, после того, как вы их использовали - это гарантирует, что все их ресурсы будут своевременно очищены. Оборачивание переменной в с помощью ()
делает то же самое (добавляя код упаковки, вызывающий за вас Dispose):
using (StreamReader reader = new StreamReader()) {
// do stuff with reader
}
В библиотеках .net есть несколько ошибок. Stream - это одно, а другое - большая часть Imaging API. Эти сущности, которые используют определенные системные ресурсы, не собирают мусор прикрепленные системные ресурсы.
Если что-то использует IDisposable API, лучше всего заключить это в блок using, как люди указали выше.
Читайте "использование" и помните об этом, когда имеете дело с дескрипторами файлов или изображениями.
На самом деле, на вопрос был дан ответ, но я хочу уточнить одну вещь.
Каждый раз, когда объект реализует интерфейс IDisposable
, вы должны избавиться от него с помощью метода Dispose или (что еще лучше) используйте оператор using
.
Если вы когда-нибудь столкнетесь с этим вопросом в будущем, просто узнайте, какие интерфейсы он реализует. Как только вы увидите IDisposable
, вы поймете, что нужно утилизировать.
Если вам нужно очистить поток, используйте null; В противном случае используйте Dispose (); метод, если ваше приложение больше не требует использования потока.