C#参考对象
如果使用'Ref'关键字将对象传递给方法,那么不使用Ref关键字传递对象有什么区别 因为两者都产生相同的结果,所以在将控制权传递回调用对象时,对象已被更改 例如:C#参考对象,c#,reference,C#,Reference,如果使用'Ref'关键字将对象传递给方法,那么不使用Ref关键字传递对象有什么区别 因为两者都产生相同的结果,所以在将控制权传递回调用对象时,对象已被更改 例如: class Student { public string Name { get; set; } public int Age { get; set; } } class Program { static Stu
class Student
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
class Program
{
static Student student = new Student();
static void Main( string[] args )
{
student.Age = 30;
student.Name = "StudentA";
Console.WriteLine("Original Student: {0}, Age: {1}", student.Name, student.Age);
SetStudent(ref student);
Console.WriteLine("Student by Ref {0}, Age{1}", student.Name, student.Age);
AnotherStudent(student);
Console.WriteLine("Just Another Student {0}, Age {1}", student.Name, student.Age);
Console.ReadLine();
}
public static void SetStudent( ref Student student )
{
student.Age = 16;
student.Name = "StudentY";
}
public static void AnotherStudent( Student studenta )
{
if (studenta.Equals(student))
{
Console.WriteLine("The same object in memory");
}
studenta.Age = 12;
studenta.Name = "StudentX";
}
}
当student对象被传递给另一个student()时,它会被更改,事件认为它没有通过'Ref'传递
有人能解释一下这里发生了什么吗
编辑
那么,在函数中C++中传递指向一个对象的指针有什么不同?p>
Tony尝试重新指定学生对象,而不是设置其属性
public static void SetStudent( ref Student student )
{
student = new Student();
student.Age = 16;
student.Name = "StudentY";
}
public static void AnotherStudent( Student studenta )
{
studenta = new Student();
studenta.Age = 12;
studenta.Name = "StudentX";
}
不要认为
ref
是“通过引用传递”,因为所有引用类型都是通过引用传递的。将其视为“可以重新分配对此对象的引用”当您使用ref
关键字将对象传递给方法时,被调用的方法可以更新引用本身,而不仅仅是对象。这意味着在以下代码段中:
object a = new object();
SomeMethod(ref a);
…
a
可能是调用后的另一个对象实例,而不是调用前的对象实例。如果传递的对象没有ref
关键字,则被调用的方法可以更新传递对象的属性和成员,但不能用另一个实例替换对象本身。执行此操作时,真正的区别将变得明显
public static void SetStudent( ref Student student )
{
student = new Student { Age = 69, Name="Botox" };
}
...
var a = new Student()
var b = a;
SetStudent(ref a);
object.ReferenceEquals(a, b) // Should be false
这些例子说明了不同之处
methodA(ref object a)
{
a = new object();
}
methodB(object a)
{
a = new object();
}
object c = new object();
methodA(ref c); //now c points to an entire new object
methodB(c); // does not change the value of c
通过引用传递允许方法更改传递给方法的参数的值-因此对于引用类型,允许方法更改变量的值以引用其他对象。下面是一个例子:
using System;
using System.Text;
class Test
{
static void PassByValue(StringBuilder x)
{
x.Append(" - Modified object in method");
x = new StringBuilder("New StringBuilder object");
}
static void PassByReference(ref StringBuilder x)
{
x.Append(" - Modified object in method");
x = new StringBuilder("New StringBuilder object");
}
static void Main()
{
StringBuilder builder = new StringBuilder("Original");
PassByValue(builder);
Console.WriteLine(builder);
builder = new StringBuilder("Original");
PassByReference(ref builder);
Console.WriteLine(builder);
}
}
在这两种情况下,原始的StringBuilder
都会修改其内容,然后为参数指定一个新值。在“传递值”的情况下,这不会更改Main
中builder
变量的值。在“通过引用传递”的情况下,builder
的值引用新的StringBuilder
,因此结果为:
Original - Modified object in method
New StringBuilder object
在您的例子中,无论是否使用ref
,您都看不到任何差异,因为您没有更改参数本身的值—只更改它所引用的对象中的数据
有关更多信息,请参阅my。尝试将两种学员方法更改为:
public static void SetStudent( ref Student student )
{
student = new Student();
student.Age = 16;
student.Name = "StudentY";
}
public static void AnotherStudent( Student studenta )
{
studenta = new Student();
studenta.Age = 12;
studenta.Name = "StudentX";
}
对
SetStudent
的调用现在将更改静态student变量以引用新实例,因为它作为ref
传递。调用另一个学生不会更改引用。我将讨论限制在引用类型(类的所有内容,这意味着我不是在谈论结构或内置值类型)。有关完整和更详细的讨论,请参见
如果您传递的引用类型没有ref关键字,您就是通过值传递引用,这意味着将生成引用的副本。此时,您可以修改ref指向的对象,但如果您在另一个对象中交换,则可以修改该对象(指定给您在创建的其他对象中传递的ref对象)当函数返回位于传入函数外部的原始对象时,该对象仍指向相同的旧引用
如果使用ref关键字传递引用类型,则可以将传递的对象与其他对象交换,因为引用不仅仅是被复制的-变量本身是以实体形式传递给函数来执行任何操作,您甚至可以将它指向内存中的其他地址(实例化另一个对象并将其分配给ref参数)
正如您所指出的,在这两种情况下,您都可以修改对象。C++中基本上通过引用对应于在C++中传递简单指针,而不带REF关键字的传递对应于在C++中传递常数指针(可以进行更改,但不能使其指向SMT其他)。您可以通过按引用传递引用类型varaible来组合它们
通过引用传递变量仅仅意味着该方法可以更改变量。该方法可以访问变量本身,而不仅仅是值的副本。变量不必是引用类型才能通过引用传递。使用引用传递的少数情况实际上主要是值类型 当通过引用传递引用类型时,这意味着该方法可以访问引用变量,而不仅仅是对象引用的副本。该方法不仅可以访问对象,还可以用对不同对象的引用替换变量中的引用
传递引用很少需要,当然也不是因为您将引用类型作为参数传递而需要做的事情。
和在C++中传递指向一个对象的区别是什么?不能与矮马竞争(我把他的文章作为参考)。但是我在我的回答中有一个简单的C++比较。如果我使用REF正确的话,可以改变调用方法中的实例,否则ON使用与调用方法之前相同的实例??@托尼:该方法总是可以创建一个新的实例并将其赋值给参数。但是,除非调用是使用ref
关键字进行的,否则调用代码不会看到这个新实例。凡人只能向小马托尼低头;-)啊,谢谢你澄清了这一点。我猜我的回答有点短视。我想我基本上同意你的观点,但是“在肉体和骨骼中”在我看来不是特别清楚-我认为在这种情况下谈论参数(通常是一个变量)而不是引用更清楚。不,所有引用类型都不是通过引用传递的。你把“路过”错了