首页新闻找找看学习计划

无法为结构体集合中某个元素的成员赋值的问题

0
[待解决问题]
    struct UserInfo
    {
        public string Name;
        public int Age;
        public bool Gender;
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<UserInfo> list = new List<UserInfo>() { 
                new UserInfo { Name = "阿三", Age = 20, Gender = true  },
                new UserInfo { Name = "阿四", Age = 30, Gender = false  },
                new UserInfo { Name = "阿五", Age = 40, Gender = true  }
            };

            UserInfo[] uArr = list.ToArray();
            uArr[0].Name = "xxx";
            list[0].Name = "yyyy";// 上一句数组索引没报错,这句集合索引为什么报错了


            Console.ReadLine();
        }
    }
横刀含笑的主页 横刀含笑 | 菜鸟二级 | 园豆:202
提问于:2015-03-31 21:06
< >
分享
所有回答(2)
0

1、struct改为class没这个问题

2、var item = list[0];item.Name="yyyy";也不会有问题。

3、List是一个集合,Array是数组。数组和集合的处理方式是不同的。

4、如果是class,list[0].Name="yyyy";等价于var item = list[0];item.Name="yyyy";

而是struct的时候,struct的复制特性,其中的item本身不存在,导致赋值报告这个错误。

519740105 | 园豆:5810 (大侠五级) | 2015-03-31 21:36
0

这个涉及到值类型与引用类型的概念

struct是值类型,list是引用类型:网上有个说法就是值类型就是现金,引用类型就是存折,数组你也可以看作值类型

那么uArr[0]就是现金,你可以直接使用

那么List[0]是存折,你不能直接用,要var item = list[0],先取出来,然后就可以用了

那么问题来了,改为class为什么又可以呢?我们来看看list[int]的源码

public List(int capacity) {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();

if (capacity == 0)
_items = _emptyArray;
else
_items = new T[capacity];
}

所以返回的是new T[capacity],实例化之后的,所以list[0]这个时候是可以直接复制的

茂茂 | 园豆:2860 (老鸟四级) | 2015-04-01 11:38

可能你要问我struct的时候返回的也new T[capacity]啊。这个设计到装箱概念,值类型放到list里面是经过装箱动作,装箱实际上是拷贝一个副本,具体的可以了解装箱拆箱概念。

支持(0) 反对(0) 茂茂 | 园豆:2860 (老鸟四级) | 2015-04-01 11:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册