2

Usually people want to make a duplicate of an object into a new object so that.

List<Car> cars = new List<Car> { new Car(), new Car() }

var b = cars[0];

var a = new Car { Brand = "Something", Price = 123}

cars[0] = a.Clone();

in this case the:

b.Brand => ""
b.Price => 0

I'm looking for a way create a "copy to reference" extension and I've been unsuccessful. This is what I'm trying to accomplish.

List<Car> cars = new List<Car> { new Car(), new Car() }

var b = cars[0];

var a = new Car { Brand = "Something", Price = 123}

a.CopyTo(ref cars[0]);

Outputs:

b.Brand => "Something"
b.Price => 123

so I'm not really replacing the object in the List but just copying to it by reference. Well I can do it manually (property be property) but I was looking for something more general (that could be applied to every object).

I know this is possible to accomplish with a method like

public static void CopyTo(this Car source, ref Car target)
{
    target.Brand = source.Brand;
    target.Price = source.Price;
}

but I wanted something more general, like going through all the variables in the object (automatically).

xDGameStudios
  • 321
  • 1
  • 13
  • Possible duplicate of [Deep cloning objects](https://stackoverflow.com/questions/78536/deep-cloning-objects) –  Feb 12 '18 at 22:07
  • No it is not a duplicate, I don't want to duplicate an object into a new object.. I want to duplicate an object into an already existing object. – xDGameStudios Feb 12 '18 at 22:21
  • "so I'm not really changing the object in the List" What you're suggesting *is* changing the objects in the list. If it wasn't, then your second snippet would have the same output as the first. The only way for the second snippet to do what you want is for it to change the object in the list. – Servy Feb 12 '18 at 22:31
  • @Servy how to make it so that the object in the index 0 of the list get's a copy of the values in the object "a" without replacing the object?! – xDGameStudios Feb 12 '18 at 22:33
  • @xDGameStudios And that statement is contradictory to the statement that you don't want to change the object in the list. The only way to do that *is to change the object in the list*. – Servy Feb 12 '18 at 22:35
  • no it is not.... I can pass the object in the array as a reference and edit it according to the values stored in "a" I just wanted an automated way to do so. – xDGameStudios Feb 12 '18 at 22:36
  • @xDGameStudios If you just want to create a new object and then set that new object to be the item in the list, you can do that, but then the program you've provided won't have the output you've claimed it should have (because you won't be changing the existing object, you'll be making a new one). If you want to change the existing object then *you'll have to change that object*, contrary to your statement that you don't want to. – Servy Feb 12 '18 at 22:39
  • Cloning is standard practice for .net. If you don't want to clone then don't title and tag your question that way –  Feb 12 '18 at 22:41
  • I think you are not understanding me... or don't want to understand... and I'm sorry if I'm not making myself clear not trying to be rude or anything. I don't want to replace the instance in the list with a new one... just want to copy the values of an existing object and apply those values to the object already in the list. Hope I made myself clearer now. an sorry again for not being that clear – xDGameStudios Feb 12 '18 at 23:04
  • @Servy I chose a bad word I didn't mean "change" because I do want to change it... I don't want to replace it with a new instance! That's it :) – xDGameStudios Feb 12 '18 at 23:17

1 Answers1

1

This is not really a recommended approach, as it won't work and could have unpredictable results for certain object types, e.g. classes that have private fields or other internal data structures that cannot be recreated by copying the publicly available properties.

That being said, it is pretty trivial to iterate through an arbitrary's object's properties (you could even use an anonymous type) and use them as data points to populate another object. This extension method should do it:

static class ExtensionMethods
{
    static public void CopyTo(this object source, object destination)
    {
        var destinationType = destination.GetType();

        foreach (var s in source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            var d = destinationType.GetProperty(s.Name);
            if (d == null) continue;   //No matching property
            if (!d.CanWrite) continue; //Property found, but is read only
            if (!d.PropertyType.IsAssignableFrom(s.PropertyType)) continue; //properties are not type-compatible
            d.SetValue(destination, s.GetValue(source));
        }
    }
}

Example:

public class Program
{
    public static void Main()
    {
        List<Car> cars = new List<Car> { new Car(), new Car() };

        var b = cars[0];

        var a = new { Brand = "Something", Price = 123M};  //Notice this is an anonymous type. You can use any object, as long as the properties match.

        a.CopyTo(cars[0]);

        Console.WriteLine("Brand: {0}", cars[0].Brand);
        Console.WriteLine("Price: {0}", cars[0].Price);
    }
}

Output:

Brand: Something
Price: 123

See my code on DotNetFiddle

John Wu
  • 50,556
  • 8
  • 44
  • 80