Cress
Cress

Reputation: 432

Passing a static variable by reference in a class constructor

public class Gameplay {
   public static int count = 0;

   AClass aClass = new AClass(ref count);
}

public class AClass {
   public int count { get; set; }

   public AClass(ref int c) {
       this.count = c;
   }

   public void printCount() {
       Console.WriteLine(this.count.ToString());
   }
}

I have two classes like the ones above. Suppose the count variable of Gameplay increases in another class that does Gameplay.count++. I want AClass.count to always be equal to Gameplay.count.

Now, surely I could just use Gameplay.count inside AClass but if I have different counts to pass in different instances of AClass it's better to have the reference to the count you want to access. The above example always writes 0 even if Gameplay count has increased.

Upvotes: 0

Views: 2937

Answers (4)

Jacob Krall
Jacob Krall

Reputation: 28825

What would you expect this code to do?

int c = 0;
int count = c;
c++;

c and count are both references, yet mutating c somehow does not change the value of count.

It's exactly the same situation in your code.

In your code, this line:

this.count = c;

does not copy the reference to c. It copies the value at the time of the assignment to the value-type backing field for count.


You can pass a lambda expression to the constructor if you need AClass to be able to access the value of some arbitrary integer.

public class Gameplay {
   public static int count = 0;

   AClass aClass = new AClass( () => count );
}

public class AClass {
   public int count { get { return this.getCount(); } }
   private readonly Func<int> getCount;

   public AClass(Func<int> getCount) {
       this.getCount = getCount;
   }

   public void printCount() {
       Console.WriteLine(this.count.ToString());
   }
}

Upvotes: 3

Bob
Bob

Reputation: 555

Wrap the count into another class

    public class CounterHolder
    {
        public int count = 0;
    }
    public class Gameplay
    {
        public static CounterHolder counterHolder = new CounterHolder();
        AClass aClass = new AClass(counterHolder);

        public void DoSomething()
        {
            // Something
            counterHolder.count++;
            aClass.printCount();
        }
    }

    public class AClass
    {
        private CounterHolder _counterHolder;

        public AClass(CounterHolder counterHolder)
        {
            _counterHolder = counterHolder;
        }

        public void printCount()
        {
            Console.WriteLine(_counterHolder.count.ToString());
        }
    }

Upvotes: 0

Ann L.
Ann L.

Reputation: 13965

That's going to be challenging, because integers are value types.

You might try using a class that has a Count property, and pass that in instead. If you have multiple objects with Count properties, you could declare an interface with a property of Count (let's call it IHasCount) and have AClass take an instance of IHasCount as its parameter.

Your design begins to sound like it uses the Singleton pattern, which is discouraged nowadays. You might want to read up on that.

Upvotes: 0

sstan
sstan

Reputation: 36483

In your constructor:

public AClass(ref int c) {
    this.count = c;
}

... even though the parameter c is passed by reference, as soon as you assign it to this.count, the value gets copied. So any changes to c or Gameplay.count will not be reflected in this.count.

Upvotes: 1

Related Questions