如何分配参考字段

时间:2018-10-09 00:05:23

标签: c# ref

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.

我要指出b.x具有相同的地址a.x。
如果是C语言,请指出来。
但是在C#中,ref关键字只能使用参数。
b.x如何拥有a.x的地址?

好。添加了信息。

a的实例具有0x0000
b的实例具有0x0100
如果a.x = new X(),则a.x指向X实例:0xF000
然后b.x = a.x然后b.x指向X实例:0xF000不是a.x的地址:0x0000 + sizeof(X)
我想b.x有a.x的Ardress。不是Value的地址

5 个答案:

答案 0 :(得分:1)

不幸的是,没有没有本地方法在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:如果ab需要不同的SomeClass对象,则可以将b的X对象引用更新为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引用与a相同的SomeClass对象。

  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.xb.x是同一个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:如果您希望其他类始终可以轻松访问a的X对象。

新课:

  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

答案 1 :(得分:0)

new关键字创建类X的新实例

您无需修改​​新对象并将其分配给a.x,只需修改x实例的内部值

a.x.name = "2";

答案 2 :(得分:0)

就像您对“ X1”所做的一样,只需在末尾再次执行此操作:

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

代替

a.x = new X();

答案 3 :(得分:0)

要做你想做的事,你应该说:

a = new SomClass();
b = a;

现在,如果您设置了:

a.x = new X();

现在b.x将包含与a.x相同的对象(因为b == a)。

答案 4 :(得分:0)

  

如何分配参考字段

你不知道。这就是为什么您应该使用Properties而不是Fields的原因。

  

我想指出b.x具有相同的地址a.x。

好吧,您的代码完全无效,所以这确实没有意义:

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

b来自哪里?它是如何初始化的?为什么要分配x?

这可能是XY Problem,因为您在做什么,您没有提供任何值。为什么,这很重要。话虽如此,它应该按照您所描述的那样起作用,但是在过去的十年中,我从未必须编写此代码,因此我怀疑它是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,这确实是一个糟糕的模式(实现的想法)。