Закройте и Расположите - чтобы звонить?

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
151
задан Community 23 May 2017 в 12:34
поделиться

6 ответов

Я хочу разъяснить эту ситуацию.

Согласно инструкциям Microsoft, это - хорошая практика для обеспечения Close метод, где подходящий. Здесь цитата от [1 117], руководство по проектированию Платформы

Рассматривает обеспечение метода Close(), в дополнение к эти Dispose(), если близко стандартная терминология в области. При выполнении так, важно, чтобы Вы сделали Close реализация идентичный Dispose...

В большинстве случаев Close и Dispose методы эквивалентны. основное различие между Close и Dispose в случае SqlConnectionObject:

приложение может звонить Close больше чем в один раз. Никакое исключение не сгенерировано.

, Если Вы звонили Dispose метод SqlConnection, объектное состояние будет сброшено. При попытке назвать какой-либо метод на склонном SqlConnection объект, Вы получите исключение.

, Который сказал:

  • при использовании объекта соединения одно время используйте Dispose.
  • , Если объект соединения должен быть снова использован, используйте Close метод.
178
ответ дан is.cattabiani 23 November 2019 в 22:16
поделиться

Как обычно, ответ: это зависит. Различная реализация классов IDisposable по-разному, и Вам решать проводить необходимое исследование.

До SqlClient идет, методические рекомендации должны сделать следующее:

using (SqlConnection conn = /* Create new instance using your favorite method */)
{
    conn.Open();
    using (SqlCommand command = /* Create new instance using your favorite method */)
    {
        // Do work
    }
    conn.Close(); // Optional
}

Вы должны звонить Dispose (или Close *) на соединении! Сделайте не , ожидают сборщика "мусора" для чистки соединения, это свяжет соединения в пуле до следующего цикла GC (по крайней мере). Если Вы звоните Dispose, не необходимо звонить Close, и начиная с эти using, конструкция делает настолько легким обработать Dispose правильно, нет действительно никакой причины звонить Close.

Соединения автоматически объединены, и вызов Dispose / Close на соединении не делает физически близко соединения (при нормальных обстоятельствах). Не пытайтесь реализовать свое собственное объединение. SqlClient выполняет очистку на соединении, когда это получено от пула (как восстановление контекста базы данных и опций соединения).

*if Вы звоните Close, удостоверьтесь, что сделали это безопасным от исключения способом (т.е. выгодой или наконец блоком).

23
ответ дан Neil Patrao 23 November 2019 в 22:16
поделиться

ДЕЙСТВИТЕЛЬНО необходимо звонить, Располагают ()!

Располагают (), для разработчика для вызова, вызовы Сборщика "мусора" Завершают (). Если Вы не звоните, Располагают () на Ваших объектах любые неуправляемые ресурсы, которые они использовали, не будет расположен, пока сборщик "мусора" не приходит, и вызовы завершают на них (и кто знает, когда это произойдет).

Этот сценарий называют Не Детерминированным Завершением и является общим прерыванием для .net разработчиков. Если Вы работаете с объектами, которые реализуют IDisposable, тогда звонят, Располагают () на них!

http://www.ondotnet.com/pub/a/oreilly/dotnet/news/programmingCsharp_0801.html?page=last

, В то время как может быть много экземпляров (как на SqlConnection), где Вы называете Disponse () на некотором объекте и это просто звонит Близко () на, он - соединение или закрывает дескриптор файла, это - почти всегда Ваш лучший выбор звонить, Располагают ()! если Вы не планируете многократное использование объекта в самом ближайшем будущем.

11
ответ дан Tyler 23 November 2019 в 22:16
поделиться

Для SqlConnection, с точки зрения самого соединения, они эквивалентны. Согласно Отражателю, Dispose() вызовы Close(), а также выполнение нескольких дополнительных освобождающих память операций - главным образом путем установки участников равняются пустому указателю.

Для Потока, они на самом деле эквивалентны. Stream.Dispose() просто вызовы Близко ().

10
ответ дан Gonzalo.- 23 November 2019 в 22:16
поделиться

Этот потенциальный быстрый совет стал длинным ответом. Извините.

Как tyler указанный в его хорошем ответе, звоня Dispose() большая практика программирования. Это вызвано тем, что этот метод, как предполагается, "сплачивает вместе" все освобождение ресурса, необходимое, таким образом, нет никаких ненужных открытых ресурсов. Если Вы записали некоторый текст в файл, например, и не удались закрыться, файл (освободите ресурс), это останется открытым, и никто больше не будет в состоянии записать в него, пока GC не придет и делает то, что необходимо было сделать.

Теперь, в некоторых случаях там будет "завершать" методы, более характерные для класса, Вы имеете дело с, как StreamWriter.Close(), который переопределяет TextWriter.Close(). Действительно они обычно больше подходят для ситуации: StreamWriter Close(), например, сбрасывает поток и базовый кодер прежде Dispose() луг объекта! Охладитесь!

Однако просматривающий MSDN Вы найдете, что даже Microsoft иногда путается множеством closers и устройств обработки отходов. На этой веб-странице , например, на некоторых примерах Close() назван перед неявным Dispose() (см. использовать оператор , если Вы не понимаете, почему это неявно), и в одном в особенности они не потрудились. Почему это было бы? Я также был озадачен.

причина я фигурировал (и, я подчеркиваю, это исходное исследование , и я, конечно, мог бы потерять репутацию, если я неправ), то, что Close() мог бы перестать работать, приведя к исключению при оставлении ресурсов открытыми, в то время как Dispose(), конечно, освободит их . Который является, почему Dispose() должен всегда охранять Close() вызов (извините для игры слов).

MyResource r = new MyResource();

try {
  r.Write(new Whatever());

  r.Close()
finally {
  r.Dispose();
}

И да, я предполагаю, что Microsoft надела тот один пример. Возможно, та метка времени никогда не сбрасывать в файл.

я фиксирую свой старый код завтра.

Редактирование: извините Brannon, я не могу прокомментировать Ваш ответ, но действительно ли Вы уверены, что это - хорошая идея звонить Close() на finally блок? Я предполагаю, что исключение из этого могло бы разрушить остальную часть блока, который, вероятно, будет содержать важный код очистки.

Ответ Brannon: большой, просто не забывайте звонить Close(), когда это действительно необходимо (например, когда контакт с потоками - не знает много о соединениях SQL в.NET).

6
ответ дан André Chalella 23 November 2019 в 22:16
поделиться

Typecast к iDisposable и вызовите dispose на нем. Это вызовет любой метод, сконфигурированный как реализующий "iDisposable.Dispose", независимо от того, как названа функция.

2
ответ дан 23 November 2019 в 22:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: