-2
public class SomeClass
{
    public X x;
    string name;
    string someInfo;
    public SomeClass(string name,...)
    {
       //....
    }
}
public class X
{
}

SomeClass a = new SomeClass(~~~);
SomeClass b = new SomeClass(~~~);

a.x = new X();    //this new X instance call X1
b.x = a.x;        //a.x = b.x => X1


a.x = new X();    //this new X instance call X2
                  //a.x == X2   b.x== X1
                  //b.x doesn't change when a.x changed.

//////////////////////////////////////////////////////////////
a.x = new X(); //a.x= b.x =>X2 - this what i want.

I wnat to point out that b.x has the same address a.x .
If it's a C language, just point it out.
but in C#, ref keyword can use only parameter.
How can b.x have an address of an a.x?

ok. added infomation.

instance of a has 0x0000
instance of b has 0x0100
if a.x = new X() then a.x pointed X instance : 0xF000
Then b.x = a.x then b.x pointed X instance : 0xF000 Not a.x's adress:0x0000 + sizeof(X)
I want to b.x has a.x's Ardress. Not Value's Adress

angdroid
  • 81
  • 6

5 Answers5

1

Unfortunately, there is no native way to store a reference to a variable in C#. Luckily, there are many ways to have b's X object reference stay in sync with a's X object reference.

First, the classes:

  public class SomeClass
  {
    public X x;
  }

  public class X
  {
    public int i; // I added this int to verify which X object we're working with.
    public X(int i)
    {
      this.i = i;
    }
  }

Scenario 1: If you need to reference a new X object.

Option 1: If a and b need to be different SomeClass objects, you can simply update b's X object reference to a's X object reference.

  SomeClass a = new SomeClass();
  SomeClass b = new SomeClass();

  a.x = new X(1);
  b.x = a.x;
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:1, b.x.i:1
  a.x = new X(2);
  b.x = a.x;
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:2, b.x.i:2

Option 2: If b doesn't need to be different than a, have b reference the same SomeClass object that a does.

  SomeClass a = new SomeClass();
  SomeClass b = a;

  a.x = new X(1);
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:1, b.x.i:1
  a.x = new X(2);
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:2, b.x.i:2

Scenario 2: If you only need to modify an internal value of the X object.

Since a.x is the same X object as b.x, you can modify that object using either reference and view that change using the other reference.

  SomeClass a = new SomeClass();
  SomeClass b = new SomeClass();

  a.x = new X(1);
  b.x = a.x;
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:1, b.x.i:1
  a.x.i = 2;
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:2, b.x.i:2
  b.x.i = 3;
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:3, b.x.i:3

Scenario 3: If you want a different class to always have easy access to a's X object.

New class:

  public class SomeClass2
  {
    private SomeClass someClass;
    public X x { get { return someClass.x; } }
    public SomeClass2(SomeClass sc)
    {
      someClass = sc;
    }
  }

Using the new class:

  SomeClass a = new SomeClass();
  SomeClass2 b = new SomeClass2(a);

  a.x = new X(1);
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:1, b.x.i:1
  a.x = new X(2);
  Console.WriteLine($"a.x.i:{a.x.i}, b.x.i:{b.x.i}"); // a.x.i:2, b.x.i:2

Scenario 4: If you want a local alias to a.x.

  SomeClass a = new SomeClass();

  Func<X> func = () => a.x; // "func()" is now essentially an alias of "a.x"
  a.x = new X(1);
  Console.WriteLine($"a.x.i:{a.x.i}, func().i:{func().i}"); // a.x.i:1, func().i:1
  a.x = new X(2);
  Console.WriteLine($"a.x.i:{a.x.i}, func().i:{func().i}"); // a.x.i:2, func().i:2

Scenario 5: If you need to use the same class and have b.x always reference the same object as a.x.

You can use a Func<X> member of your class to act like similarly to a variable reference. This works but I don't necessarily recommend doing it because it is not intuitive and can cause confusion.

The class:

  public class SomeClass3
  {
    public Func<X> x;
  }

Using the class:

  SomeClass3 a = new SomeClass3();
  SomeClass3 b = new SomeClass3();

  X x1 = new X(1);
  a.x = () => x1;
  b.x = () => a.x();
  Console.WriteLine($"a.x().i:{a.x().i}, b.x().i:{b.x().i}"); // a.x().i:1, b.x().i:1
  X x2 = new X(2);
  a.x = () => x2;
  Console.WriteLine($"a.x().i:{a.x().i}, b.x().i:{b.x().i}"); // a.x().i:2, b.x().i:2
Aaron T
  • 1,092
  • 2
  • 10
  • 25
  • `no native way to store a reference to a variable in C#` That's what i want. i'll try Sc4. Great Thanks. – angdroid Oct 09 '18 at 02:13
0

The new keyword creates a new instance of class X

Instead of creating a new object and assigning it to a.x, you should simply modify the internal value of the instance of x

a.x.name = "2";
MrZander
  • 3,031
  • 1
  • 26
  • 50
0

As you did for "X1", just do this again at the end:

b.x = a.x; //a.x = b.x => X2

instead of

a.x = new X();

sean
  • 367
  • 2
  • 12
0

To do what you want you should say:

a = new SomClass();
b = a;

Now, if you set:

a.x = new X();

Now b.x will contain the same object as a.x (because b == a).

Poul Bak
  • 10,450
  • 5
  • 32
  • 57
0

How do I assign reference field

You don't. This is exactly why you should be using Properties not Fields.

I want to point out that b.x has the same address a.x .

Well your code is completely invalid, so it really doesn't make sense:

a.x = new X();    //X1
b.x = a.x;        //a.x = b.x => X1

Where did b come from? How was it initialized? Why can you assign x?

This is probably an XY Problem because what you're doing, you've provided no value why this is important. That being said this should work as you've described, but I've never had to write this code in the last 10 years so I suspect it's a code smell.

public class X1 { }
public class SomeClass
{
  private static X1 _X = new X1();

  public X1 X 
  {
    get 
    {
      return _X;
    }
  }
}

var a = new SomeClass();
var b = new SomeClass();
Assert.That(a.X, Is.EqualTo(b.X)) // true, always

YMMV, this is really a bad pattern (the idea of the implementation).

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • X1 X2 just for distinction. And this code is a simplification. Think of it as a pseudocode. – angdroid Oct 09 '18 at 01:35
  • if var c = new SomeClass(); and want to c.x != a.x then How?? – angdroid Oct 09 '18 at 01:39
  • I just Wanted know How to b.x has Same adress with a.x . Not Static, Not a=b just like ref Keyword. Yes Someone said Using unsafe. but i know unsafe Not recommended. That's why asking This Question. i don't know why everyone giving to me a wild answer. – angdroid Oct 09 '18 at 01:44