通过引用传递变量
Passing variables by reference
如果我有这个class:
public class Foo
{
Boo a;
public Foo (ref Boo b)
{
a=b;
}
}
是 a
将成为对 b
的引用,还是 a 将复制 ref b
指向的值?
如果它复制值,我如何使 a
引用 b
和 b
引用参数引用?(像 Java 那样)
Is a
going to be a reference to b
, or a
is going to copy the value which ref b
points to ?
这取决于:
如果Boo
是引用类型,如下图,a
调用后会指向同一个实例
public class Boo
{
public int Number { get; set; }
}
如果 Boo
是值类型,如下所示,a
将是 ref b
指向的内容的成员副本。
public struct Boo
{
public int Number { get; set; }
}
请参考以下例子:
public class Foo
{
public string Name { get; set; }
}
public class Bar
{
public Foo MyFoo { get; set; }
public Bar(Foo paramFoo)
{
this.MyFoo = paramFoo;
}
}
这个序列:
Foo f = new Foo();
f.Name = "First Foo";
System.Diagnostics.Debug.WriteLine(f.Name);
Bar b = new Bar(f);
System.Diagnostics.Debug.WriteLine(b.MyFoo.Name);
b.MyFoo.Name = "Renaming Bar Name";
System.Diagnostics.Debug.WriteLine(f.Name);
System.Diagnostics.Debug.WriteLine(b.MyFoo.Name);
输出将是:
First Foo
First Foo
Renaming Bar Name
Renaming Bar Name
在这种情况下,我们将 f
引用传递给 Bar
ctor,因此 f
和 MyFoo
都指向相同的内存地址,但它们是不同的变量。这意味着,如果我们执行以下操作
b.MyFoo = new Foo();
b.MyFoo.Name = "Yet another foo";
System.Diagnostics.Debug.WriteLine(f.Name);
System.Diagnostics.Debug.WriteLine(b.MyFoo.Name);
输出将是
Renaming Bar Name
Yet another foo
要更改此行为,您应该使用 ref
关键字,以便将指针发送到该变量。
正常传递引用类型和使用ref关键字肯定是有区别的。
下面的代码应该有解释,请仔细阅读评论:
class Class6
{
static void Main(string[] args)
{
Boo b = new Boo { BooMember = 5 };
Console.WriteLine(b.BooMember);
Foo f = new Foo(b);
// b is unaffected by the method code which is making new object
Console.WriteLine(b.BooMember);
Foo g = new Foo(ref b);
// b started pointing to new memory location (changed in the method code)
Console.WriteLine(b.BooMember);
}
}
public class Foo
{
Boo a;
public Foo(Boo b)
{
a = b;
// b is just a reference, and actually is a copy of reference passed,
// so making it point to new object, dosn't affect actual object , check in calling code
b = new Boo();
}
public Foo(ref Boo b)
{
a = b;
// b is just a reference, but actual reference itself is copied,
// so making it point to new object would make the calling code object reference to point
// to new object. check in the calling code.
b = new Boo();
}
}
public class Boo
{
public int BooMember { get; set; }
}
如果我有这个class:
public class Foo
{
Boo a;
public Foo (ref Boo b)
{
a=b;
}
}
是 a
将成为对 b
的引用,还是 a 将复制 ref b
指向的值?
如果它复制值,我如何使 a
引用 b
和 b
引用参数引用?(像 Java 那样)
Is
a
going to be a reference tob
, ora
is going to copy the value whichref b
points to ?
这取决于:
如果Boo
是引用类型,如下图,a
调用后会指向同一个实例
public class Boo
{
public int Number { get; set; }
}
如果 Boo
是值类型,如下所示,a
将是 ref b
指向的内容的成员副本。
public struct Boo
{
public int Number { get; set; }
}
请参考以下例子:
public class Foo
{
public string Name { get; set; }
}
public class Bar
{
public Foo MyFoo { get; set; }
public Bar(Foo paramFoo)
{
this.MyFoo = paramFoo;
}
}
这个序列:
Foo f = new Foo();
f.Name = "First Foo";
System.Diagnostics.Debug.WriteLine(f.Name);
Bar b = new Bar(f);
System.Diagnostics.Debug.WriteLine(b.MyFoo.Name);
b.MyFoo.Name = "Renaming Bar Name";
System.Diagnostics.Debug.WriteLine(f.Name);
System.Diagnostics.Debug.WriteLine(b.MyFoo.Name);
输出将是:
First Foo
First Foo
Renaming Bar Name
Renaming Bar Name
在这种情况下,我们将 f
引用传递给 Bar
ctor,因此 f
和 MyFoo
都指向相同的内存地址,但它们是不同的变量。这意味着,如果我们执行以下操作
b.MyFoo = new Foo();
b.MyFoo.Name = "Yet another foo";
System.Diagnostics.Debug.WriteLine(f.Name);
System.Diagnostics.Debug.WriteLine(b.MyFoo.Name);
输出将是
Renaming Bar Name
Yet another foo
要更改此行为,您应该使用 ref
关键字,以便将指针发送到该变量。
正常传递引用类型和使用ref关键字肯定是有区别的。
下面的代码应该有解释,请仔细阅读评论:
class Class6
{
static void Main(string[] args)
{
Boo b = new Boo { BooMember = 5 };
Console.WriteLine(b.BooMember);
Foo f = new Foo(b);
// b is unaffected by the method code which is making new object
Console.WriteLine(b.BooMember);
Foo g = new Foo(ref b);
// b started pointing to new memory location (changed in the method code)
Console.WriteLine(b.BooMember);
}
}
public class Foo
{
Boo a;
public Foo(Boo b)
{
a = b;
// b is just a reference, and actually is a copy of reference passed,
// so making it point to new object, dosn't affect actual object , check in calling code
b = new Boo();
}
public Foo(ref Boo b)
{
a = b;
// b is just a reference, but actual reference itself is copied,
// so making it point to new object would make the calling code object reference to point
// to new object. check in the calling code.
b = new Boo();
}
}
public class Boo
{
public int BooMember { get; set; }
}