在一个循环中,是否创建新对象是如此必要?

时间:2013-12-22 13:18:29

标签: c#

var users = new List<User>();
User user = new User();
foreach (var element in elements)
{                
    try
    {
        user.Id = element.Attribute("Id").Value;
        user.Reputation = element.Attribute("Reputation").Value;
        user.CreationDate = DateTime.Parse(element.Attribute("CreationDate").Value);
        user.DisplayName = element.Attribute("DisplayName").Value;
        user.LastAccessDate = Convert.ToDateTime(element.Attribute("LastAccessDate").Value);
        user.WebsiteUrl = element.Attribute("WebsiteUrl").Value;
        user.Location = element.Attribute("Location").Value;
        user.Age = Convert.ToInt32(element.Attribute("Age").Value);
        user.AboutMe = element.Attribute("AboutMe").Value;
        user.Views = element.Attribute("Views").Value.ToInt32();
        user.UpVotes = element.Attribute("UpVotes").Value.ToInt32();
        user.DownVotes = element.Attribute("DownVotes").Value.ToInt32();

        users.Add(user);
    }
    catch (NullReferenceException)
    {
        // do nothing
    } 
    catch (Exception e)
    {
        System.Diagnostics.Debug.WriteLine(e.Message);
    }
}

表达式User user = new User();在foreach循环之外使用。我的目的是避免实例化新的User对象,如果一个循环运行10000000次(假设),如果我只是实例化一次并且在每个循环上我只是更改其内容变量并添加到列表中。但是发生了什么...我虽然得到了所有不同的用户,但在我的最终列表中只有一个用户(第一个用户),它有与循环运行一样多的副本...... 在foreach循环中使用express User user = new User();可以解决这个问题,但我不相信自己,为什么需要在每个循环中实例化一个新对象?.....请清除我

2 个答案:

答案 0 :(得分:4)

当您将其添加到列表中时,您将添加对正在创建的对象的引用,该列表将保留以供将来使用。

通过在循环中放置“new”,每次都会添加一个新对象。你会因为为它分配内存而受到性能影响。有一些方法可以缓解这种情况,因此命中是在其他地方(即程序运行时程序启动时创建的池/列表),但必须在某处分配它们。 / p>

通过在循环中放置“new”,列表的每个元素都指向您创建的同一个对象。

如果要为每个对象保留不同的信息,则必须将其存储在某处。

这个概念不只适用于C#

答案 1 :(得分:3)

引用类型和值类型是不同的。这是因为每次在foreach循环中,您只需更改一个用户并将其添加到列表中。

Value types: 数据类型是一种值类型,如果它将数据保存在自己的内存分配中。

Reference types: 引用类型包含指向另一个保存数据的内存位置的指针。

选中此处了解详情:http://msdn.microsoft.com/en-us/library/t63sy5hs.aspx

正如其他人所说,你应该在你的foreach循环中移动User定义:

    foreach (var element in elements)
    {
      User user = new User();
      ...
    }