如何在c#中复制一个对象[复制]

时间:2021-12-17 21:33:31

This question already has an answer here:

这个问题在这里已有答案:

Let's say that I have a class:

假设我有一节课:

class obj
{
  int a;
  int b;
}

and then I have this code:

然后我有这个代码:

obj myobj = new obj(){ a=1, b=2}
obj myobj2 = myobj;

Now the above code makes a reference to the first obj. What I want is that myobj2 refers to a copy of the myobj with changes not being reflected in the original. I have searched SO and the solutions thus far seems complicated. Is there an easier way to do this. I am using .net 4.5

现在上面的代码引用了第一个obj。我想要的是myobj2指的是myobj的副本,其中的变化没有反映在原文中。我搜索过SO,到目前为止解决方案似乎很复杂。有没有更简单的方法来做到这一点。我正在使用.net 4.5

3 个解决方案

#1


77  

Properties in your object are value types and you can use shallow copy in such sutuation like that:

对象中的属性是值类型,您可以在这样的sutuation中使用浅拷贝:

obj myobj2 = (obj)myobj.MemberwiseClone();

But in other situations like if any members are reference types, then you need Deep Copy. You can get deep copy of object using this method:

但在其他情况下,如果任何成员是引用类型,那么您需要Deep Copy。您可以使用此方法获取对象的深层副本:

public static T DeepCopy<T>(T other)
{
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(ms, other);
        ms.Position = 0;
        return (T)formatter.Deserialize(ms);
    }
}

Additional Info: (you can also read this article from MSDN)

附加信息:(您也可以从MSDN阅读本文)

Shallow copying is creating a new object and then copying the non-static fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed; for a reference type, the reference is copied but the referred object is not; therefore the original object and its clone refer to the same object.

浅复制正在创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则执行字段的逐位复制;对于引用类型,引用被复制但引用的对象不是;因此原始对象及其克隆引用相同的对象。

Deep copy is creating a new object and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, a new copy of the referred object is performed.

深层复制正在创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则执行字段的逐位复制。如果字段是引用类型,则执行引用对象的新副本。

#2


4  

You can use MemberwiseClone

您可以使用MemberwiseClone

obj myobj2 = (obj)myobj.MemberwiseClone();

The copy is a shallow copy which means the reference properties in the clone are pointing to the same values as the original object but that shouldn't be an issue in your case as the properties in obj are of value types.

副本是浅拷贝,这意味着克隆中的引用属性指向与原始对象相同的值,但在您的情况下不应该是一个问题,因为obj中的属性是值类型。

If you own the source code, you can also implement ICloneable

如果您拥有源代码,您还可以实现ICloneable

#3


0  

It sounds like your looking for an easy way to loosely couple your objects, but maintain the ability to allow the values to be changed when needed.

这听起来像是在寻找一种简单的方法来松散地耦合对象,但保持在需要时允许更改值的能力。

One way of passing values between classes can be like this.

在类之间传递值的一种方法可以是这样的。

public class Folders
{
     public string Source { get; private set; }
     public string Target { get; private set; }

     public Folders(string source, string target) 
     {
         if (String.IsEmptyOrNull(source) && String.IsEmptyOrNull(target))
         {
              throw new Exception("Null Parameter");
         }
         else
         {
               Source = source;
               Target = target;
          }
     }
}

So we've created a particular object called Folders. This can now be called in a second class file like this:

所以我们创建了一个名为Folders的特定对象。现在可以在第二个类文件中调用它,如下所示:

public bool CopyDirectory(string _source, string _destination)
{
    var dirStack = new Stack<Folders>();
    dirStack.Push(new Folders(_source, _destination));

    // Perform stuff related to this method.
}

So in our second class we are passing our methods parameters to this original class, which will set our values and allow us to manipulate them.

所以在我们的第二个类中,我们将方法参数传递给这个原始类,它将设置我们的值并允许我们操作它们。

We have another way, so in a separate class lets say we wanted to use our Constructor to pass the variables. This will allow an initial reference then the ability to actually deviate if we choose to.

我们有另一种方法,所以在一个单独的类中我们可以说我们想使用我们的构造函数来传递变量。如果我们选择,这将允许初始参考,然后实际偏离的能力。

public class DirectoryManagement
{
    private Folders _folder { get; private set; }
    public DirectoryManagement(Folders folder)
    {
        _folder = folder;
    }

}

So when we utilize this manner, we are actually ensuring the parameters initially passed to our Folders class are passed into our new class DirectoryManagement. Which would allow us to either link these values to other variables, use these values, or whatever our needs are.

因此,当我们使用这种方式时,我们实际上确保最初传递给Folders类的参数被传递到我们的新类DirectoryManagement中。这将允许我们将这些值链接到其他变量,使用这些值,或者我们的需求。

