为什么对象多次重复?

时间:2015-03-29 00:33:31

标签: c# asp.net-mvc-4 object generics

我想知道对象创建/引用的发生方式。我有一段代码,其中列表中的所有Employee对象都是重复的。顶级代码的问题是覆盖所有以前的条目,因此列表包含重复的对象,而底部是我的修复。我想了解为什么在while.Read()循环中创建新对象,而在while循环之外创建雇员对象却没有。

public IEnumerable<Employee> Employees
{
    get
    {
        List<Employee> employees = new List<Employee>();

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            Employee _employee = new Employee(); //<issue is here, all enties in employees are duplicated values of a single record
            SqlCommand sqlCmd = new SqlCommand("spGetAllEmployees", connection);
            sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
            connection.Open();
            SqlDataReader reader = sqlCmd.ExecuteReader();
            while (reader.Read())
            {
                _employee.EmployeeID = Convert.ToInt32(reader["EmployeeID"]); //object instantiation here fixed the issue, why?
                _employee.Name = (reader["Name"].ToString());
                _employee.Gender = (reader["Gender"].ToString());
                _employee.City = (reader["City"].ToString());
                _employee.DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]);
                _employee.DepartmentID = Convert.ToInt32(reader["DepartmentID"]);
                employees.Add(_employee);
            }
        }
        return employees;
    }
}

我想了解为什么这样可以解决问题。

    public IEnumerable<Employee> Employees
            {
                get
                {
                    List<Employee> employees = new List<Employee>();

                    using (SqlConnection connection = new 

SqlConnection(connectionString))
                {
                    SqlCommand sqlCmd = new SqlCommand("spGetAllEmployees", connection);
                    sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
                    connection.Open();
                    SqlDataReader reader = sqlCmd.ExecuteReader();
                    while (reader.Read())
                    {
                        Employee _employee = new Employee(); //this fixed the issue, why?
                        _employee.EmployeeID = Convert.ToInt32(reader["EmployeeID"]);
                        _employee.Name = (reader["Name"].ToString());
                        _employee.Gender = (reader["Gender"].ToString());
                        _employee.City = (reader["City"].ToString());
                        _employee.DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]);
                        _employee.DepartmentID = Convert.ToInt32(reader["DepartmentID"]);
                        employees.Add(_employee);
                    }
                    }
                    return employees;
                }
            }

2 个答案:

答案 0 :(得分:1)

在第一个示例中,您在循环外部创建了一个_employee对象。该对象存储在内存中的单个引用中。当您使用Add(_employee)时,您没有使用_employee的当前属性创建新对象,而是将多个内存中的单个对象的引用添加到列表中。当您在循环中的后续行程中更改_employee的任何属性的值时,您正在更改内存中的单个对象,这实际上是更改列表中的每个项目。

在第二个示例中,您将通过_employee每次循环创建一个新的while对象,并且每个新对象都有一个新的内存地址。因此,您添加到列表中的每个对象都独立于最后一个。

答案 1 :(得分:0)

Typeof Employee是一个引用类型,它只是指向保存实际数据的另一个内存位置的指针。

在第一个示例中,您只是初始化一个Employee实例(引用类型)。在while循环中,您继续将相同的实例添加到集合中,同时更新其属性(集合中的所有项目的属性都将设置数据库中最后一行的值)。

在第二个示例中,您将在每次迭代中创建一个新实例,并根据当前行设置其属性。下一次迭代创建另一个实例并设置其属性。

This article可能有助于解释引用类型和值类型之间的区别。