将所有值从列表复制/克隆到C#中的另一个列表

Viv*_*rav 5 c# clone list

我有一堂课

public class Car()
{
    public string Name;
    public string Model;
}
Run Code Online (Sandbox Code Playgroud)

而且我有财产

List<Car> CarsA = new List<Car>();
CarsA.Add(new Car(){Name = "Verna",Model="Hyundai"});
CarsA.Add(new Car(){Name = "X1",Model="Bmw"});
Run Code Online (Sandbox Code Playgroud)

我还有另一个财产

List<Car> CarsB = new List<Car>();
Run Code Online (Sandbox Code Playgroud)

现在,我想将所有条目从CarsA添加到克隆/复制到CarsB,而不用将CarsA属性作为当前实例

(即我想为每个条目创建一个新对象并添加它)。

就像是

foreach(var car in CarsA)
{
    Car newCar =new Car();
    newCar.Name = car.Name;
    newCar.Model = car.Model;
    CarsB.Add(newCar);
}
Run Code Online (Sandbox Code Playgroud)

如果我不想实现ICloneable并且没有复制构造器怎么办?

Ian*_*Ian 6

您可能会考虑 LINQ 解决方案:

List<Car> CarsB = (from c in CarsA
                    let a = new Car() { Name = c.Name, Model = c.Model }
                    select a).ToList();
Run Code Online (Sandbox Code Playgroud)

由于NameModel属于string类型(不可变),因此此操作是安全的。

我认为它非常具有可读性。

相同但使用查询语法:

CarsB = CarsA.Select(c => new Car(){ Name = c.Name, Model = c.Model }).ToList();
Run Code Online (Sandbox Code Playgroud)

注意:如果,假设Model不是stringa class,那么上面的操作a = new Car()必须稍微更改为真正克隆模型中所有项目的东西(类似这样 Model = c.Model.Clone():),而不仅仅是引用它(Model = c.Model


Sim*_*son 3

如果您想对实例进行深度复制,序列化JSON然后再返回,您可以考虑选择。

然而,这比为所有要复制的对象实现复制方法需要更多的性能。然而,它节省了大量编写复制方法的时间,尽管它可能慢数百倍,但仍然很快。

我使用Json.net来解决这个问题,使用如下所示的扩展方法:

public static T Clone<T>(this T source)
{
    if (Object.ReferenceEquals(source, null))
        return default(T);

    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
}
Run Code Online (Sandbox Code Playgroud)

正如 Scott Chamberlain 所指出的,这也可以通过其他类型的序列化(不需要第 3 方库)来完成,例如:(BinaryFormatter另请注意,在使用这种方法时,您的类必须使用属性进行注释[Serializable]

public static T Clone<T>(this T source)
{
    if (Object.ReferenceEquals(source, null))
        return default(T);

    using (var stream = new MemoryStream())
    {
        var formatter = new BinaryFormatter();
        formatter.Serialize(stream, source);
        stream.Position = 0;

        return (T) formatter.Deserialize(stream);
    }
}
Run Code Online (Sandbox Code Playgroud)

那么用法将是:

foreach(var car in CarsA)
{
    CarsB.Add(car.Clone<Car>());
}
Run Code Online (Sandbox Code Playgroud)

它也可以这样使用:

List<Car> CarsB = CarsA.Clone<List<Car>>();
Run Code Online (Sandbox Code Playgroud)

  • 您不需要第 3 方依赖项,我经常使用完全相同的模式,但使用 [`BinaryFormatter`](https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary .binaryformatter(v=vs.110).aspx) 而不是 `JsonConvert`。 (3认同)