¿Por qué añadir un nuevo valor a la lista sobrescribe los valores anteriores en la lista

Después de algunos tutoriales, pude crear con éxito una clase de colección que hereda la funcionalidad necesaria para crear una DataTable que se puede pasar al procedimiento almacenado de un servidor Sql como un parámetro de valor de tabla. Todo parece estar funcionando bien; Puedo agregar todas las filas y se ve hermosa. Sin embargo, tras una inspección más cercana noté que cuando agrego una nueva fila, los datos de todas las filas anteriores se sobrescriben con el valor de la nueva fila. Entonces, si tengo una fila con un valor de cadena de “foo” y agrego una segunda fila con el valor “barra”, se insertará la segunda fila (haciendo una DataTable con dos filas) pero ambas filas tendrán el valor “bar” “. ¿Alguien puede ver por qué sería esto? Aquí hay parte del código, que funciona pero ha sido un poco simplificado (la clase Tag se ha reducido para facilitar la explicación).

La siguiente es la clase de la Colección:

using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Web; using Microsoft.SqlServer.Server; namespace TagTableBuilder { public class TagCollection : List, IEnumerable { IEnumerator IEnumerable.GetEnumerator() { var sdr = new SqlDataRecord( new SqlMetaData("Tag", SqlDbType.NVarChar) ); foreach (Tag t in this) { sdr.SetSqlString(0, t.tagName); yield return sdr; } } } public class Tag { public string tagName { get; set; } } } 

Estos se llaman de la siguiente manera:

 //Create instance of collection TagCollection tags = new TagCollection(); //Create instance of object Tag _tag = new Tag(); foreach (string t in tagList) { //Add value to class propety _tag.tagName = t; //Add class to collection, this is where all previously added rows are overwritten tags.Add(_tag); } 

Está utilizando la misma instancia del objeto Tag dentro del bucle, por lo que cada actualización de tagName tiene la misma referencia. Mueva la statement dentro del ciclo para obtener un objeto nuevo en cada pasada del ciclo:

 foreach (string t in tagList) { Tag _tag = new Tag(); //Add value to class propety _tag.tagName = t; //Add class to collection, this is where all previously added rows are overwritten tags.Add(_tag); } 

También observe que actualicé la última línea para agregar _tag lugar de mTag ya que no veo esto definido en ningún lado.

En el bucle donde agrega las tags a la colección, está usando la misma instancia de objeto de Tag. Básicamente, está configurando el nombre de una Etiqueta para el primer valor en tagList y agregándolo a la colección, luego está cambiando el nombre de esa misma Etiqueta por el segundo valor en tagList y lo vuelve a agregar a la colección.

¡Su colección de tags contiene varias referencias al mismo objeto de etiqueta! Cree una instancia de _tag dentro del bucle for cada vez antes de configurar el nombre de la etiqueta y agregarla a la colección.