1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace school_project_final
{
    class Program
    {
        static void Main()
        {
            Console.WriteLine("who are you...?");
            
            string name = Console.ReadLine();

            Console.WriteLine("how old are you " + name + "?");

            int age;

            try
            {
                age = Convert.ToInt32(Console.ReadLine());
            }
            catch (FormatException)
            {
                Console.WriteLine("that's... not a number");
                return; 
            }
            finally
            {
                if (System.Convert.ToInt32(age) >= 18)
                {
                    Console.WriteLine("so you're " + age + " years old, good to know");
                }
                else if (System.Convert.ToInt32(age) < 18 && System.Convert.ToInt32(age) > 0)
                {
                    Console.WriteLine("so you're a child, how worthless");
                }

                Console.ReadLine();
            }
        }
    }
}

if (System.Convert.ToInt32(age) >= 18)

This line returns an error that the age variable does not exist, but the other lines after it like

Console.WriteLine("so you're " + age + " years old, good to know");

and

else if (System.Convert.ToInt32(age) < 18 && 
         System.Convert.ToInt32(age) > 0)

do not return this error, how do I fix this?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
moewmoew
  • 11
  • 2
  • 2
    Please provide the exact error message in the question. Don't attempt to paraphrase it. – mason Apr 04 '22 at 14:54
  • 3
    The error doesn't say the variable doesn't *exist*. Read it again, but more carefully. Then think about what the semantics of `try..catch..finally` are -- specifically, the `finally` block *always* executes, even if the code in the `try` should not. If you put these together it should become apparent why the compiler is complaining, and what the fix is. – Jeroen Mostert Apr 04 '22 at 14:54
  • error CS0165: Use of unassigned local variable 'age' – moewmoew Apr 04 '22 at 14:54
  • is there an indepth explanation to why this happens tho? – moewmoew Apr 04 '22 at 14:56
  • no thats not what happens – moewmoew Apr 04 '22 at 14:56
  • @Austin: the compiler is in fact working as designed. The language specification has detailed rules on when a variable is or is not considered "definitively assigned", and the compiler is required to warn if a variable is used that is not definitively assigned. Reflexively adding an initialization is not a good idea -- the message is trying to warn you that there's an unforeseen path in your code, which probably needs a more careful fix. – Jeroen Mostert Apr 04 '22 at 14:56
  • @mason, im initializing the age variable before checking the user input – moewmoew Apr 04 '22 at 14:56
  • 1
    I'd suggest you remove the `finally` block. You don't want that code within to *always* run, you only want it to run if the code before it didn't result in an exception (where the `catch` block has a `return`) – Charles Mager Apr 04 '22 at 14:56
  • Does this answer your question? [Why did I get the compile error "Use of unassigned local variable"?](https://stackoverflow.com/questions/9233000/why-did-i-get-the-compile-error-use-of-unassigned-local-variable) – gunr2171 Apr 04 '22 at 14:58
  • 1
    Also I would like to add, why do you use convert.ToInt32 twice? Here if (System.Convert.ToInt32(age) >= 18), in age you already have the input value conversion ToInt32, why converting again? You should use if (age >= 18) instead. – mbd Apr 04 '22 at 15:13
  • Note that `age` is already an `Int32` so this call does nothing: `System.Convert.ToInt32(age)` – JAlex Apr 05 '22 at 13:20
  • Don't use convert. Use `int.TryParse()` instead. – JAlex Apr 05 '22 at 13:59

2 Answers2

2

finally always runs after try/catch, even if there's an execption That's why compiler doesn't think there's a value for age

Add your if/else statements in try block

try
{
    age = Convert.ToInt32(Console.ReadLine());
    
    if (age >= 18) 
    {
        Console.WriteLine("so you're " + age + " years old, good to know");
    } 
    else if (age < 18 && age > 0) 
    {
        Console.WriteLine("so you're a child, how worthless");
    }

    Console.ReadLine();
}
catch (FormatException)
{
     Console.WriteLine("that's... not a number");
     return; 
}
spaleet
  • 838
  • 2
  • 10
  • 23
1

The compiler thinks the age value is not assigned in the finally block because it's scope is evaluated regardless of the try block successfully running. In other words, if you got an exception, the finally block wouldn't have any value of age unless you assigned it to something else in the catch.

Your if/else statements should be in the try block

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245