值类型和引用类型

时间:2010-12-08 15:35:21

标签: c#

我在以下代码段中总结了我的问题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication13
{
    public class Student
    {
        public int Marks { get; set; }
        public Student(int marks)
        {
            this.Marks = marks;

        }
        public void AssignMarks(Student st)
        {
            st = null;
        }
        public void AssignMarks(ref Student st)
        {
            st = null;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Student st = new Student(50);
            st.AssignMarks(st);
            Console.WriteLine(st.Marks);
            Student st1 = new Student(50);
            st.AssignMarks(ref st1); // NullReferenceException
            Console.WriteLine(st1.Marks);
        }
    }
}

为什么我在标有**

的行上收到NullReferenceException异常

4 个答案:

答案 0 :(得分:5)

你实际上是在WriteLine电话上获得了例外。(我试过了)

由于st1已通过ref,您传递的变量将变为null

ref参数是对变量的引用,而不是对对象的引用。
因此,如果方法将其ref参数更改为指向其他对象,则将更改其引用的变量。

答案 1 :(得分:1)

你确定你没有在下面一行NullReferenceException(正如我所看到的那样)吗?

这是由AssignMarks(ref Student st)正文中的引用st1设置为null引起的。

答案 2 :(得分:1)

您在下一行(Console.WriteLine(st1.Marks);)上收到NullReferenceException,因为执行AssignMarks(ref Student st1)后st1为空

答案 3 :(得分:1)

您应该阅读有关ValueType / Reference Type和Stack / Heap的信息。

这里,Student是一个引用类型,因此您的对象存储在Heap中。 指向此对象的指针位于Stack(因为它是一个变量)。

“方法 - 1”

当您在第一个方法(没有引用)中传递对象时,您将发送指向Heap中某个地址的指针(同样,因为Student是引用类型)。此指针被“复制”到参数,并且仅对方法是本地的。 现在,该方法可以访问该内存位置并“更改”存储在该地址中的值。

如下,

public void AssignMarks(Student st)
        {
            st.Marks=100;
        }

在这种情况下,Program.Main方法中的WriteLine将pring 100 !!!

回到你的第一种方法。指针在方法的参数中“复制”。 通过执行'st = null',此本地副本指向堆中的“新”内存位置,并且原始内存位置保持原样。 因此,当呼叫返回时。你的对象保持不变。

“方法 - 2”

另一方面,当您将此参数作为“ref”传递时,它实际上是发送指向原始变量的指针(对于ValyeType和ReferenceType,行为保持不变)。 在这种情况下,该方法可以访问变量本身的内存位置(而不是它所指向的值)。因此,如果方法更改了此参数中的任何内容,则它将在调用方法中反映为原样。 一定是吧?从各方面来说,它是从不同的地方和不同的变量访问的相同内存位置。

由于您已明确为对象指定了“null”。它抛出Null Reference异常。

希望这会有所帮助。