Trouble assigning value to integers inside a function to be referred to later scope issue I think

I'm learning C#. (6 hours in) I'm more comfortable with Ruby and Javascript and am finding C# fun, yet way tighter in what it will allow you to do, so I am rediscovering simple functions. I'm trying to build a simple calculator just to transition to the C# way of doing things and I keep hitting scope issues.

Here's the code. The NumSelect function is breaking it. I want a user to be able to type in 2 numbers in the console and then they'll be added. Once that works I'll create other math operations and throw in some logic to have the user select with operation they would like to do and then ask them for their inputs and then do the calculation.

The error is

calculator.cs(18,9): error CS0103: The name `number1' does not exist in the current context

and it's hitting it at very instance of number1 and number2 beyond the NumSelector function. So it seems like a scope issue, but I can't figure out the right approach for assigning these variables in a function so I only have to do it once.

using System;

class SimpleMath
{
    public int Add(int number1, int number2)
    {
        int result = number1 + number2;
        return result;
    }
    public int Subtract(int number1, int number2)
    {
        int result = number1 - number2;
        return result;
    }
    //this function will assign the inputs to variables
    public int NumSelect()
    {
        number1 = Console.ReadLine;
        number2 = Console.ReadLine;
    }
    static void Main()
    {
        SimpleMath operation = new SimpleMath();

        Console.WriteLine("Give me two numbers and I will add them");
        operation.NumSelect();
        int result = operation.Add(number1, number2);
        Console.WriteLine("{0} + {1} = {2}", number1, number2, result);

    }
}
Jon Skeet
people
quotationmark

Well you need to decide whether these numbers are meant to be part of the state of your object or not. If they are, make them fields. If they're not, don't. In this case, I'd probably keep them as local variables and change your NumSelect code to simply return one number entered by the user - and call it twice:

public int NumSelect()
{
    string line = Console.ReadLine();
    return int.Parse(line);
}

static void Main()
{
    SimpleMath operation = new SimpleMath();

    Console.WriteLine("Give me two numbers and I will add them");
    int number1 = operation.NumSelect();
    int number2 = operation.NumSelect();
    int result = operation.Add(number1, number2);
    Console.WriteLine("{0} + {1} = {2}", number1, number2, result);
}

You could change your whole class to make the values fields, and remove the parameters, like this:

class SimpleMath
{
    private int number1;
    private int number2;

    public int Add()
    {
        int result = number1 + number2;
        return result;
    }

    public int Subtract()
    {
        int result = number1 - number2;
        return result;
    }

    public int SelectNumbers()
    {
        number1 = int.Parse(Console.ReadLine());
        number2 = int.Parse(Console.ReadLine());
    }

    static void Main()
    {
        SimpleMath operation = new SimpleMath();

        Console.WriteLine("Give me two numbers and I will add them");
        operation.NumSelect();
        int result = operation.Add();
        Console.WriteLine(
            "{0} + {1} = {2}",
            operation.number1,
            operation.number2,
            result);   
    }
}

This doesn't feel like the best approach to me - I'd take the earlier approach of using local variables in Main - but I wanted to show you the alternative. Note that you can only access operation.number1 in Main because the Main method is in the same type - that should raise warning bells for you.

people

See more on this question at Stackoverflow