本帖最后由 az235 于 2011-06-17 09:57:37 编辑

解决方案 »

  1.   

    你每次调用add的时候 都是同一个对象u啊
    只是你把u的UserName改变了
      

  2.   

    是啊,我已经把那个值给改变了,但是添加到了List中,为什么两个值都会是一样呢?
      

  3.   

    倒~~~
    你应该这样:
    UserInfo u1=new UserInfo{UserName="aaa"};
    list.Add(u1);UserInfo u2=new UserInfo{UserName="bbb"};
    list.Add(u2);或者直接使用C# 的集合初始化器:List<UserInfo> list=new List<UserInfo>
    {
      new UserInfo{UserName="aaa"},
      new UserInfo{UserName="bbb"}
    }
      

  4.   

    你自己debug看下list.count就明白了
      

  5.   

    你把任何一个对象加入到List里面,再修改此对象的值,在list里面的那个值也会随之改变,因为他们本来就是一个东西。
    所以你先list.add(u),再u.name="aaa";list里面的那个u的name也变成aaa了。
    如果你懂指针的话,这个很容易理解(c#里面没有指针,我是指思想)。
      

  6.   

    5楼正解,U被修改以后依然是一个实例,存在list里面的自动被修改掉了。创建多个实例吧。
      

  7.   


    深层原因见你楼上13楼。
    用白话说,如果没记错的话,就是你存到list里面的是指向U这个对象的路径,类似指针。当你修改的时候是修改的对象存储空间里面的值,所以当你程序运行的时候,由于你已经在对象的存储空间里面的值已经被修改,所以对应的取的值在你修改之后也发生了变化。PS:N久没看书了,原理大致如此吧,如有错误,请轻喷……
      

  8.   

    还是代码来得实用,先看下汇编的代码
    --- D:\Projects\Test\Test\Program.cs -------------------------------------------
            {
    00000000  push        ebp 
    00000001  mov         ebp,esp 
    00000003  push        edi 
    00000004  push        esi 
    00000005  push        ebx 
    00000006  sub         esp,50h 
    00000009  mov         esi,ecx 
    0000000b  lea         edi,[ebp-38h] 
    0000000e  mov         ecx,0Bh 
    00000013  xor         eax,eax 
    00000015  rep stos    dword ptr es:[edi] 
    00000017  mov         ecx,esi 
    00000019  xor         eax,eax 
    0000001b  mov         dword ptr [ebp-1Ch],eax 
    0000001e  mov         dword ptr [ebp-3Ch],ecx 
    00000021  cmp         dword ptr ds:[049714A4h],0 
    00000028  je          0000002F 
    0000002a  call        76364477 
    0000002f  xor         edx,edx 
    00000031  mov         dword ptr [ebp-44h],edx 
    00000034  xor         edx,edx 
    00000036  mov         dword ptr [ebp-40h],edx 
    00000039  xor         edx,edx 
    0000003b  mov         dword ptr [ebp-48h],edx 
    0000003e  nop 
                List<UserInfo> list = new List<UserInfo>();
    0000003f  mov         ecx,49725E4h 
    00000044  call        FD95FC20 
    00000049  mov         dword ptr [ebp-4Ch],eax 
    0000004c  mov         ecx,dword ptr [ebp-4Ch] 
    0000004f  call        76AA1190 
    00000054  mov         eax,dword ptr [ebp-4Ch] 
    00000057  mov         dword ptr [ebp-40h],eax 
                UserInfo u = new UserInfo();
    0000005a  mov         ecx,4972590h 
    0000005f  call        FD95FC20 
    00000064  mov         dword ptr [ebp-50h],eax 
    00000067  mov         ecx,dword ptr [ebp-50h] 
    0000006a  call        FD97A438 
    0000006f  mov         eax,dword ptr [ebp-50h] 
    00000072  mov         dword ptr [ebp-44h],eax 
                UserInfo[] us = new UserInfo[3];
    00000075  mov         edx,3 
    0000007a  mov         ecx,30A7B3Eh 
    0000007f  call        FD95FD54 
    00000084  mov         dword ptr [ebp-54h],eax 
    00000087  mov         eax,dword ptr [ebp-54h] 
    0000008a  mov         dword ptr [ebp-48h],eax 
                u.UserName = "aaa";
    0000008d  mov         edx,dword ptr ds:[01B72088h] 
    00000093  mov         ecx,dword ptr [ebp-44h] 
    00000096  cmp         dword ptr [ecx],ecx 
    00000098  call        FD97A430 
    0000009d  nop 
                us[0] = u;
    0000009e  push        dword ptr [ebp-44h] 
    000000a1  mov         ecx,dword ptr [ebp-48h] 
    000000a4  xor         edx,edx 
    000000a6  call        76160434 
                list.Add(u);
    000000ab  mov         edx,dword ptr [ebp-44h] 
    000000ae  mov         ecx,dword ptr [ebp-40h] 
    000000b1  cmp         dword ptr [ecx],ecx 
    000000b3  call        76AA1140 
    000000b8  nop 
                u.UserName = "bbb";
    000000b9  mov         edx,dword ptr ds:[01B7208Ch] 
    000000bf  mov         ecx,dword ptr [ebp-44h] 
    000000c2  cmp         dword ptr [ecx],ecx 
    000000c4  call        FD97A430 
    000000c9  nop 
                us[1] = u;
    000000ca  push        dword ptr [ebp-44h] 
    000000cd  mov         ecx,dword ptr [ebp-48h] 
    000000d0  mov         edx,1 
    000000d5  call        76160434 
                list.Add(u);
    000000da  mov         edx,dword ptr [ebp-44h] 
    000000dd  mov         ecx,dword ptr [ebp-40h] 
    000000e0  cmp         dword ptr [ecx],ecx 
    000000e2  call        76AA1140 
    000000e7  nop 
                Console.WriteLine(list[0].UserName);
    000000e8  mov         ecx,dword ptr [ebp-40h] 
    000000eb  xor         edx,edx 
    000000ed  cmp         dword ptr [ecx],ecx 
    000000ef  call        76A347D0 
    000000f4  mov         dword ptr [ebp-58h],eax 
    000000f7  mov         ecx,dword ptr [ebp-58h] 
    000000fa  cmp         dword ptr [ecx],ecx 
    000000fc  call        FD97A428 
    00000101  mov         dword ptr [ebp-5Ch],eax 
    00000104  mov         ecx,dword ptr [ebp-5Ch] 
    00000107  call        76A44CAC 
    0000010c  nop 
                Console.ReadLine();
    0000010d  call        770183B8 
    00000112  nop 
            }
    00000113  nop 
    00000114  lea         esp,[ebp-0Ch] 
    00000117  pop         ebx 
    00000118  pop         esi 
    00000119  pop         edi 
    0000011a  pop         ebp 
    0000011b  ret 
      

  9.   

    再看下List的代码实现方式
     private static readonly T[] _emptyArray = new T[0];
        private const int _defaultCapacity = 4;
        private T[] _items;
        private int _size;
        private int _version;
        [NonSerialized]
        private object _syncRoot;。。 public void Add(T item)
        {
          if (this._size == this._items.Length)
            this.EnsureCapacity(this._size + 1);
          this._items[this._size++] = item;
          ++this._version;
        }
    从这看出List的底层还是数组
      

  10.   

    在来用数组同样的实现下 class Program
        {
            static void Main(string[] args)
            {
                List<UserInfo> list = new List<UserInfo>();
                UserInfo u = new UserInfo();
                UserInfo[] us = new UserInfo[3];
                u.UserName = "aaa";
                us[0] = u;
                list.Add(u);
                u.UserName = "bbb";
                us[1] = u;
                list.Add(u);
                Console.WriteLine(list[0].UserName);
                Console.ReadLine();
            }
        }
        public class UserInfo
        {
            public string UserName { get; set; }
        }在想想数组的原理(C中的)得出结果是 list.add添加的是UserInfo的地址引用,改变UserName的值,修改了UserInfo对象所在的内存地址(因为C#是引用传递啊,这里就是引用传递),所以被修改了
      

  11.   

    List<UserInfo> list=new List<UserInfo>
    实例化一次就够了..
      

  12.   

    list.add添加的是UserInfo的地址引用  这是对的
    改变UserName的值,修改了UserInfo对象所在的内存地址(因为C#是引用传递啊,这里就是引用传递),所以被修改了这是不对的 改变UserName的值,不会改变UserInfo对象所在的内存地址,UserName是UserInfo的一个字段
    ,你改变的UserName的值的时候,UserName的地址不会变化,变化的是它指向的对象,因为它是引用类型。
      

  13.   

    每当遇到这种类似情况,我就怀念Java, 看一下List.Add的源码,什么都清楚了. 
    这就是.net让人不爽的地方
      

  14.   

    List<UserInfo> user=new List<UserInfo>();
    foreach(DataRow dr in dt.Rows){
         UserInfo user=new UserInfo();
         user.UserName=dr["UserName"].ToString();
         list.Add(user);
    }
    return user;跟你的
    List<UserInfo> list=new List<UserInfo>();
    UserInfo u=new UserInfo();
    u.UserName="aa";
    list.Add(u);
    u.UserName="bb";
    list.Add(u)
    return list;
    你自己去比较区别,我看得懂你这是这块没理解透彻
      

  15.   


    开始没懂原理,我看你是没看懂我们在说什么,new 两个对象得到两个不同的地址,值会一样才怪,上面这题是无意中偷懒出现的,所有来弄明白原来,抱着不懂就问的心态,问题一出就要直捣老巢的学习方式。