I'm not sure if this approach or the approach listed is your ideal solution. But I thought I'd present another manner of passing and using existing variables. Also some details on MemberwiseClone can be found here.

我不确定这种方法或列出的方法是否是您理想的解决方案。但我想我会提出另一种传递和使用现有变量的方式。还可以在此处找到有关MemberwiseClone的一些详细信息。

#1


77  

Properties in your object are value types and you can use shallow copy in such sutuation like that:

对象中的属性是值类型,您可以在这样的sutuation中使用浅拷贝:

obj myobj2 = (obj)myobj.MemberwiseClone();

But in other situations like if any members are reference types, then you need Deep Copy. You can get deep copy of object using this method:

但在其他情况下,如果任何成员是引用类型,那么您需要Deep Copy。您可以使用此方法获取对象的深层副本:

public static T DeepCopy<T>(T other)
{
    using (MemoryStream ms = new MemoryStream())
    {
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(ms, other);
        ms.Position = 0;
        return (T)formatter.Deserialize(ms);
    }
}

Additional Info: (you can also read this article from MSDN)

附加信息:(您也可以从MSDN阅读本文)

Shallow copying is creating a new object and then copying the non-static fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed; for a reference type, the reference is copied but the referred object is not; therefore the original object and its clone refer to the same object.

浅复制正在创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则执行字段的逐位复制;对于引用类型,引用被复制但引用的对象不是;因此原始对象及其克隆引用相同的对象。

Deep copy is creating a new object and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, a new copy of the referred object is performed.

深层复制正在创建一个新对象,然后将当前对象的非静态字段复制到新对象。如果字段是值类型,则执行字段的逐位复制。如果字段是引用类型,则执行引用对象的新副本。

#2


4  

You can use MemberwiseClone

您可以使用MemberwiseClone

obj myobj2 = (obj)myobj.MemberwiseClone();

The copy is a shallow copy which means the reference properties in the clone are pointing to the same values as the original object but that shouldn't be an issue in your case as the properties in obj are of value types.

副本是浅拷贝,这意味着克隆中的引用属性指向与原始对象相同的值,但在您的情况下不应该是一个问题,因为obj中的属性是值类型。

If you own the source code, you can also implement ICloneable

如果您拥有源代码,您还可以实现ICloneable

#3


0  

It sounds like your looking for an easy way to loosely couple your objects, but maintain the ability to allow the values to be changed when needed.

这听起来像是在寻找一种简单的方法来松散地耦合对象,但保持在需要时允许更改值的能力。

One way of passing values between classes can be like this.

在类之间传递值的一种方法可以是这样的。

public class Folders
{
     public string Source { get; private set; }
     public string Target { get; private set; }

     public Folders(string source, string target) 
     {
         if (String.IsEmptyOrNull(source) && String.IsEmptyOrNull(target))
         {
              throw new Exception("Null Parameter");
         }
         else
         {
               Source = source;
               Target = target;
          }
     }
}

So we've created a particular object called Folders. This can now be called in a second class file like this:

所以我们创建了一个名为Folders的特定对象。现在可以在第二个类文件中调用它,如下所示:

public bool CopyDirectory(string _source, string _destination)
{
    var dirStack = new Stack<Folders>();
    dirStack.Push(new Folders(_source, _destination));

    // Perform stuff related to this method.
}

So in our second class we are passing our methods parameters to this original class, which will set our values and allow us to manipulate them.

所以在我们的第二个类中,我们将方法参数传递给这个原始类,它将设置我们的值并允许我们操作它们。

We have another way, so in a separate class lets say we wanted to use our Constructor to pass the variables. This will allow an initial reference then the ability to actually deviate if we choose to.

我们有另一种方法,所以在一个单独的类中我们可以说我们想使用我们的构造函数来传递变量。如果我们选择,这将允许初始参考,然后实际偏离的能力。

public class DirectoryManagement
{
    private Folders _folder { get; private set; }
    public DirectoryManagement(Folders folder)
    {
        _folder = folder;
    }

}

So when we utilize this manner, we are actually ensuring the parameters initially passed to our Folders class are passed into our new class DirectoryManagement. Which would allow us to either link these values to other variables, use these values, or whatever our needs are.

因此,当我们使用这种方式时,我们实际上确保最初传递给Folders类的参数被传递到我们的新类DirectoryManagement中。这将允许我们将这些值链接到其他变量,使用这些值,或者我们的需求。

I'm not sure if this approach or the approach listed is your ideal solution. But I thought I'd present another manner of passing and using existing variables. Also some details on MemberwiseClone can be found here.

我不确定这种方法或列出的方法是否是您理想的解决方案。但我想我会提出另一种传递和使用现有变量的方式。还可以在此处找到有关MemberwiseClone的一些详细信息。