Существует ли лучший детерминированный шаблон распоряжения, чем вложенное “использование” s?

Другое событие NullPointerException возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.

String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals для гарантированного непустого объекта.

Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null.

Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.

String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
    System.out.println(phrase.equals(keyPhrase));
}

20
задан keyser 5 November 2012 в 16:06
поделиться

9 ответов

Вы не должны вкладывать с несколькими использованиями:

using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
    // all three get disposed when you're done
}
40
ответ дан 29 November 2019 в 23:12
поделиться

Можно соединить операторы использования перед вводными фигурными скобками как так:

  using (StreamWriter w1 = File.CreateText("W1"))
  using (StreamWriter w2 = File.CreateText("W2"))
  {
      // code here
  }

http://blogs.msdn.com/ericgu/archive/2004/08/05/209267.aspx

8
ответ дан 29 November 2019 в 23:12
поделиться

Вы могли использовать этот синтаксис для сжатия вещей вниз немного:

using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
}

Это - один из тех редких случаев, где не использование {} для всех блоков имеет смысл, по моему скромному мнению.

3
ответ дан 29 November 2019 в 23:12
поделиться

Вместо операторов использования вложения можно просто выписать вызовы.Dispose вручную - но Вы почти наверняка пропустите тот в какой-то момент.

Или выполнить FxCop или что-то еще, которое может удостовериться, что все экземпляры типа IDisposable-реализации имеют.Dispose () вызов или соглашение с вложением.

1
ответ дан 29 November 2019 в 23:12
поделиться

У меня есть используемые решения как Michael Meadows прежде, но его StreamWrapper код не принимает во внимание, обратились ли эти Dispose() методы к членским переменным, выдают исключение по той или иной причине, последующее Dispose(), es не назовут, и ресурсы могли свиснуть. Более безопасный путь к тому для работы:

        var exceptions = new List<Exception>();

        try
        {
            this.sr.Dispose();
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }

        try
        {
            this.bs.Dispose();
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }

        try
        {
            this.fs.Dispose();
        }
        catch (Exception ex)
        {
            exceptions.Add(ex);
        }

        if (exceptions.Count > 0)
        {
            throw new AggregateException(exceptions);
        }
    }
1
ответ дан 29 November 2019 в 23:12
поделиться

можно опустить фигурные скобки, как:

using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
        // use sr, and have everything cleaned up when done.
}

или использование регулярная попытка наконец приблизьтесь:

FileStream fs = new FileStream("c:\file.txt", FileMode.Open);
BufferedStream bs = new BufferedStream(fs);
StreamReader sr = new StreamReader(bs);
try
{
        // use sr, and have everything cleaned up when done.
}finally{
   sr.Close(); // should be enough since you hand control to the reader
}
0
ответ дан 29 November 2019 в 23:12
поделиться

Это делает для намного большей сети плюс в строках кода, но материальном усилении в удобочитаемости:

using (StreamWrapper wrapper = new StreamWrapper("c:\file.txt", FileMode.Open))
{
    // do stuff using wrapper.Reader
}

, Где StreamWrapper определяется здесь:

private class StreamWrapper : IDisposable
{
    private readonly FileStream fs;
    private readonly BufferedStream bs;
    private readonly StreamReader sr;

    public StreamWrapper(string fileName, FileMode mode)
    {
        fs = new FileStream(fileName, mode);
        bs = new BufferedStream(fs);
        sr = new StreamReader(bs);
    }

    public StreamReader Reader
    {
        get { return sr; }
    }

    public void Dispose()
    {
        sr.Dispose();
        bs.Dispose();
        fs.Dispose();
    }
}

С некоторым усилием, StreamWrapper мог быть пересмотрен, чтобы быть более универсальным и допускающим повторное использование.

0
ответ дан 29 November 2019 в 23:12
поделиться

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

using (Stream Reader sr = new StreamReader( new BufferedStream( new FileStream("c:\file.txt", FileMode.Open))))
{
    // all three get disposed when you're done
}
0
ответ дан 29 November 2019 в 23:12
поделиться

Оператор использования является синтаксическим сахаром, который преобразовывает в:

   try
   {
      obj declaration
      ...
   }
   finally
   {
      obj.Dispose();
   }

можно явно звонить, Располагают на объектах, но это не будет столь же безопасно, с тех пор, если один из них выдает исключение, ресурсы не будут освобождены правильно.

-1
ответ дан 29 November 2019 в 23:12
поделиться
Другие вопросы по тегам:

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