如下代码:
方法A、方法B.
2种创建对象的方法,他们的性能区别很大吗?
方法A 是比较靠谱的吧?        /// <summary>
        /// 查询所有菜品 【方法A】
        /// </summary>
        /// <returns>返回[IList]</returns>
        public static IList<FoodInfo> GetAllFood()
        {
            IList<FoodInfo> listFood = new List<FoodInfo>(); ;
            FoodInfo food= null;//1.创建
            string sql = "select FID,F_Pic,F_Desc from FoodInfo order by F_SendTime desc,FID desc";
            OleDbDataReader dr=SqlHelper.GetReader(sql)
            
                while (dr.Read())
                {
                    food= new FoodInfo();//2.实例化
                    food.FID = Convert.ToInt32(dr[0]);
                    food.F_Pic = dr[1].ToString();
                    food.F_Desc = dr[2].ToString();
                    listFood.Add(food);
                }
            
            return listCus;
        }对比下面的        /// <summary>
        /// 查询所有菜品 【方法B】
        /// </summary>
        /// <returns>返回[IList]</returns>
        public static IList<FoodInfo> GetAllFood()
        {
            IList<FoodInfo> listFood = new List<FoodInfo>(); ;
            
            string sql = "select FID,F_Pic,F_Desc from FoodInfo order by F_SendTime desc,FID desc";
            OleDbDataReader dr=SqlHelper.GetReader(sql)
            
                while (dr.Read())
                {
                    FoodInfo food == new FoodInfo();//1.创建,并且实例化
                    food.FID = Convert.ToInt32(dr[0]);
                    food.F_Pic = dr[1].ToString();
                    food.F_Desc = dr[2].ToString();
                    listFood.Add(food);
                }
            
            return listCus;
        }

解决方案 »

  1.   

    while (dr.Read())
    创建方法都在这里面
    每次都会实例化个对象的
      

  2.   

    ls说的对啊。在JAVA里面这样可能会造成内存占用增高,效率不高的情况,但是C#已经在编译期对这部分代码进行了优化。
    其实从Java转行的我,还是青睐第一种的,原因是:习惯的适应性。
      

  3.   


    堆栈的内存分配机制对于值类型,一般创建在线程堆栈上。但是值类型作为实例成员的一部分或发生装箱时,值类型
    是存储在托管堆上的。
    对于分配在堆栈上的局部变量来说,操作系统维护一个堆栈指针来指向下一个自由空间的地址,
    并且堆栈的内存地址是由高位到低位向下填充。托管堆的内存分配机制:引用类型的实例分配于托管堆上,而线程栈是对象生命周期开始的地方。32位处理器来说,应用
    程序完成进程初始化后,CLR将在进程的可用地址空间上分配一块保留的地址空间,它是进程(
    每个进程可使用4GB)中可用地址空间上的一块内存区域,但并不对应于任何物理内存,这块地址
    空间即是托管堆。托管堆可划分不同区域:重要的包括垃圾回收堆(GC Heap)和加载堆(Loader Heap),GC Heap
    用于存储对象实例,受GC管理;Loader Heap最重要的信息就是和元数据相关的信息,也就是Type
    对象,每个Type在Loader Heap上体现为一个方法表(Method Table,创建于编译时期,主要包含类
    型的特征信息、实现的接口数目等),Loader Heap不受GC控制,其生命周期是从创建到AppDomain卸载
    FoodInfo food= null;//声明了一个引用类型的变量food,这不是创建!!!
    它仅是一个引用(或指针),保村在线程的堆栈上,占4Byte的内存,用于保存FoodInfo对象的有
    效地址,执行过程是线程栈上的分配过程。此时food为指向任何有效实例,手动初始化为null,试
    图对food的任何操作将抛出NullReferenceException的异常;while
    {
    接着 food= new FoodInfo();通过new操作执行对象创建,该操作对应IL中的newobj指令,执行过程
    如下:
      (a) CLR按照继承关系进行递归搜素,找到System.Object类型,并返回字节总数total(根据你的成员及附加成员的总字节数计算)。
      (b) CLR在当前AppDomain对应的托管堆上搜素,找到一个连续未使用的total字节的连续空间
          并为其分配地址。注:堆得分配是向高地址扩展,和栈分配时相反的
      (c) 如果分配空间时发现内存不足,GC将启动垃圾收集操作来回收垃圾对象所占的内存。  (d)调用构造器,进行初始化操作,完成创建。   (e) 引用指向分配的托管堆地址
    }
    这个过程重复利用了一个指针,每次循环的时候都是改变这个指针指向的位置而已while (dr.Read())
    {
                        FoodInfo food == new FoodInfo();
     这个过程先执都会在线程栈上创建一个新的引用,然后(a)(b)(c)(d),然后将新的引用指向分配的托管堆空间
    }同时,二者的声明的范围不一样
      

  4.   

    呵呵··楼上的是必须知道的NET吧··