Question

I've got int variable lets say:

int x = 0;

then I pass it to the class which should hold it and which has Print method which prints current value of that variable.

Then in another class I change the i value and as a result I would like to have in MyPrinter class after calling print new value of the i variable printed. Is it possible?

sample code below:

int x = 0;
MyPrinter printer = new MyPrinter(x);
printer.Print(); //Expected result is 0
x++;
MyPrinter.Print(); //Expected result is 1
Was it helpful?

Solution 2

You could change your class to take a Func<int> and close over x instead e.g.

public class Printer
{
    private readonly Func<int> f;
    public Printer(Func<int> f)
    {
        this.f = f;
    }

    public void Print()
    {
        Console.WriteLine(f());
    }
}


MyPrinter printer = new MyPrinter(() => x);
printer.Print(); //Expected result is 0
x++;
MyPrinter.Print(); //Expected result is 1

OTHER TIPS

When an int is passed to a method or constructor it is passed by value and the callee gets a copy of the value. This copy is independent of the original and hence updates to one are not reflected on the other. It is possible to pass it by ref but that isn't suitable here because ref can't be used on a field of a type.

In order to make this work you are going to need to put the int value into a class and then pass that class into MyPrinter.

class Container {
  public int Value;
}

Container x = new Container();
MyPrinter printer = new MyPrinter(x);
printer.Print();
x.Value++;
MyPrint.Print();  // x.Value is 1 

As others have pointed out, you can't do this without either wrapping the int up in a reference type or doing some other funky stuff.

However, I think this misses the point, which is that you're addressing the problem all wrong. Here's a more OOP-friendly way of approaching your problem:

public class Printer
{
    public int Value { get; set; }

    public Printer(int x)
    {
        Value = x;
    }

    public void Print()
    {
        Console.WriteLine(Value);
    }
}

public class Program
{
    public static void Main()
    {
        var printer = new Printer(0);

        printer.Print();    
        printer.Value++;        
        printer.Print();
    }
}

This cannot be done, unless you wrap the int in a reference type so that MyPrinter holds the int as part of a reference to the same object you're modifying.

EDIT: @JaredPar has the same answer, but with a clean code example! :)

In order for this to work, you need to pass something that is a reference type instead of a value type. Instance primitives are always passed by value, but there is nothing preventing you from passing the instance - but this would require a redesign of your classes: Consider the following (c#-like pseudocode)...

public class Container
{
    public int x;
}

... // some implementation in another class
Container myContainer = new Container();
myContainer.x = 0;

MyPrinter printer = new MyPrinter(myContainer);
printer.Print(); //Result is 0
myContainer.x ++;
MyPrinter.Print(); //Result is 1

This assumes that the MyPrinter class knows what to do with a Container instance.

What's going on here? Well a primitive, like int is passed by value - which means that the program makes a copy when passing it into the method:

int x = 0;
MyPrinter printer = new MyPrinter(x); // Makes a copy of x, and passes the copy to MyPrinter
printer.Print(); //Expected result is 0 - correct
x++; // Increments the local variable, but not the copy
MyPrinter.Print(); //Expected result is 1 - incorrect because only the local variable is updated.

As opposed to:

Container myContainer = new Container();
myContainer.x = 0;

MyPrinter printer = new MyPrinter(myContainer); // Passes the reference to the same instance
printer.Print(); //Result is 0 - because it uses the variable attached to the instance
myContainer.x ++; // Increments the variable attached to the instance
MyPrinter.Print(); //Result is 1 - because the instance is still the same in both places - due to being passed by reference.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top