foreach 引发的值类型与引用类型思考

简介: 用都知道的一句话概括:“引用类型在堆上,栈上只保存引用;值类型即可存放于栈上也可存放于堆上,值类型变量直接存储值本身”。 class Program { static void Main(string[] args) { var list = new L...

用都知道的一句话概括:“引用类型在堆上,栈上只保存引用;值类型即可存放于栈上也可存放于堆上,值类型变量直接存储值本身”。

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Person>()
        {
            new Person() {Name = "xfh"},
            new Person() {Age = 26}
        };
        foreach (var l in list)
        {
            if (l.Age != 0) continue;
            l.Age = 24;
            Console.WriteLine(l.Age);
        }
    }
}

class Person
{
    public string Name { set; get; }
    public int Age { set; get; }
}

 

若把上述代码中的Person类型由class改为struct则会出现编译错误:
Foreach iteration variable 'l' is immutable.Cannot modify struct member when accessed strucy is not classified as a variable.

对于foreach,MSDN上有句话:
The foreach statement is a wrapper around the enumerator,which only allows reading from,not writing to,the collection.

Person为class时内存分配示意图:

 

 
如上图,list集合中存储的是Person实例的地址,所以代码中的操作并不会使集合发生改变。

Person为struct时内存分配示意图:

 

 

如上图,list集合中存储的是Person实例,所以代码中的操作会使集合发生改变而引发错误。

【延申】数组的内存分配

数组元素可分为引用类型和值类型两种,其内存分配与上图中的list集合类似。

Stackoverflow上讨论数组中存放值类型元素时内存如何分配的几句话:

Object are always allocated on the heap.
The heap only contains objects.
Value types are either allocated on the stack, or part of an object on the heap.
An array is an object.
An array can only contain value types.
An object reference is a value type.

推荐阅读

Arrays, heap and stack and value types

目录
相关文章
|
9月前
|
存储 C# C++
|
7月前
|
C#
C#由Dictionary赋值引发的对引用类型使用的思考
C#由Dictionary赋值引发的对引用类型使用的思考
|
9月前
|
存储 JavaScript 前端开发
JavaScript】基本数据类型与引用数据类型区别(及为什么String、Boolean、Number基本数据类型会有属性和方法?)
JavaScript】基本数据类型与引用数据类型区别(及为什么String、Boolean、Number基本数据类型会有属性和方法?)
70 0
|
存储 开发框架 .NET
C#系列之值类型和引用类型
C#系列之值类型和引用类型
132 0
C#系列之值类型和引用类型
|
存储 数据格式 JSON
第183天:引用类型和值类型
一、内存分配 1、数值型内存分配 1 2 var num1; //这个时候不进行内存分配 3 var num3=9;//分配内存 4 var num4=num3;//会不会分配 5 6 // 这里到底分配还是不分配内存?? 7 // 答案 --分配内存 彼此拥有独立的内存空间,互不影响 8 console.
985 0
|
算法 C#
c#值类型与引用类型区别
值类型对象的两种表示方式:未装箱和已装箱,引用类型总是处于已装箱 值类型从System.ValueType派生。该类型提供了与System.Object相同方法,但System.ValueType重写了Equals方法, 能在两个对象的自断值完全匹配的前提下返回true。
933 0