如何分配参考字段
How do I assign reference field
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
if a.x = new X()
then a.x 指向 X 实例:0xF000
Then b.x = a.x
then b.x pointed X instance : 0xF000 Not a.x's adress:0x0000 + sizeof(X)
我想 b.x 有 a.x 的地址。不是值的地址
new
关键字创建了 class X
的新实例
与其创建新对象并将其分配给 a.x
,不如简单地修改 x
实例的内部值
a.x.name = "2";
正如您在 "X1" 中所做的那样,只需在最后再执行一次即可:
b.x = a.x; //a.x = b.x => X2
而不是
a.x = new X();
做你想做的你应该说:
a = new SomClass();
b = a;
现在,如果您设置:
a.x = new X();
现在 b.x 将包含与 a.x 相同的对象(因为 b == a)。
How do I assign reference field
你不知道。这正是您应该使用 Properties
而不是 Fields
.
的原因
I want to point out that b.x has the same address a.x .
嗯,你的代码完全无效,所以它真的没有意义:
a.x = new X(); //X1
b.x = a.x; //a.x = b.x => X1
b
从哪里来的?它是如何初始化的?为什么可以赋值x?
这可能是一个 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,这真是一个糟糕的模式(实现的想法)。
遗憾的是,在 C# 中没有本地方法来存储对变量的引用。幸运的是,有很多方法可以使 b
的 X 对象引用与 a
的 X 对象引用保持同步。
首先,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;
}
}
场景一:如果需要引用一个新的X对象。
选项 1:如果 a
和 b
需要不同的 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
场景二:如果只需要修改X对象的一个内部值。
由于 a.x
与 b.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:如果您希望不同的 class 始终可以轻松访问 a
的 X 对象。
新 class:
public class SomeClass2
{
private SomeClass someClass;
public X x { get { return someClass.x; } }
public SomeClass2(SomeClass sc)
{
someClass = sc;
}
}
使用新的 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
场景 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:如果您需要使用相同的 class 并且让 b.x
始终引用与 a.x
相同的对象。
您可以使用 class 的 Func<X>
成员来类似于变量引用。这行得通 但我不一定推荐这样做 因为它不直观并且会引起混淆。
class:
public class SomeClass3
{
public Func<X> x;
}
使用 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
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
if a.x = new X()
then a.x 指向 X 实例:0xF000
Then b.x = a.x
then b.x pointed X instance : 0xF000 Not a.x's adress:0x0000 + sizeof(X)
我想 b.x 有 a.x 的地址。不是值的地址
new
关键字创建了 class X
与其创建新对象并将其分配给 a.x
,不如简单地修改 x
a.x.name = "2";
正如您在 "X1" 中所做的那样,只需在最后再执行一次即可:
b.x = a.x; //a.x = b.x => X2
而不是
a.x = new X();
做你想做的你应该说:
a = new SomClass();
b = a;
现在,如果您设置:
a.x = new X();
现在 b.x 将包含与 a.x 相同的对象(因为 b == a)。
How do I assign reference field
你不知道。这正是您应该使用 Properties
而不是 Fields
.
I want to point out that b.x has the same address a.x .
嗯,你的代码完全无效,所以它真的没有意义:
a.x = new X(); //X1
b.x = a.x; //a.x = b.x => X1
b
从哪里来的?它是如何初始化的?为什么可以赋值x?
这可能是一个 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,这真是一个糟糕的模式(实现的想法)。
遗憾的是,在 C# 中没有本地方法来存储对变量的引用。幸运的是,有很多方法可以使 b
的 X 对象引用与 a
的 X 对象引用保持同步。
首先,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;
}
}
场景一:如果需要引用一个新的X对象。
选项 1:如果 a
和 b
需要不同的 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
场景二:如果只需要修改X对象的一个内部值。
由于 a.x
与 b.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:如果您希望不同的 class 始终可以轻松访问 a
的 X 对象。
新 class:
public class SomeClass2
{
private SomeClass someClass;
public X x { get { return someClass.x; } }
public SomeClass2(SomeClass sc)
{
someClass = sc;
}
}
使用新的 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
场景 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:如果您需要使用相同的 class 并且让 b.x
始终引用与 a.x
相同的对象。
您可以使用 class 的 Func<X>
成员来类似于变量引用。这行得通 但我不一定推荐这样做 因为它不直观并且会引起混淆。
class:
public class SomeClass3
{
public Func<X> x;
}
使用 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