.NET将对象复制到现有对象

时间:2018-02-12 22:01:41

标签: c# .net reference

通常人们希望将对象复制到一个新对象中,以便。

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();

在这种情况下:

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

我正在寻找一种方法来创建一个&#34;副本来引用&#34;延期,我没有成功。这就是我想要完成的事情。

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]);

输出:

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

所以我并没有真正替换List中的对象,只是通过引用复制它。好吧,我可以手动完成(属性属性)但我正在寻找更通用的东西(可以应用于每个对象)。

我知道这可以通过像

这样的方法来实现
public static void CopyTo(this Car source, ref Car target)
{
    target.Brand = source.Brand;
    target.Price = source.Price;
}

但是我想要更通用的东西,比如遍历对象中的所有变量(自动)。

1 个答案:

答案 0 :(得分:0)

这不是一种真正推荐的方法,因为它不会起作用,并且可能对某些对象类型产生不可预测的结果,例如:具有私有字段或其他内部数据结构的类,无法通过复制公共可用属性来重新创建。

话虽这么说,迭代任意对象的属性(你甚至可以使用匿名类型)并将它们用作数据点来填充另一个对象是非常简单的。这种扩展方法应该这样做:

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));
        }
    }
}

示例:

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);
    }
}

输出:

Brand: Something
Price: 123

See my code on DotNetFiddle