关于C#数组和List列表对数据进行赋值的问题

XD-1 2015-08-07 11:37:43
下面声明了一个结构体,以及用此结构体声明了一个数组和一个List动态数组,给数组赋值的时候不会报错,但是给List赋值的时候就会出现如下图中的错误,求原因?

...全文
5469 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
瑞卡哥哥 2015-08-07
  • 打赏
  • 举报
回复
数组 在构造时,会调用 数组每个元素的构造,即,数组中的元素已经实例化了。 但是 list 在构造时,只会构造list 内部是没有元素的, 所以你需要先把元素Add进去, 才可以进行操作。
於黾 2015-08-07
  • 打赏
  • 举报
回复
student s=new student (); s.age=10; s.name=""; stuList.Add(s);
於黾 2015-08-07
  • 打赏
  • 举报
回复
既然你知道list是动态的 那么一开始里面是没有元素的 你需要使用add方法来添加元素,不能直接赋值
laymat 2015-08-07
  • 打赏
  • 举报
回复
stuList[0]返回的只是一个值的拷贝,修改也无法影响真实的内存数据,顾禁止了这种方式进行复制,因为他没有意义。 如果非要修改,可以使用临时变量模式:
var d = stuList[0];
d.age = 10;
stuList[0]=d;
zhanwengong 2015-08-07
  • 打赏
  • 举报
回复
对列表List赋值,要先构造一个对象,再用Add方法加入到列表中。 stuList.Add(new student() {age=10, name=""});
XD-1 2015-08-07
  • 打赏
  • 举报
回复
引用 15 楼 ajianchina 的回复:
[quote=引用 11 楼 u013899077 的回复:] [quote=引用 7 楼 ajianchina 的回复:] 前面不能误导人家,这个问题不是因为没有add进去student数据,虽然stuList里面是空的,但这一错误提示原因在于student是值类型,因为值类型默认是按值传递的,因此返回的是栈上的一份临时的、本地的拷贝,由于存在栈上的这个本地副本,即使能对它进行修改,也无法最终反映到结构体本身,因此这是一个毫无何意义的操作,C#编译器就从源头上禁止了这样的操作。
可能是我上面的程序表述有点问题,我知道list该用add添加,所以层主理解到了我要问的意思,还有个不清楚的是为什么利用静态数组进行这种值类型的赋值就可以呢?按我的理解,list和数组应该是一个东西啊,无非是动态和静态的区别?[/quote] 上面我已经说过原因了,正好撸主也有所疑惑,我把重点提出来: student[] stuArray = student[10]; 这里的stuArray[0]是student的直接引用。 List<student> stuList = new List<student>()]; 这里的stuList[0]返回的是一个"副本",是这一student结构体在这一位置的副本,赋值并不改变这一位置student的值,知道了吗?[/quote] 恩恩,谢谢,大概能理解了,静态数组每一个存的都是引用,数组中的每个bianliang就跟C语言的指针变量差不度
引用 15 楼 ajianchina 的回复:
[quote=引用 11 楼 u013899077 的回复:] [quote=引用 7 楼 ajianchina 的回复:] 前面不能误导人家,这个问题不是因为没有add进去student数据,虽然stuList里面是空的,但这一错误提示原因在于student是值类型,因为值类型默认是按值传递的,因此返回的是栈上的一份临时的、本地的拷贝,由于存在栈上的这个本地副本,即使能对它进行修改,也无法最终反映到结构体本身,因此这是一个毫无何意义的操作,C#编译器就从源头上禁止了这样的操作。
可能是我上面的程序表述有点问题,我知道list该用add添加,所以层主理解到了我要问的意思,还有个不清楚的是为什么利用静态数组进行这种值类型的赋值就可以呢?按我的理解,list和数组应该是一个东西啊,无非是动态和静态的区别?[/quote] 上面我已经说过原因了,正好撸主也有所疑惑,我把重点提出来: student[] stuArray = student[10]; 这里的stuArray[0]是student的直接引用。 List<student> stuList = new List<student>()]; 这里的stuList[0]返回的是一个"副本",是这一student结构体在这一位置的副本,赋值并不改变这一位置student的值,知道了吗?[/quote] 恩恩,谢谢,大概理解了
ajianchina 2015-08-07
  • 打赏
  • 举报
回复
引用 11 楼 u013899077 的回复:
[quote=引用 7 楼 ajianchina 的回复:] 前面不能误导人家,这个问题不是因为没有add进去student数据,虽然stuList里面是空的,但这一错误提示原因在于student是值类型,因为值类型默认是按值传递的,因此返回的是栈上的一份临时的、本地的拷贝,由于存在栈上的这个本地副本,即使能对它进行修改,也无法最终反映到结构体本身,因此这是一个毫无何意义的操作,C#编译器就从源头上禁止了这样的操作。
可能是我上面的程序表述有点问题,我知道list该用add添加,所以层主理解到了我要问的意思,还有个不清楚的是为什么利用静态数组进行这种值类型的赋值就可以呢?按我的理解,list和数组应该是一个东西啊,无非是动态和静态的区别?[/quote] 上面我已经说过原因了,正好撸主也有所疑惑,我把重点提出来: student[] stuArray = student[10]; 这里的stuArray[0]是student的直接引用。 List<student> stuList = new List<student>()]; 这里的stuList[0]返回的是一个"副本",是这一student结构体在这一位置的副本,赋值并不改变这一位置student的值,知道了吗?
xuzuning 2015-08-07
  • 打赏
  • 举报
