Why can't I use a local variable inside of a Using block?

I'm still learning the particulars of C# so please forgive me if this rudimentary. I have been looking for an answer to this but haven't found one.

I have declared the local variable (in my function):

string myVar;

I keep getting the error, "Use of unassigned local variable" when I try to return it:

return (myVar);

What am I doing wrong here?

public string GetSomethingFromDB()
{
    string connectionString;
    string sql;
    string myVar;

    connectionString = "Data Source=MyServer; Port=MyPort; User ID=someuser; Password=mypassword; Database=myDatabase";
    sql = "select something from something";
    using (AseConnection conn = new AseConnection(connectionString))
    {
        using (AseCommand cmd = new AseCommand(sql, conn))
        {
            try
            {
                conn.Open();
                using (AseDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        myVar= reader.GetString("column1").Trim();
                    }
                    reader.Close();
                    reader.Dispose();
                }
                conn.Close();
                conn.Dispose();
                cmd.Dispose();
                return (myVar);
            }
            catch (AseException ex)
            {
                //do some stuff
            }
            finally
            {
                 //do some stuff
            }
        }
    }
} 
Jon Skeet
people
quotationmark

This has nothing to do with the using statement, and everything to do with the while loop. Leaving everything else aside, this is the problem, in essence:

string myVar;
while (someNonConstantCondition)
{
    myVar = someValue;
}
return myVar;

The compiler is saying that the while loop body may never execute because the condition may be false.

I would suggest changing the code to:

if (reader.Read())
{
    return reader.GetString("column1").Trim();
}

... and use using statements to make sure that all your commands etc are disposed automatically. (You've already got those using statements, so you can remove the calls to conn.Close(), conn.Dispose() and cmd.Dispose() anyway.)

Note that this will only read the first row from the results, whereas you're currently returning the value from the last row. If that's important to you, there may be bigger design problems.

Next you'll need to consider what happens if reader.Read() returns false... do you want to throw an exception? Return something else? By putting the return statement directly at the place where you've managed to read some data, the question of what happens if you can't read some data is clearer, IMO.

people

See more on this question at Stackoverflow