2012-01-04 15 views
7

¿Existe una forma sencilla de obtener básicamente una copia de los datos en lugar de una referencia con este método? Intenté .ToArray(). Where() pero eso todavía parece pasar una referencia.¿Cómo obtener una copia de datos en lugar de una referencia usando linq/lambda en C#?

Ejemplo:

static void Main(string[] args) 
{ 
    List<ob> t = new List<ob>(); 
    t.Add(new ob() { name = "hello" }); 
    t.Add(new ob() { name = "test" }); 

    ob item = t.Where(c => c.name == "hello").First(); 

    // Changing the name of the item changes the original item in the list<> 
    item.name = "burp"; 

    foreach (ob i in t) 
    { 
     Console.WriteLine(i.name); 
    } 

    Console.ReadLine(); 
} 

public class ob 
{ 
    public string name; 
} 

Respuesta

6

Es necesario crear una copia de su ob sí mismo - no es algo que proporciona LINQ.

+3

tratar de implementar [IClonable] (http://msdn.microsoft.com/en-us/library/system.icloneable%28v=VS.100%29.aspx) por tipo de ob. Luego puede usar 't.Where (c => c.name ==" hello "). Primero(). Clone()'. –

3

se podría definir un método Clone basado en la protected MemberwiseClone método existente:

public class Item 
{ 
    public Item Clone() 
    { 
     return (Item)this.MemberwiseClone(); 
    } 
} 

continuación:

ob item = t.Where(c => c.name == "hello").First().Clone(); 
2

Como ob es una clase, es un reference type y por lo tanto cualquier instancia de ob, cuando se asigna a una variable diferente (como ocurre dentro de la línea ob item = t.Where(c => c.name == "hello").First();) se copiará automáticamente el reference a la instancia original, y no se copiará la real instancia en sí. Este es un tema general de .NET relacionado con la copia de objetos y está separado de LINQ/Lambda,

Para lograr lo que desea, deberá crear Shallow Copy or a Deep Copy de la instancia resultante de su proyección LINQ.

para su clase ob, una copia superficial sería suficiente (generalmente shallowCopy copias tan poco como sea posible mientras que las copias DeepCopy todo - Una buena referencia para las diferencias se pueden encontrar here).

Para realizar un ShallowCopy de un objeto, puede usar simplemente MemberwiseClone que es un método incorporado del tipo de objeto .NET, heredado por todos los objetos.

Para algo más sustancial, que tendrá que implementar su propia función DeepCopy, pero que puede ser relativamente simple. Algo similar a estas implementaciones como se especifica here y here.

0

Una manera mucho más fácil de ir es simplemente serializar sus datos a JSON y luego de vuelta otra vez. Se necesita un pequeño golpe de rendimiento, pero es más seguro ya que es menos propenso a errores y no es necesario modificar todas las clases.

simplemente hacer:

var json = JsonConvert.SerializeObject(myObject) 
var clone = JsonConvert.DeserializeObject<T>(json) 
+0

¿Por qué no enviarlo a la base de datos SQL y luego volver a leerlo? – zgnilec

+0

Aunque poco elegante, esto funcionó muy bien para tratar con un objeto HttpRuntime.Cache. La minicumbre golpeó y volvió a hacer las cosas en lugar de buscar una solución de clonación que también tuviera un impacto en el rendimiento. – Stonetip

Cuestiones relacionadas