回复
struct 不是对象 所以不能通过对 List<T> 成员赋值的方式赋值(因为传递的不是引用) 而数组的成员是可以直接访问到的,所以可以直接复制 stuList[0].age = 10; 这样写法的下决条件是 stuList[0] 必须是对象
XD-1 2015-08-07
  • 打赏
  • 举报
回复
引用 12 楼 lulianqi 的回复:
C# 索引器的实现 类似于字段属性的实现

   public T this[int i]
    {
        get
        {
            return arr[i];
        }
       set
        {
            arr[i] = value;
        }
  }
相当于方法直接返回了一个数据(由于你student是struct ,所以返回的是数据的拷贝) 另外 你平常可以直接设置属性那些 其实不是把值取出来赋值(只是看起来是这样),实际上是属性实现了set,本质上是调用了数据类型里面的方法改变数据的值。 而你的student没有为age字段定义属性,所以不能赋值(不过由于你student是struct 所以即便修改了实际数据的值也不会改变) 另外楼上很多前辈说操作是无意义的所以被禁止,这点我保留意见。被禁止是因为语法错误,跟操作有没有意义没有关系 提示很清楚了,你没有为这个数据指定一个变量来存储,当然不让你修改/赋值(前面解释了有时候看起来像可以直接修改/赋值的,那其实是属性里的方法完成的) 如果 先定义一个tempVaule变量 来存储数据 ,再改变变量的值,编译器就不会报错了(虽然不能改变数据源的值)
我也知道这个原因,但是为什么上面声明的静态数组就可以直接赋值呢?
lulianqi 2015-08-07
  • 打赏
  • 举报
回复
C# 索引器的实现 类似于字段属性的实现

   public T this[int i]
    {
        get
        {
            return arr[i];
        }
       set
        {
            arr[i] = value;
        }
  }
相当于方法直接返回了一个数据(由于你student是struct ,所以返回的是数据的拷贝) 另外 你平常可以直接设置属性那些 其实不是把值取出来赋值(只是看起来是这样),实际上是属性实现了set,本质上是调用了数据类型里面的方法改变数据的值。 而你的student没有为age字段定义属性,所以不能赋值(不过由于你student是struct 所以即便修改了实际数据的值也不会改变) 另外楼上很多前辈说操作是无意义的所以被禁止,这点我保留意见。被禁止是因为语法错误,跟操作有没有意义没有关系 提示很清楚了,你没有为这个数据指定一个变量来存储,当然不让你修改/赋值(前面解释了有时候看起来像可以直接修改/赋值的,那其实是属性里的方法完成的) 如果 先定义一个tempVaule变量 来存储数据 ,再改变变量的值,编译器就不会报错了(虽然不能改变数据源的值)
XD-1 2015-08-07
  • 打赏
  • 举报
回复
引用 7 楼 ajianchina 的回复:
前面不能误导人家,这个问题不是因为没有add进去student数据,虽然stuList里面是空的,但这一错误提示原因在于student是值类型,因为值类型默认是按值传递的,因此返回的是栈上的一份临时的、本地的拷贝,由于存在栈上的这个本地副本,即使能对它进行修改,也无法最终反映到结构体本身,因此这是一个毫无何意义的操作,C#编译器就从源头上禁止了这样的操作。
可能是我上面的程序表述有点问题,我知道list该用add添加,所以层主理解到了我要问的意思,还有个不清楚的是为什么利用静态数组进行这种值类型的赋值就可以呢?按我的理解,list和数组应该是一个东西啊,无非是动态和静态的区别?
by_封爱 版主 2015-08-07
  • 打赏
  • 举报
回复
不是get;set么...没有也可以吗?
老李家的小二 2015-08-07
  • 打赏
  • 举报
回复
引用 4 楼 Z65443344 的回复:
student s=new student (); s.age=10; s.name=""; stuList.Add(s);
同意。楼主在stuList后面输入一个点(.),看看都有什么属性就好了
於黾 2015-08-07
  • 打赏
  • 举报
回复
引用 7 楼 ajianchina 的回复:
前面不能误导人家,这个问题不是因为没有add进去student数据,虽然stuList里面是空的,但这一错误提示原因在于student是值类型,因为值类型默认是按值传递的,因此返回的是栈上的一份临时的、本地的拷贝,由于存在栈上的这个本地副本,即使能对它进行修改,也无法最终反映到结构体本身,因此这是一个毫无何意义的操作,C#编译器就从源头上禁止了这样的操作。
yes 结构体和实体类不一样
ajianchina 2015-08-07
  • 打赏
  • 举报
回复
前面不能误导人家,这个问题不是因为没有add进去student数据,虽然stuList里面是空的,但这一错误提示原因在于student是值类型,因为值类型默认是按值传递的,因此返回的是栈上的一份临时的、本地的拷贝,由于存在栈上的这个本地副本,即使能对它进行修改,也无法最终反映到结构体本身,因此这是一个毫无何意义的操作,C#编译器就从源头上禁止了这样的操作。
於黾 2015-08-07
  • 打赏
  • 举报
回复
此外,你定义的是个结构体,不是实体类 改为class才可以这样赋值 否则不能这样赋值

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