Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#参考对象_C#_Reference - Fatal编程技术网

C#参考对象

C#参考对象,c#,reference,C#,Reference,如果使用'Ref'关键字将对象传递给方法,那么不使用Ref关键字传递对象有什么区别 因为两者都产生相同的结果,所以在将控制权传递回调用对象时,对象已被更改 例如: class Student { public string Name { get; set; } public int Age { get; set; } } class Program { static Stu

如果使用'Ref'关键字将对象传递给方法,那么不使用Ref关键字传递对象有什么区别

因为两者都产生相同的结果,所以在将控制权传递回调用对象时,对象已被更改

例如:

 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
关键字进行的,否则调用代码不会看到这个新实例。凡人只能向小马托尼低头;-)啊,谢谢你澄清了这一点。我猜我的回答有点短视。我想我基本上同意你的观点,但是“在肉体和骨骼中”在我看来不是特别清楚-我认为在这种情况下谈论参数(通常是一个变量)而不是引用更清楚。不,所有引用类型都不是通过引用传递的。你把“路过”错了