JMD
JMD

Reputation: 403

Assign Variable to another Variable and have changes in one be mirrored in the other

Is it possible to assign a variable to another variable and when you change the second variable the change waterfalls down to the first variable?

Like this.

int a = 0;
int b = a;
b = 1;

now both b and a would = 1.

The reason I ask this is because I have 4 objects I'm keeping track of, and I keep track of each using a 5th object called currentObject that equals whichever of the 4 objects the user is using. However, I would like to just make a change to the currentObject and just have it waterfall to the variable it came from.

Thanks

Upvotes: 9

Views: 35070

Answers (6)

Jonathan Plumb
Jonathan Plumb

Reputation: 435

I know this is an old post, but there are a couple ways I'd handle this scenario.

First, you could create private variables and then have public getters/setters that modify the private values as desired:

private int firstVar = 10;
private int secondVar = 20;

public int FirstVar
{
    get
    {
        return firstVar;
    }
    set
    {
        firstVar = secondVar = value;
    }
}
public int SecondVar
{
    get
    {
        return secondVar;
    }
    set
    {
        firstVar = secondVar = value;
    }
}

public void SomeFunction()
{
    Console.WriteLine("FirstVar=" + FirstVar); // Output: "FirstVar=10"
    Console.WriteLine("SecondVar=" + SecondVar); // Output: "SecondVar=20"

    FirstVar = 30;
    Console.WriteLine("FirstVar=" + FirstVar); // Output: "FirstVar=30"
    Console.WriteLine("SecondVar=" + SecondVar); // Output: "SecondVar=30"
}

Another way would be to create a custom class that can do the same thing:

    public class MyVariable
    {
        protected static List<MyVariable> _instances;

        public int Value { get; set; }

        public MyVariable() 
        {
            if (_instances == null) _instances = new List<MyVariable>();
            _instances.Add(this);
        }
        public MyVariable(int value) : base() { Value = value; }

        public void SetAll(int value) { foreach (MyVariable myVar in _instances) myVar.Value = value; }
        public override string ToString() { return Value.ToString(); }
    }

    public void SomeOtherFunction()
    {
        MyVariable var1 = new MyVariable(30);
        MyVariable var2 = new MyVariable(50);

        Console.WriteLine("var1=" + var1.ToString()); // Output: "var1=30"
        Console.WriteLine("var2=" + var2.ToString()); // Output: "var2=50"

        var1.SetAll(100);
        Console.WriteLine("var1=" + var1.ToString()); // Output: "var1=100"
        Console.WriteLine("var2=" + var2.ToString()); // Output: "var2=100"
    }

Cheers!

Upvotes: 1

Ahmed Fwela
Ahmed Fwela

Reputation: 973

First of all you should understand what you are doing in your previous code

  1. Create a 4-byte-sized variable named "a" in memory and after that give it a value of 0
  2. Create a 4-byte-sized variable named "b" in memory and after that give it a value of (a)'s value [Currently 0]
  3. Change the Value of the variable "b" to 1

But this isn't what you want, what you want is something more like this

  1. Create a 4-byte-sized variable named "a" in memory and after that give it a value of 0
  2. Create a 4-byte-sized variable named "b" in memory and after that change the address of the variable "b" so that it doesn't refer to these 4 bytes anymore,but instead refer to (a)'s 4 bytes

What you are asking for is both Bad + Impossible

  • Bad : you have just created an empty space of 4 bytes that have no use at all and completely ignored them
  • Impossible : Because you can't change the address of a value type (thus they are called "value" types not "reference" types)

But what you "Should" be asking for is this

  1. Create a 4-byte-sized variable named "a" in memory and after that give it a value of 0
  2. Create an address that refers to the variable a
  3. Change the value of a through this address

And this approach is actually totally OK, and it uses Pointers, Pointers simply are addresses in memory.

Note : To use pointers you have to Allow unsafe code in Project > Build

In code here is how to do it :

int a = 5;
unsafe //use unsafe around the areas where pointers exist
{
    int* b = &a; //create an address named b that refers to a
    *b = 1; //change the value of the variable that exists at the address b to 1

    //now a = 1
}

Upvotes: 5

Samy Arous
Samy Arous

Reputation: 6814

What your are looking for is a design pattern commonly know as observer. An object B will monitor an object A (or 4 objects since this is what u need) and when A is modified, B is notified and update its state accordingly.

In the case of C#, I would use events. For example, define event ValueChanged on A. B would listen to this event and update its value.

public delegate void ChangedEventHandler(object sender, EventArgs e);

Class A
{
   public event ChangedEventHandler Changed;
   int val = 0;
   int Val
   {
      get { return val;}
      set { 
          if ( val != value ) val = value
          {
              val = value;
              if (Changed != null) Changed(this, new EventArgs());
          }

   }
}


class B
{
    A obj1, obj2, obj3, obj4;
    int Val {get;set;}
    A CurrentlyWatched {get;set;}

    public B()
    {
       obj1 = new A();
       obj1.Changed += new ChangedEventHandler(ElementChanged);
       obj2 = new A(); 
       ...
    }

    private void ElementChanged(object sender, EventArgs e) 
      {
         this.CurrentlyWatched = sender as A;
         this.Val = CurrentlyWatched.Val;
      }
}

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500665

You need to distinguish between objects, references and variables. If you have two different variables (which aren't aliased via ref/out in a method, etc) then those will be independent.

However, if two variables refer to the same object (i.e. their type is a class, and their values are equal references), then any changes to that object will be visible via either variable. It sounds like this is what you want to achieve. For example:

public class SomeMutableClass
{
    public string Name { get; set; }
}

// Two independent variables which have the same value
SomeMutableClass x1 = new SomeMutableClass();
SomeMutableClass x2 = x1;

// This doesn't change the value of x1; it changes the
// Name property of the object that x1's value refers to
x1.Name = "Fred";
// The change is visible *via* x2's value.
Console.WriteLine(x2.Name); // Fred

If you're not entirely comfortable with how reference types and objects work, you may wish to read my article about them.

EDIT: One analogy I often use is of a house. Suppose we have two pieces of paper (variables). The same house address is written on both pieces of paper (that's the value of each variable, the reference). There's only one house. If someone uses the first piece of paper to get to the house, then paints the door red, they're not changing anything about their piece of paper - they're changing something about the house. Then if someone uses the second piece of paper to get to the house, they'll see the front door is red too. There's only one house, however many pieces of paper have its address written on them.

Upvotes: 20

Nikhil Agrawal
Nikhil Agrawal

Reputation: 48568

With struct/value types ------- NO

like int, boolean, double etc.

With Reference types -------- YES

like classes, objects etc.

Upvotes: 4

L3tha1Am6iti0n
L3tha1Am6iti0n

Reputation: 11

Here you go you can change the code in the get and set functions to do pretty much anything. You can not declare this in a function however.

    int a;
    int b
    {
        get
        {
            return a;
        }
        set
        {
            a = value;
        }
    }

Upvotes: -1

Related Questions