我有一个ClassA实例作为引用传递给ClassB的构造函数。现在,ClassB的实例是否始终可以访问传递的ClassA实例的最新更新版本?
public class ClassA {
private int variableA = 0;
public ClassA() { }
public void Change(int newValue) {
variableA = newValue;
}
}
public class ClassB {
public ClassA classA;
public ClassB(ref ClassA refClassA) {
classA = refClassA;
}
public void Print() {
Console.WriteLine(classA.variableA);
}
}
static void Main() {
ClassA classA = new ClassA();
ClassB classB = new ClassB(ref classA);
classB.Print(); // 0
classA.Change(50);
classB.Print(); // 50?
}
我已经阅读了我在互联网上找到的内容,但我发现的唯一用途是更新引用的值,例如dotnetperls http://www.dotnetperls.com/ref。
答案 0 :(得分:1)
这不是ref
的用途,没有它就可以实现相同的行为。
答案 1 :(得分:1)
这里不需要ref关键字。即使没有它,ClassB也会持有对ClassA的引用,而不是其值的副本。
请注意,由于variableA是私有的,因此您的代码将无效,因此ClassB无法在其Print
方法中访问它。除此之外,输出将如您在示例中所预期的那样
答案 2 :(得分:1)
ref与持久性无关。它只表示您可以更改原始变量的值。如果你调用一个没有ref的方法,该方法可以根据需要分配该变量,并且调用者的变量不会改变。使用ref,来电者也会指向另一个地方。
简单示例:
void Call(int x)
{
x = 2;
}
void CallRef(ref int x)
{
x = 10;
}
int a=0;
Call(a); // a is still 0
CallRef(ref a); // a is 10
答案 3 :(得分:1)
是的。但它甚至不需要,因为对象总是指针,ref
关键字用于将非对象的指针传递给函数(例如:int,float,structs等)。
答案 4 :(得分:0)
是的,它有参考。这意味着它不保存ClassA元素的值,而只保存它在内存中(堆上)的地址。
因此,请确保不要重新实例化classA:
classA.change(50)
可以使用,但classA = new ClassA()
不会。
另外,请注意引用类型(例如类)不需要ref
关键字,它们会以这种方式自动处理。
答案 5 :(得分:0)
如果您想要访问ClassA
的最后一个实例,可以用这样的类包装变量:
public class Ref<T>
{
readonly Func<T> getter;
readonly Action<T> setter;
public T Value
{
get
{
return getter();
}
set
{
setter(value);
}
}
public Ref(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
}
然后像这样修改你的ClassB
:
public class ClassB
{
readonly Ref<ClassA> refClassA;
public ClassA ClassA
{
get
{
return refClassA.Value;
}
}
public ClassB(Ref<ClassA> refClassA)
{
this.refClassA = refClassA;
}
public void Print()
{
Console.WriteLine(ClassA.VariableA);
}
}
然后你可以测试并看看你是否有所需的行为:
var a = new ClassA(1);
var b = new ClassB2(new Ref<ClassA>(() => a, x => a = x));
b.Print(); // output 1
var c = a; // backup old reference
a = new ClassA(2);
b.Print(); // output 2
// b stores old instance of a?
Console.WriteLine(object.ReferenceEquals(b.ClassA, c)); // output false
// a stores new instance of a?
Console.WriteLine(object.ReferenceEquals(b.ClassA, a)); // output true
我认为你会这样做,请记住这是一个草稿,所以你必须做很多工作。
修改强>
我从Eric Lippert的博客中偷了Ref<T>
课,最后我发现了SO question他发布的帖子。