Как мне назначить справочное поле - PullRequest
0 голосов
/ 09 октября 2018
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.

Хочу отметить, что bx имеет тот же адрес ax.
Если это язык C, просто укажите на него.
, но в C # ключевое слово ref может использовать только параметр.
Как bx может иметь адрес топора?

ок.добавлена ​​информация.

экземпляр a имеет 0x0000
экземпляр b имеет 0x0100
, если a.x = new X(), то X указывает на экземпляр X: 0xF000
Затем b.x = a.x затем bx указал X экземпляр: 0xF000Не адрес топора: 0x0000 + sizeof (X)
Я хочу, чтобы у bx был Ardress топора.Адрес не по стоимости

Ответы [ 5 ]

0 голосов
/ 09 октября 2018

К сожалению, нет собственного способа сохранить ссылку на переменную в C # .К счастью, есть много способов, чтобы b ссылка на объект X оставалась синхронизированной с a ссылкой на объект X.

Во-первых, классы:

  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;
    }
  }

Сценарий1: Если вам нужно сослаться на новый объект X.

Вариант 1: Если a и b должны быть разными объектами SomeClass, вы можете просто обновить ссылку на X * объекта b на a Ссылка на объект X.

  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

Вариант 2: Если b не должен отличаться от a, пусть b ссылается на тот же объект SomeClass, что и a.

  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

Сценарий 2: Если вам нужно только изменить внутреннее значение объекта X.

Поскольку a.x - это тот же объект X, что и b.x, вы можете изменитьэтот объект, используя любую ссылку, и просмотрите это изменение, используя другую ссылку.

  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

Сценарий 3: Если вы хотите, чтобы другой класс всегда имел легкий доступ к X-объекту a.

Новый класс:

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

Использование нового класса:

  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

Сценарий 4: Если вы хотите локальныйпсевдоним 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

Сценарий 5: Если вам нужно использовать один и тот же класс и иметь b.x, всегда ссылаться на тот же объект, что и a.x.

Вы можете использоватьFunc<X> член вашего класса, действующий аналогично ссылке на переменную.Это работает , но я не обязательно рекомендую делать это , потому что это не интуитивно понятно и может привести к путанице.

Класс:

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

Использование класса:

  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
0 голосов
/ 09 октября 2018

Как мне назначить справочное поле

Вы не делаете.Именно поэтому вы должны использовать Properties, а не Fields.

Я хочу отметить, что bx имеет тот же адрес ax.

Хорошо, ваш кодявляется полностью недействительным, поэтому в действительности это не имеет смысла:

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

Откуда взялся b?Как это было инициализировано?Почему вы можете назначить x?

Это, вероятно, XY Проблема , потому что в том, что вы делаете, вы не указали значение , почему это важно.Тем не менее, это должно работать так, как вы описали, но мне никогда не приходилось писать этот код за последние 10 лет, поэтому я подозреваю, что это запах кода .

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, это действительно плохая схема (идея реализации).

0 голосов
/ 09 октября 2018

Как вы сделали для «X1», просто сделайте это снова в конце:

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

вместо

a.x = new X();

0 голосов
/ 09 октября 2018

Чтобы сделать то, что вы хотите, вы должны сказать:

a = new SomClass();
b = a;

Теперь, если вы установите:

a.x = new X();

Теперь bx будет содержать тот же объект, что и топор (потому что b ==а).

0 голосов
/ 09 октября 2018

Ключевое слово new создает новый экземпляр класса X

Вместо создания нового объекта и присвоения ему a.x, вы должны просто изменить внутреннее значение экземпляра x

a.x.name = "2";
...