目录

一、须知概念

1.值类型:

2.引用类型:

二、ref

1.传值参数→值参数

2.传值参数→引用类型,并且创建新对象

3.传值参数→引用类型,只操作对象,不创建新对象

4.引用参数→值参数

5.引用参数→引用类型,并且创建新对象

6.引用参数→引用类型,不创建新对象只改变对象值

一、须知概念

1.值类型:

结构体类型、枚举类型

值类型在内存中存在栈中,根据变量的类型不同,在栈中分配响应的字节。

2.引用类型:

类、接口、委托

引用类型在内存中的存储分为两个部分。string x=new string();  创建一个对象首先会在内存栈中分配4个字节用来存储该对象在堆中存放的地址,然后根据对象成员类型在堆中分配对应的空间存储对象,获得一个堆中内存的地址存放在栈中分配的四个字节中。

二、ref

1.传值参数→值参数

图片解释:(来自刘铁猛C#入门视频)

 代码示例:

static void Main(string[] args)

{

Student stu=new Student();

int x=100;

stu.Add(x);

Console.WriteLine(x);//打印 100

}

class Student

{

public void Add(int x)

{

x = x + 1;

Console.WriteLine(x);//打印 101

}

}

打印预览:

从代码示例中可以看到,当我们使用传值参数时在方法中对值类型 形参x 增加时,并不会影响到实参x,因为在传递传值参数→值类型的时候是在内存中开辟一个新的地址把实参拷贝过去,当我们对形参进行修改其实是对拷贝的数据修改,不会影响到实参。

2.传值参数→引用类型,并且创建新对象

图片解释:(来自刘铁猛C#入门视频)

  代码示例:

static void Main(string[] args)

{

Student stu = new Student() { Name = "张三" };

//打印Name:李四,Hash:58225482

MetHodTest(stu);

//打印Name:张三,Hash:54267293

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

static void MetHodTest(Student stu)

{

stu = new Student() { Name = "李四" };

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

class Student

{

public string Name { get; set; }

}

打印预览:

 

从代码示例中可以看到, 当我们使用传值参数时在方法中对引用类型 形参stu 创建一个新对象时并不会影响 实参stu 的值,因为当形参是引用类型的时候,我们把实参传递过去的时候在内存中其实是开辟一个新的空间,把实参对象在堆中的内存地址拷贝过去了,然后往形参上创建对象,创建的对象内存地址是保存在拷贝的栈中内存空间,所以不会影响实参。       

3.传值参数→引用类型,只操作对象,不创建新对象

图片解释:(来自刘铁猛C#入门视频)

  代码示例:

static void Main(string[] args)

{

Student stu = new Student() { Name = "张三" };

//打印Name:李四,Hash:58225482

MetHodTest(stu);

//打印Name:李四,Hash:58225482

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

static void MetHodTest(Student stu)

{

stu.Name = "李四";

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

class Student

{

public string Name { get; set; }

}

打印预览:

 

从代码示例中可以看到, 当我们使用传值参数时在方法中对引用类型 形参stu 修改时会影响 实参stu 的值,因为当形参是引用类型的时候,我们把实参传递过去的时候在内存中其实是开辟一个新的空间,把实参对象在堆中的内存地址拷贝过去了,因为两个地址中存的是对象在堆中存的相同地址,所以当修改 形参stu 的值会影响 实参stu 的值。

4.引用参数→值参数

图片解释:(来自刘铁猛C#入门视频)

 代码示例:

static void Main(string[] args)

{

Student stu=new Student();

int x=100;

stu.Add(ref x);

Console.WriteLine(x);//打印 101

}

class Student

{

public void Add(ref int x)

{

x = x + 1;

Console.WriteLine(x);//打印 101

}

}

打印预览:

 

 从代码示例中可以看到,当我们使用引用参数时在方法中对值类型 形参x 增加时,会影响到实参x,因为在传递引用参数→值类型的时候实参和形参指向内存中同一个地址,当我们对形参进行修改实参也会跟着改变。

5.引用参数→引用类型,并且创建新对象

图片解释:(来自刘铁猛C#入门视频)

  代码示例:

static void Main(string[] args)

{

Student stu = new Student() { Name = "张三" };

//打印Name:李四,Hash:58225482

MetHodTest(ref stu);

//打印Name:李四,Hash:58225482

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

static void MetHodTest(ref Student stu)

{

stu = new Student() { Name = "李四" };

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

class Student

{

public string Name { get; set; }

}

打印预览:

 

从代码示例中可以看到, 当我们使用引用参数时在方法中对引用类型 形参stu 创建一个新对象时会影响 实参stu 的值,因为当形参是引用类型的时候,我们把实参传递过去的时候是把实参在内存中的地址传递给形参了,然后往形参上创建对象,创建的对象内存地址是保存在实参栈中内存空间,所以会影响实参。    

6.引用参数→引用类型,不创建新对象只改变对象值

图片解释:(来自刘铁猛C#入门视频)

   代码示例:

static void Main(string[] args)

{

Student stu = new Student() { Name = "张三" };

//打印Name:李四,Hash:58225482

MetHodTest(ref stu);

//打印Name:李四,Hash:58225482

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

static void MetHodTest(ref Student stu)

{

stu.Name = "李四";

Console.WriteLine($"Name:{stu.Name},Hash:{stu.GetHashCode()}");

}

class Student

{

public string Name { get; set; }

}

打印预览:

 

 从代码示例中可以看到, 当我们使用引用参数时在方法中对引用类型 形参stu 修改对象值会影响 实参stu 的值,因为当形参是引用类型的时候,我们把实参传递过去的时候是把实参在内存中的地址传递给形参了,然后修改形参的对象,其实就是在修改实参上存的对象,所以会影响实参。 

参考阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: