Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#2.0
All:
private void AppendData(string strData, string strFileName)
        {
            FileStream fStream;
            StreamWriter sWriter;
            try
            {
                fStream = new FileStream(strFileName, FileMode.Append);
                sWriter = new StreamWriter(fStream);
                sWriter.WriteLine(strData);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                sWriter.Close();
                sWriter.Dispose();
                fStream.Close();
                fStream.Dispose();
            }
        }
The above code tells during compiling that "Use of unassigned local variable. It points to sWriter and fStream inside the finally block". Why I did it this way was, I read in a forum that .NET does not require us to explicitly initialize a variable. Is my understanding wrong ?
 
The code works fine if I initialize it to NULL.
private void AppendData1(string strData, string strFileName)
        {
            FileStream fStream = null;
            StreamWriter sWriter = null;
            try
            {
                fStream = new FileStream(strFileName, FileMode.Append);
                sWriter = new StreamWriter(fStream);
                sWriter.WriteLine(strData);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                sWriter.Close();
                sWriter.Dispose();
                fStream.Close();
                fStream.Dispose();
            }
        }
Can you throw some light here...
Posted 26-Jun-12 19:16pm
Edited 26-Jun-12 19:32pm
v2
Comments
OriginalGriff at 27-Jun-12 0:45am
   
Answer updated
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

If the compiler can see any route through the software such that the variable does not get a value, it complains. Such a route exists:
FileStream fStream;
StreamWriter sWriter;
try
   {
   fStream = new FileStream(strFileName, FileMode.Append);
This line causes an exception - fStream is not modified.
These lines are skipped:
   sWriter = new StreamWriter(fStream);
   sWriter.WriteLine(strData);
   }
Execution continues here:
catch (Exception ex)
   {
   MessageBox.Show(ex.Message);
   }
Then the finally block is executed:
finally
   {
This is the first reference to sWriter since it was declared.
   sWriter.Close();
   sWriter.Dispose();
This is the first reference to fStream since it was declared.
   fStream.Close();
   fStream.Dispose();
   }
 
[edit]
Setting it to null gets rid of the compilation problem, but introduces another: your finally block will cause an exception if your try/catch is triggered.
You need to check for null in each before you try to Close or Dispose. I would suggest rewriting this as:
private void AppendData(string strData, string strFileName)
        {
            try
            {
                using (FileStream fStream = new FileStream(strFileName, FileMode.Append))
                {
                     using (StreamWriter sWriter = new StreamWriter(fStream))
                     {
                          sWriter.WriteLine(strData);
                     }
                 }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
- OriginalGriff[/edit]
  Permalink  
v2
Comments
amitgajjar at 27-Jun-12 1:43am
   
5+ for edit block, best way of disposing stream. also see my answer for variable initialization. thanks.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Hi,
 
Although the Edited code by OriginalGiff is perfect. use of using is the best way to dispose any of the variable. but in case you need to initialize your variable in the beginning then don't assign null, instead use the default value of that type.
 
say for example, if we have our custom class Customer , we have implemented IDisposable with our class and if you want to use finally block then good practice is to use like,
 
good
Customer newCustomer = default(Customer); 
bad
Customer newCustomer = null;
 
Reason is if your class is changed to not Nullable then you need to change everywhere. instead above will be helpful to you in future.
 
And as far as Disposing is concern follow the way of OriginalGriff.
 
Thanks
-Amit
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Peter Leow 160
1 Mika Wendelius 156
2 Abhinav S 155
3 Sergey Alexandrovich Kryukov 115
4 TheRealSteveJudge 114
0 Sergey Alexandrovich Kryukov 8,593
1 OriginalGriff 6,536
2 Peter Leow 3,727
3 Zoltán Zörgő 3,436
4 Richard MacCutchan 2,417


Advertise | Privacy | Mobile
Web02 | 2.8.150123.1 | Last Updated 27 Jun 2012
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100