tags:

views:

122

answers:

5

I got the error Use of unassigned local variable 'dictionary' despite I assigned the value in the following code:

private static void UpdateJadProperties(Uri jadUri, Uri jarUri, Uri notifierUri)
    {
        Dictionary<String, String> dictionary;

        try
        {
            String[] jadFileContent;

            // Create an instance of StreamReader to read from a file.
            // The using statement also closes the StreamReader.
            using (StreamReader sr = new StreamReader(jadUri.AbsolutePath.ToString()))
            {
                Char[] delimiters = { '\r', '\n' };
                jadFileContent = sr.ReadToEnd().Split(delimiters, System.StringSplitOptions.RemoveEmptyEntries);
            }

            // @@NOTE: Keys contain ": " suffix, values don't!
            dictionary = jadFileContent.ToDictionary(x => x.Substring(0, x.IndexOf(':') + 2), x => x.Substring(x.IndexOf(':') + 2));

        }
        catch (Exception e)
        {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }

        try
        {
            if (dictionary.ContainsKey("MIDlet-Jar-URL: "))
            {
                // Change the value by Remove follow by Add

            }
        }
        catch (ArgumentNullException ane)
        {

            throw;
        }

    }

The error is from the line:

if (dictionary.ContainsKey("MIDlet-Jar-URL: "))

Can any one help me out here, pls? TIA

+3  A: 

You need to be explicit here:

Dictionary<String, String> dictionary = null;

There's the possibility it won't be assigned when you try to use it in your second try statement, for example if you throw an exception immediately in the first try, the dictionary wouldn't point to anything. This won't prevent a null reference exception (you'll have to handle that), it just makes your intent clear to the compiler.

Nick Craver
Thanks Nick, silly me!
codemonkie
A: 

The compiler does not know you assigned anything to it. For all it knows an exception will get thrown and the assignment will never happen.

Just assign null to the dictionary when you declare it.

Matt Greer
Thanks. Consequence of not paying attention in programming class over 10 years ago when I learn Java, try..catch is more or less the same in C# I suppose.
codemonkie
+1  A: 

If an exception is thrown before the following line:

dictionary = jadFileContent.ToDictionary(x => x.Substring(0, x.IndexOf(':') + 2), x => x.Substring(x.IndexOf(':') + 2));

dictionary will be unassigned.

A possible code path is:

private static void UpdateJadProperties(Uri jadUri, Uri jarUri, Uri notifierUri)
    {
        Dictionary<String, String> dictionary;

        try
        {
            String[] jadFileContent;

            // Create an instance of StreamReader to read from a file.
            // The using statement also closes the StreamReader.
            using (StreamReader sr = new StreamReader(jadUri.AbsolutePath.ToString()))
            {
                Char[] delimiters = { '\r', '\n' };
                jadFileContent = sr.ReadToEnd().Split(delimiters, System.StringSplitOptions.RemoveEmptyEntries);
                throw new Exception();
            }

            // @@NOTE: Keys contain ": " suffix, values don't!
            //dictionary = jadFileContent.ToDictionary(x => x.Substring(0, x.IndexOf(':') + 2), x => x.Substring(x.IndexOf(':') + 2));

        }
        catch (Exception e)
        {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }

        try
        {
            if (dictionary.ContainsKey("MIDlet-Jar-URL: "))
            {
                // Change the value by Remove follow by Add

            }
        }
        catch (ArgumentNullException ane)
        {

            throw;
        }

    }
strager
A: 

Your try..catch block creates a scope. Your dictionary is initializes in the first try block, but it may never reach that code (e.g., if something throws an exception before). So the second try block may access the uninitialized dictionary.

Michael Stum
A: 

You problem is that when you defined it: Dictionary<String, String> dictionary; you didn't initialize it. What is happening is that you are assigning a value in a try statement which, depending on what else happens in that statement, may not ever make it to the assignment code of the dictionary variable.
You could combine the two try catch blocks. This way you don't need to initialize it, because it is all being used in the same branch of code. There is no way that the dictionary variable can be used before it is assigned.

try
    {
        Dictionary<string,string> dictionary;
        String[] jadFileContent;

        // Create an instance of StreamReader to read from a file.
        // The using statement also closes the StreamReader.
        using (StreamReader sr = new StreamReader
          (jadUri.AbsolutePath.ToString()))
        {
            Char[] delimiters = { '\r', '\n' };
            jadFileContent = sr.ReadToEnd().Split(delimiters,
                 System.StringSplitOptions.RemoveEmptyEntries);
        }

        // @@NOTE: Keys contain ": " suffix, values don't!
        dictionary = jadFileContent.ToDictionary
         (x => x.Substring(0, x.IndexOf(':') + 2), 
          x => x.Substring(x.IndexOf(':') + 2));


        if(dictionary == null)
        {
           throw new Exception("dictionary is null");
           //or ArgumentNullException since you specified 
           //in the second try catch block.
        }

        if (dictionary.ContainsKey("MIDlet-Jar-URL: "))
        {
            // Change the value by Remove follow by Add

        }

    }
    catch (ArgumentNullException ane)
    {

        throw;
    }
    catch (Exception e)
    {
        // Let the user know what went wrong.
        Console.WriteLine("The file could not be read:");
        Console.WriteLine(e.Message);
    }
Kevin
Thanks, same comment as I place above.
codemonkie