2015-01-21 4 views
1

Так что я довольно новичок в C# (не в общем программировании), и я написал код с почти ошибкой обработки нуля, чтобы сделать доказательство концепции для работы только в VS. Теперь я готов к созданию некоторой обработки ошибок в приложении, чтобы приложение могло быть развернуто. Итак, теперь у меня возникают проблемы с выяснением того, как/где объявлять переменные, чтобы я мог правильно настроить блок Try Catch.Правильный способ объявить переменную для использования за пределами блока try

Так с примитивными типами я просто создать переменную вне блока

Перед:

String TheString = "Some times I break"; 
SomeFunctionThatBreaks(TheString); 

SomeFunctionThatDoesntBreak(TheString); 

После:

String TheString =""; 
Try 
{ 
TheString="Some Times I break"; 
SomeFunctionThatBreaks(TheString); 
} 
Catch 
{ 
MessageBox.Show("Error") 
return false; 
} 
SomeFunctionThatDoesntBreak(TheString); 

Однако со сложными типами, такими как FileStream Я не уверен, надлежащего способа создания ПУСТОЙ переменной для последующего использования:

Befo Re:

 FileStream SourceFile = File.OpenRead(TheFile); 
     StreamReader sr ; = new StreamReader(SourceFile);    
      char[] block = new char[3]; 
      byte[] header = new byte[6]; 
      SourceFile.Read(header, 0, 6); 
      SourceFile.Seek(0, 0); 
      encoding = (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; 
      sr.ReadBlock(block, 0, 3); 
      String sBlock = new String(block); 
      SourceFile.Seek(0, 0); 
    if(sBlock=="ABC") 
    { 
MyFunction(SourceFile); 
    } 

причины ошибки компиляции:

FileStream SourceFile ; 
    String sBlock =""; 
    Encoding encoding; 
    StreamReader sr; 

    try 
    { 
     SourceFile = File.OpenRead(TheFile); 
     sr = new StreamReader(SourceFile); 
     char[] block = new char[3]; 
     byte[] header = new byte[6]; 
     SourceFile.Read(header, 0, 6); 
     SourceFile.Seek(0, 0); 
     encoding = (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; 
     sr.ReadBlock(block, 0, 3); 
     sBlock = new String(block); 
     SourceFile.Seek(0, 0); 

    } 
    catch (Exception ex) 
    { 
     String Error = "Error Accessing: " + TheFile + " System Message: " + ex.Message; 
     EventLog.LogEvent(dtmLogging.LogEventType.Error, Error); 
     MessageError(Error, "MyFunction()"); 
    } 
    if(sBlock=="ABC") 
    { 
MyFunction(SourceFile); //THIS LINE DOES NOT COMPILE: Use of unassigned variables 
    } 

Предлагаемые изменения: // Если я это приложение изменений, кажется, работает хорошо, но я не уверен, что это «правильный»

FileStream SourceFile =null; 
    String sBlock =""; 
    Encoding encoding = null; 
    StreamReader sr = null; 

Спасибо за любую помощь

+0

Это красная ошибка, которая не позволяет мне компилировать или отлаживать. Я знаю разницу – Cade

+0

Я не понимаю, почему вы не делаете то, что делали раньше - назначьте переменную (ы) вне блока try. Если для сложных типов вы думаете, что может быть исключение, возникшее во время строительства или инициализации. В этом случае непризнанная ошибка var указывает на действительную проблему - вы не знаете, была ли построена/инициализирована переменная после блока try. – hatchet

+0

Я отредактировал код, чтобы включить строку, которая вызывает ошибку – Cade

ответ

2

Я бы рекомендовал не установки переменной в NULL в декларации, по крайней мере, в случае, например, ваш образец кода. В этом случае установка его на нуль фактически затушевывает другую проблему с кодом как написано: блок catch позволяет методу продолжать выполнение (и пытается использовать объект FileStream), даже если что-то пошло не так, и объект FileStream, скорее всего, неизвестен и не должны использоваться.

Причина, по которой вы видели «красную ошибку» изначально, заключалась в том, что код мог «провалиться» в блок catch. Если вы добавили return или в конце блока catch, чтобы вернуть управление вызывающему, красная ошибка исчезла бы, и вам не понадобилось бы устанавливать переменную в нуль.

Чтобы ответить на ваш первоначальный вопрос, объявление переменных, как вы это делали, может быть разумным способом структурирования кода. Лучше всего включить все ваши действия в FileStream в блоке try, чтобы переменные можно было определить и ссылаться на все внутри этого же блока. Если блок try начинает становиться слишком большим, это, вероятно, указывает на то, что вы должны реорганизовать часть своего содержимого на более мелкие утилиты, которые могут быть вызваны из блока try.

И один связанный момент: вы должны иметь using объявления вокруг объектов, которые необходимо закрыть или иным образом очистить после использования (т.все, что реализует интерфейс IDisposable). Это гарантирует, что файлы будут закрыты, а другие ресурсы будут выпущены независимо от того, что происходит в остальной части кода.

Например:

try 
{ 
    using (FileStream SourceFile = File.OpenRead(TheFile)) 
    using (StreamReader sr = new StreamReader(SourceFile)) 
    { 
     char[] block = new char[3]; 
     byte[] header = new byte[6]; 
     SourceFile.Read(header, 0, 6); 
     SourceFile.Seek(0, 0); 
     Encoding encoding = (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8; 
     sr.ReadBlock(block, 0, 3); 
     String sBlock = new String(block); 
     SourceFile.Seek(0, 0); 

     if (sBlock=="ABC") 
     { 
      MyFunction(SourceFile); 
     } 

     // And do anything else you want with SourceFile & sr here 
    } 
} 
catch (Exception ex) 
{ 
    String Error = "Error Accessing: " + TheFile + " System Message: " + ex.Message; 
    EventLog.LogEvent(dtmLogging.LogEventType.Error, Error); 
    MessageError(Error, "MyFunction()"); 
} 

Надеется, что это помогает.

Смежные вопросы