Creating a copy of an object in C#
There is no built-in way. You can have MyClass implement the IClonable
interface (but it is sort of deprecated) or just write your own Copy/Clone method. In either case you will have to write some code.
For big objects you could consider Serialization + Deserialization (through a MemoryStream), just to reuse existing code.
Whatever the method, think carefully about what "a copy" means exactly. How deep should it go, are there Id fields to be excepted etc.
Easy way to make a copy of a Type object
There will always be only one Type
for each class, so you can safely assign it.
Excerpt from Object.GetType:
For two objects x and y that have identical runtime types, Object.ReferenceEquals(x.GetType(),y.GetType()) returns true.
So there is no way that two Type
instances could exist for any given class, there will always be only one (ReferenceEquals
cannot be overriden)
In your case you could just do:
copy.ConnectionType = ConnectionType;
Full example:
public class A
{
public int Quantity { get; set; } = 0;
public Type ConnectionType { get; set; } = null;
public A Copy()
{
var copy = new A();
copy.Quantity = Quantity;
copy.ConnectionType = ConnectionType;
return copy;
}
}
How do you do a deep copy of an object in .NET?
Important Note
BinaryFormatter has been deprecated, and will no longer be available in .NET after November 2023. See BinaryFormatter Obsoletion Strategy
I've seen a few different approaches to this, but I use a generic utility method as such:
public static T DeepClone<T>(this T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
Notes:
Your class MUST be marked as
[Serializable]
for this to work.Your source file must include the following code:
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
How do you make a copy of an object?
Create a copy constructor for Colors. Then, do this.
Colors objColors = new Colors((Colors)Session["Colors"]);
In your new constructor, just copy the values that you need to and do your other constructor-related things.
What's happening in your code is that you are getting a pointer to a Colors object. Session["Colors"] and objColors point to the same object in memory, so when you modify one, changes are reflected in both. You want a brand spankin' new Colors object, with values initialized from objColors or Session["Colors"].
edit: A copy constructor might look like this:
public Colors(Colors otherColors)
{
this.privateVar1 = otherColors.privateVar1;
this.publicVar2 = otherColors.publicVar2;
this.Init();
}
.NET Copy object to existing object
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
Related Topics
Accessing a Variable from Another Script C#
Creating a Generic<T> Type Instance with a Variable Containing the Type
What Are the Differences Between Delegates and Events
Making a Property Deserialize But Not Serialize with JSON.Net
Mod of Negative Number Is Melting My Brain
How to Create a Dynamic Button Click Event on a Dynamic Button
How to Use Winforms Progress Bar
Run Single Instance of an Application Using Mutex
Any Decent C# Profilers Out There
Web App Blocked While Processing Another Web App on Sharing Same Session
Entity Framework Stored Procedure Table Value Parameter
Interop Type Cannot Be Embedded
Entity Framework 4 - Addobject VS Attach