Clone object without changing the values of the original object C# - c#

I need to make a copy of a MyGame class and use it in my simulation for game trials before I select a move to play.
For example :
public class MyGame
{
private int Start;
private Board board;
//Constructor
public void Play()
{
//play game
}
public object Clone()
{
}
}
public class Board
{
private int Count;
//Constructor
//Some methods and properties
public object Clone()
{
}
}
Writing code for the method Clone() I have tried
MemberwiseClone()
(Board) this.MemberwiseClone()
Board b = (Board) this.Board
I have read alot of articles and forums about this topic. The answer most people
use is Deep cloning objects in C#, I tried samples with respect to my project but I still
get my simulation modifying the original object (MyGame Class) and not the copy.

Here I have an example for a deep copy, which deeply copies all reference type objects that are used with a copy constructor:
public sealed class MyGame
{
private int start;
private Board board;
public MyGame(MyGame orig)
{
// value types - like integers - can easily be
// reused
this.start = orig.start;
// reference types must be clones seperately, you
// must not use orig.board directly here
this.board = new Board(orig.board);
}
}
public sealed class Board
{
private int count;
public Board(Board orig)
{
// here we have a value type again
this.count = orig.count;
// here we have no reference types. if we did
// we'd have to clone them too, as above
}
}
I think your copy might be somehow shallow and re-use some references (like for instance this.board = orig.board instead of creating a new board). This is a guess though, as I can't see your cloning implementation.
Furthermore, I used copy constructors instead of implementing ICloneable. The implementation is almost the same. One advantage though is that you simplify dealing with subclasses:
Suppose you had a MyAwesomeGame : MyGame, not overriding MyGame.Clone. What would you get from myAwesomeGame.Clone()? Actually, still a new MyGame because MyGame.Clone is the method in charge. One may carelessly expect a properly cloned MyAwesomeGame here, however. new MyGame(myAwesomeGame) still copies somehow incompletely, but it's more obvious. In my example I made the classes sealed to avoid this failures. If you can seal them, there's good change it will make your life simpler.
Implementing ICloneable is not recommended in general, see Why should I implement ICloneable in c#? for more detailed and general information.
Here I have an ICloneable approach anyway, to make things complete and enable you to compare and contrast:
public class MyGame : ICloneable
{
private int start;
private Board board;
public object Clone()
{
var copy = new MyGame();
copy.start = this.start;
copy.board = (Board)this.board.Clone();
return copy;
}
}
public class Board : ICloneable
{
private int count;
public object Clone()
{
var copy = new Board();
copy.count = this.count;
return copy;
}
}

The simplest and most reliable way to implement deep cloning is to serialize, and then deserialize your objects. This can have a large performance cost associated with it. Consider classes from this namespace for serialization http://msdn.microsoft.com/en-us/library/System.Xml.Serialization.aspx
Deep cloning requires recursively creating a new instance of every property that is not a value type. Cloning MyGame would require a new instance of MyGame and a new instance of Board, both populated with the same Start and Count values as their originals. This is fiddly and a nightmare to maintain. As you can guess, it is not an automatic process out of the box but it can be, using reflection (which is how the xml serialization above works.
MemberwiseClone only creates a new instance of the object you called it on - all references remain the same.

MemberwiseClone() creates a stupid shallow clone of each member of an object. This works fine when members are value types but in case of reference types it fails because it'll clone pointers and not pointed objects.
Starting from your code a memberwise clone is something like this:
public object Clone()
{
MyGame cloned = new MyGame();
cloned.Start = this.Start; // Copied (cloned) because value type
cloned.Board = this.Board; // This is not a copy, just a reference!
}
A better solution for a deep clone would be to implement ICloneable (for example, otherwise a copy constructor approach is also good) for each reference type, let's suppose Board is cloneable too:
public object Clone()
{
MyGame cloned = new MyGame();
cloned.Start = this.Start;
cloned.Board = (Board)this.Board.Clone();
}
Please note that in your example Board can implement Clone() using MemberwiseClone() because its members are all value types.
If you can't manage this (for example because code is not accesible) or you need a quick/dirty solution you may consider to user serializaiton (in memory). Which serializer is a big question, each one has some limitations (about what's serialized and how). For example XML serializer won't serialize private fields (it won't serialize fields at all). Faster one is binary formatter but you need to mark each class with a proper attribute.
Change according serializer you prefer (according to your requirements), in this case I assume you marked MyGame and Board as [Serializable] for the quick binary serialization:
public object Clone()
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(stream);
}
}

Try this
public static T DeepCopy<T>(this T obj)
{
T result;
var serializer = new DataContractSerializer(typeof(T));
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
ms.Position = 0;
result = (T)serializer.ReadObject(ms);
ms.Close();
}
return result;
}

I have two extension methods that I use to achieve this. Demo code below:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace SimpleCloneDemo
{
public class Program
{
public static void Main(string[] args)
{
var person = new Person { Id = 1, FirstName = "John", Surname = "Doe" };
var clone = person.Clone();
clone.Id = 5;
clone.FirstName = "Jane";
Console.WriteLine(#"person: {0}", person);
Console.WriteLine(#"clone: {0}", clone);
if (Debugger.IsAttached)
Console.ReadLine();
}
}
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public override string ToString()
{
return string.Format("Id: {0}, Full Name: {1}, {2}", Id, Surname, FirstName);
}
}
public static class ObjectExtensions
{
public static T Clone<T>(this T entity) where T : class
{
var clone = Activator.CreateInstance(entity.GetType());
var entityPropValueDictionary = entity.AsPropValueDictionary();
foreach (var prop in clone.GetType().GetProperties())
{
clone.GetType().GetProperty(prop.Name).SetValue(clone, entityPropValueDictionary[prop.Name]);
}
return clone as T;
}
public static IDictionary<string, object> AsPropValueDictionary<T>(this T instance, params BindingFlags[] bindingFlags)
{
var runtimeBindingFlags = BindingFlags.Default;
switch (bindingFlags.Count())
{
case 0:
runtimeBindingFlags = BindingFlags.Default;
break;
case 1:
runtimeBindingFlags = bindingFlags[0];
break;
default:
runtimeBindingFlags = bindingFlags.Aggregate(runtimeBindingFlags, (current, bindingFlag) => current | bindingFlag);
break;
}
return runtimeBindingFlags == BindingFlags.Default
? instance.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(instance))
: instance.GetType().GetProperties(runtimeBindingFlags).ToDictionary(prop => prop.Name, prop => prop.GetValue(instance));
}
}
}
Result:
I wrote these quick-and-dirty extension methods in a hurry so there are probably some issues with it and they are probably horribly inefficient, but they seemed to work for my use case. They may help you, too.

Related

Why is it impossible to cast to a derived type [duplicate]

Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?.
I have tried it and it creates a run-time error.
No. A reference to a derived class must actually refer to an instance of the derived class (or null). Otherwise how would you expect it to behave?
For example:
object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?
If you want to be able to convert an instance of the base type to the derived type, I suggest you write a method to create an appropriate derived type instance. Or look at your inheritance tree again and try to redesign so that you don't need to do this in the first place.
No, that's not possible since assigning it to a derived class reference would be like saying "Base class is a fully capable substitute for derived class, it can do everything the derived class can do", which is not true since derived classes in general offer more functionality than their base class (at least, that's the idea behind inheritance).
You could write a constructor in the derived class taking a base class object as parameter, copying the values.
Something like this:
public class Base {
public int Data;
public void DoStuff() {
// Do stuff with data
}
}
public class Derived : Base {
public int OtherData;
public Derived(Base b) {
this.Data = b.Data;
OtherData = 0; // default value
}
public void DoOtherStuff() {
// Do some other stuff
}
}
In that case you would copy the base object and get a fully functional derived class object with default values for derived members. This way you can also avoid the problem pointed out by Jon Skeet:
Base b = new Base();//base class
Derived d = new Derived();//derived class
b.DoStuff(); // OK
d.DoStuff(); // Also OK
b.DoOtherStuff(); // Won't work!
d.DoOtherStuff(); // OK
d = new Derived(b); // Copy construct a Derived with values of b
d.DoOtherStuff(); // Now works!
Solution with JsonConvert (instead of typecast)
Today i faced the same issue and i found a simple and quick solution to the problem using JsonConvert.
var base = new BaseClass();
var json = JsonConvert.SerializeObject(base);
DerivedClass derived = JsonConvert.DeserializeObject<DerivedClass>(json);
I had this problem and solved it by adding a method that takes a type parameter and converts the current object into that type.
public TA As<TA>() where TA : Base
{
var type = typeof (TA);
var instance = Activator.CreateInstance(type);
PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties)
{
property.SetValue(instance, property.GetValue(this, null), null);
}
return (TA)instance;
}
That means that you can use it in you code like this:
var base = new Base();
base.Data = 1;
var derived = base.As<Derived>();
Console.Write(derived.Data); // Would output 1
As many others have answered, No.
I use the following code on those unfortunate occasions when I need to use a base type as a derived type. Yes it is a violation of the Liskov Substitution Principle (LSP) and yes most of the time we favor composition over inheritance. Props to Markus Knappen Johansson whose original answer this is based upon.
This code in the base class:
public T As<T>()
{
var type = typeof(T);
var instance = Activator.CreateInstance(type);
if (type.BaseType != null)
{
var properties = type.BaseType.GetProperties();
foreach (var property in properties)
if (property.CanWrite)
property.SetValue(instance, property.GetValue(this, null), null);
}
return (T) instance;
}
Allows:
derivedObject = baseObect.As<derivedType>()
Since it uses reflection, it is "expensive". Use accordingly.
No it is not possible, hence your runtime error.
But you can assign an instance of a derived class to a variable of base class type.
As everyone here said, that's not possible directly.
The method I prefer and is rather clean, is to use an Object Mapper like AutoMapper.
It will do the task of copying properties from one instance to another (Not necessarily the same type) automatically.
In c# 9.0 you can try to use records for this. They have default copy constructor that copy all fields - no need to use reflection / constructor with all fields.
public record BaseR
{
public string Prop1 { get; set; }
}
public record DerivedR : BaseR
{
public DerivedR(BaseR baseR) : base(baseR) { }
public string Prop2 { get; set; }
}
var baseR = new BaseR { Prop1 = "base prob" };
var derivedR = new DerivedR(baseR) { Prop2 = "new prop" };
Not in the Traditional Sense... Convert to Json, then to your object, and boom, done! Jesse above had the answer posted first, but didn't use these extension methods which make the process so much easier. Create a couple of extension methods:
public static string ConvertToJson<T>(this T obj)
{
return JsonConvert.SerializeObject(obj);
}
public static T ConvertToObject<T>(this string json)
{
if (string.IsNullOrEmpty(json))
{
return Activator.CreateInstance<T>();
}
return JsonConvert.DeserializeObject<T>(json);
}
Put them in your toolbox forever, then you can always do this:
var derivedClass = baseClass.ConvertToJson().ConvertToObject<derivedClass>();
Ah, the power of JSON.
There are a couple of gotchas with this approach: We really are creating a new object, not casting, which may or may not matter. Private fields will not be transferred, constructors with parameters won't be called, etc. It is possible that some child json won't be assigned. Streams are not innately handled by JsonConvert. However, if our class doesn't rely on private fields and constructors, this is a very effective method of moving data from class to class without mapping and calling constructors, which is the main reason why we want to cast in the first place.
Expanding on #ybo's answer - it isn't possible because the instance you have of the base class isn't actually an instance of the derived class. It only knows about the members of the base class, and doesn't know anything about those of the derived class.
The reason that you can cast an instance of the derived class to an instance of the base class is because the derived class actually already is an instance of the base class, since it has those members already. The opposite cannot be said.
You can cast a variable that is typed as the base-class to the type of a derived class; however, by necessity this will do a runtime check, to see if the actual object involved is of the correct type.
Once created, the type of an object cannot be changed (not least, it might not be the same size). You can, however, convert an instance, creating a new instance of the second type - but you need to write the conversion code manually.
You have to use an object cloner/copier that will assign all the properties one by one.
Doing this by hand is inefficient and not future-proof. But serializing & deserializing to JSON and back is not the best solution, it is slow and very memory inefficient.
However, using AutoMapper is fast. PropMapper is even faster.
PS. Disclosure: I am a contributor at PropMapper open source project.
No, it is not possible.
Consider a scenario where an ACBus is a derived class of base class Bus. ACBus has features like TurnOnAC and TurnOffAC which operate on a field named ACState. TurnOnAC sets ACState to on and TurnOffAC sets ACState to off. If you try to use TurnOnAC and TurnOffAC features on Bus, it makes no sense.
class Program
{
static void Main(string[] args)
{
a a1 = new b();
a1.print();
}
}
class a
{
public a()
{
Console.WriteLine("base class object initiated");
}
public void print()
{
Console.WriteLine("base");
}
}
class b:a
{
public b()
{
Console.WriteLine("child class object");
}
public void print1()
{
Console.WriteLine("derived");
}
}
}
when we create a child class object,the base class object is auto initiated so base class reference variable can point to child class object.
but not vice versa because a child class reference variable can not point to base class object because no child class object is created.
and also notice that base class reference variable can only call base class member.
There actually IS a way to do this. Think about how you might use Newtonsoft JSON to deserialize an object from json. It will (or at least can) ignore missing elements and populate all the elements that it does know about.
So here's how I did it. A small code sample will follow my explanation.
Create an instance of your object from the base class and populate it accordingly.
Using the "jsonconvert" class of Newtonsoft json, serialize that object into a json string.
Now create your sub class object by deserializing with the json string created in step 2. This will create an instance of your sub class with all the properties of the base class.
This works like a charm! So.. when is this useful? Some people asked when this would make sense and suggested changing the OP's schema to accommodate the fact that you can't natively do this with class inheritance (in .Net).
In my case, I have a settings class that contains all the "base" settings for a service. Specific services have more options and those come from a different DB table, so those classes inherit the base class. They all have a different set of options. So when retrieving the data for a service, it's much easier to FIRST populate the values using an instance of the base object. One method to do this with a single DB query. Right after that, I create the sub class object using the method outlined above. I then make a second query and populate all the dynamic values on the sub class object.
The final output is a derived class with all the options set. Repeating this for additional new sub classes takes just a few lines of code. It's simple, and it uses a very tried and tested package (Newtonsoft) to make the magic work.
This example code is vb.Net, but you can easily convert to c#.
' First, create the base settings object.
Dim basePMSettngs As gtmaPayMethodSettings = gtmaPayments.getBasePayMethodSetting(payTypeId, account_id)
Dim basePMSettingsJson As String = JsonConvert.SerializeObject(basePMSettngs, Formatting.Indented)
' Create a pmSettings object of this specific type of payment and inherit from the base class object
Dim pmSettings As gtmaPayMethodAimACHSettings = JsonConvert.DeserializeObject(Of gtmaPayMethodAimACHSettings)(basePMSettingsJson)
You can use an Extention:
public static void CopyOnlyEqualProperties<T>(this T objDest, object objSource) where T : class
{
foreach (PropertyInfo propInfo in typeof(T).GetProperties())
if (objSource.GetType().GetProperties().Any(z => z.Name == propInfo.Name && z.GetType() == propInfo.GetType()))
propInfo.SetValue(objDest, objSource.GetType().GetProperties().First(z => z.Name == propInfo.Name && z.GetType() == propInfo.GetType()).GetValue(objSource));
}
In Code:
public class BaseClass
{
public string test{ get; set;}
}
public Derived : BaseClass
{
//Some properies
}
public void CopyProps()
{
BaseClass baseCl =new BaseClass();
baseCl.test="Hello";
Derived drv=new Derived();
drv.CopyOnlyEqualProperties(baseCl);
//Should return Hello to the console now in derived class.
Console.WriteLine(drv.test);
}
Might not be relevent, but I was able to run code on a derived object given its base. It's definitely more hacky than I'd like, but it works:
public static T Cast<T>(object obj)
{
return (T)obj;
}
...
//Invoke parent object's json function
MethodInfo castMethod = this.GetType().GetMethod("Cast").MakeGenericMethod(baseObj.GetType());
object castedObject = castMethod.Invoke(null, new object[] { baseObj });
MethodInfo jsonMethod = baseObj.GetType ().GetMethod ("ToJSON");
return (string)jsonMethod.Invoke (castedObject,null);
You can do this using generic.
public class BaseClass
{
public int A { get; set; }
public int B { get; set; }
private T ConvertTo<T>() where T : BaseClass, new()
{
return new T
{
A = A,
B = B
}
}
public DerivedClass1 ConvertToDerivedClass1()
{
return ConvertTo<DerivedClass1>();
}
public DerivedClass2 ConvertToDerivedClass2()
{
return ConvertTo<DerivedClass2>();
}
}
public class DerivedClass1 : BaseClass
{
public int C { get; set; }
}
public class DerivedClass2 : BaseClass
{
public int D { get; set; }
}
You get three benefits using this approach.
You are not duplicating the code
You are not using reflection (which is slow)
All of your conversions are in one place
I know this is old but I've used this successfully for quite a while.
private void PopulateDerivedFromBase<TB,TD>(TB baseclass,TD derivedclass)
{
//get our baseclass properties
var bprops = baseclass.GetType().GetProperties();
foreach (var bprop in bprops)
{
//get the corresponding property in the derived class
var dprop = derivedclass.GetType().GetProperty(bprop.Name);
//if the derived property exists and it's writable, set the value
if (dprop != null && dprop.CanWrite)
dprop.SetValue(derivedclass,bprop.GetValue(baseclass, null),null);
}
}
I combined some portions of the previous answers (thanks to those authors) and put together a simple static class with two methods that we're using.
Yes, it's simple, no it doesn't cover all scenarios, yes it could be expanded and made better, no it's not perfect, yes it could possibly be made more efficient, no it's not the greatest thing since sliced bread, yes there are full-on robust nuget package object mappers out there that are way better for heavy use, etc etc, yada yada - but it works for our basic needs though :)
And of course it will try to map values from any object to any object, derived or not (only the public properties that are named the same of course - ignores the rest).
USAGE:
SesameStreetCharacter puppet = new SesameStreetCharacter() { Name = "Elmo", Age = 5 };
// creates new object of type "RealPerson" and assigns any matching property
// values from the puppet object
// (this method requires that "RealPerson" have a parameterless constructor )
RealPerson person = ObjectMapper.MapToNewObject<RealPerson>(puppet);
// OR
// create the person object on our own
// (so RealPerson can have any constructor type that it wants)
SesameStreetCharacter puppet = new SesameStreetCharacter() { Name = "Elmo", Age = 5 };
RealPerson person = new RealPerson("tall") {Name = "Steve"};
// maps and overwrites any matching property values from
// the puppet object to the person object so now our person's age will get set to 5 and
// the name "Steve" will get overwritten with "Elmo" in this example
ObjectMapper.MapToExistingObject(puppet, person);
STATIC UTILITY CLASS:
public static class ObjectMapper
{
// the target object is created on the fly and the target type
// must have a parameterless constructor (either compiler-generated or explicit)
public static Ttarget MapToNewObject<Ttarget>(object sourceobject) where Ttarget : new()
{
// create an instance of the target class
Ttarget targetobject = (Ttarget)Activator.CreateInstance(typeof(Ttarget));
// map the source properties to the target object
MapToExistingObject(sourceobject, targetobject);
return targetobject;
}
// the target object is created beforehand and passed in
public static void MapToExistingObject(object sourceobject, object targetobject)
{
// get the list of properties available in source class
var sourceproperties = sourceobject.GetType().GetProperties().ToList();
// loop through source object properties
sourceproperties.ForEach(sourceproperty => {
var targetProp = targetobject.GetType().GetProperty(sourceproperty.Name);
// check whether that property is present in target class and is writeable
if (targetProp != null && targetProp.CanWrite)
{
// if present get the value and map it
var value = sourceobject.GetType().GetProperty(sourceproperty.Name).GetValue(sourceobject, null);
targetobject.GetType().GetProperty(sourceproperty.Name).SetValue(targetobject, value, null);
}
});
}
}
You can use a copy constructor that immediately invokes the instance constructor, or if your instance constructor does more than assignments have the copy constructor assign the incoming values to the instance.
class Person
{
// Copy constructor
public Person(Person previousPerson)
{
Name = previousPerson.Name;
Age = previousPerson.Age;
}
// Copy constructor calls the instance constructor.
public Person(Person previousPerson)
: this(previousPerson.Name, previousPerson.Age)
{
}
// Instance constructor.
public Person(string name, int age)
{
Name = name;
Age = age;
}
public int Age { get; set; }
public string Name { get; set; }
}
Referenced the Microsoft C# Documentation under Constructor for this example having had this issue in the past.
With regarding #MarkusKnappenJohansson answer and below comments we can change his code extending extension function :) so it may update an existing deriving class instance via this code :
public static TDerived As<TDerived>(this Base baseInstance, TDerived updateDerivedInstance = null) where TDerived : Base, new()
{
Type baseType = typeof(Base);
Type derivedType = typeof(TDerived);
PropertyInfo[] properties = baseType.GetProperties();
object instanceDerived = null;
if (updateDerivedInstance == null)
{
instanceDerived = Activator.CreateInstance(derivedType);
}
else
{
instanceDerived = (object)(updateDerivedInstance);
}
foreach (PropertyInfo property in properties)
{
if (property.CanWrite)
{
property.SetValue(instanceDerived, property.GetValue(baseInstance, null), null);
}
}
return (TDerived)instanceDerived;
}
Usage for getting new derived Instance is var base = new Base(); base.Data = 1; var derived = base.As<Derived>(); Console.Write(derived.Data); // Would output 1
Usage for updating existing derived Instance is var derived = new Derived(); var base = new Base(); base.Data = 1; var derivedUpdated = base.As<Derived>(derived); Console.Write(derivedUpdated.Data); // Would output 1
Another solution is to add extension method like so:
public static void CopyProperties(this object destinationObject, object sourceObject, bool overwriteAll = true)
{
try
{
if (sourceObject != null)
{
PropertyInfo[] sourceProps = sourceObject.GetType().GetProperties();
List<string> sourcePropNames = sourceProps.Select(p => p.Name).ToList();
foreach (PropertyInfo pi in destinationObject.GetType().GetProperties())
{
if (sourcePropNames.Contains(pi.Name))
{
PropertyInfo sourceProp = sourceProps.First(srcProp => srcProp.Name == pi.Name);
if (sourceProp.PropertyType == pi.PropertyType)
if (overwriteAll || pi.GetValue(destinationObject, null) == null)
{
pi.SetValue(destinationObject, sourceProp.GetValue(sourceObject, null), null);
}
}
}
}
}
catch (ApplicationException ex)
{
throw;
}
}
then have a constructor in each derived class that accepts base class:
public class DerivedClass: BaseClass
{
public DerivedClass(BaseClass baseModel)
{
this.CopyProperties(baseModel);
}
}
It will also optionally overwrite destination properties if already set (not null) or not.
Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?.
Not only explicit, but also implicit conversions are possible.
C# language doesn't permit such conversion operators, but you can still write them using pure C# and they work. Note that the class which defines the implicit conversion operator (Derived) and the class which uses the operator (Program) must be defined in separate assemblies (e.g. the Derived class is in a library.dll which is referenced by program.exe containing the Program class).
//In library.dll:
public class Base { }
public class Derived {
[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Implicit(Base a) {
return new Derived(a); //Write some Base -> Derived conversion code here
}
[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Explicit(Base a) {
return new Derived(a); //Write some Base -> Derived conversion code here
}
}
//In program.exe:
class Program {
static void Main(string[] args) {
Derived z = new Base(); //Visual Studio can show squiggles here, but it compiles just fine.
}
}
When you reference the library using the Project Reference in Visual Studio, VS shows squiggles when you use the implicit conversion, but it compiles just fine. If you just reference the library.dll, there are no squiggles.
How about:
public static T As<T>(this object obj)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
}
Best way to add all base properties to derived item is use reflection in costructor. Try this code, without creating methods or instances.
public Derived(Base item) :base()
{
Type type = item.GetType();
System.Reflection.PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties)
{
try
{
property.SetValue(this, property.GetValue(item, null), null);
}
catch (Exception) { }
}
}
I disagree that it is not possible. You can do it like this:
public class Auto
{
public string Make {get; set;}
public string Model {get; set;}
}
public class Sedan : Auto
{
public int NumberOfDoors {get; set;}
}
public static T ConvertAuto<T>(Sedan sedan) where T : class
{
object auto = sedan;
return (T)loc;
}
Usage:
var sedan = new Sedan();
sedan.NumberOfDoors = 4;
var auto = ConvertAuto<Auto>(sedan);
This is how I solved this for fields. You can do the same iteration through properties if you want. You may want to do some checks for null etc. but this is the idea.
public static DerivedClass ConvertFromBaseToDerived<BaseClass, DerivedClass>(BaseClass baseClass)
where BaseClass : class, new()
where DerivedClass : class, BaseClass, new()
{
DerivedClass derived = (DerivedClass)Activator.CreateInstance(typeof(DerivedClass));
derived.GetType().GetFields().ToList().ForEach(field =>
{
var base_ = baseClass.GetType().GetField(field.Name).GetValue(baseClass);
field.SetValue(derived, base_);
});
return derived;
}
You can just serialize the base object to JSON and then deserialize it to the derived object.
No, see this question which I asked - Upcasting in .NET using generics
The best way is to make a default constructor on the class, construct and then call an Initialise method

JSON.Net preserve reference to static object

I am using a variation of the type object pattern (basically smart enums). Since this problem can best be explained with code I will jump right into it.
class Program
{
static void Main(string[] args)
{
Test C = Test.B;
Console.WriteLine(C == Test.B); //Returns true
string Json = JsonConvert.SerializeObject(C);
C = JsonConvert.DeserializeObject<Test>(Json);
Console.WriteLine(C == Test.B); //Returns false
}
}
public class Test
{
public int A { get; set; }
public Test(int A)
{
this.A = A;
}
public static Test B = new Test(100);
}
In this example Test is the type object, and instances of it are assigned to it's static field, B. In real life scenarios there would be multiple of these static fields, each representing a different type. When I serialize and deserialize, the test object is serialized purely as data. I understand why this is happening, but I don't know what to do about it. I would like to somehow preserve instances of Test being references to a static member in that class.
What you are looking for is support for the IObjectReference interface:
Implement this interface on objects that are references to a different object, which cannot be resolved until the current object is completely restored. During the fixup stage, any object implementing IObjectReference is queried for its real object and that object is inserted into the graph.
Unfortunately, Json.NET does not support this interface. However, it turns out to be quite easy to extend Json.NET to support this interface in cases where the type in question also implements ISerializable. This is a quite reasonable restriction given that, in practice, these two interfaces are often used together, as is shown in the documentation example.
First, introduce the following custom contract resolver:
public class ISerializableRealObjectContractResolver : DefaultContractResolver
{
// As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons.
// http://www.newtonsoft.com/json/help/html/ContractResolver.htm
// http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm
// "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance."
static ISerializableRealObjectContractResolver instance;
static ISerializableRealObjectContractResolver() { instance = new ISerializableRealObjectContractResolver(); }
public static ISerializableRealObjectContractResolver Instance { get { return instance; } }
public ISerializableRealObjectContractResolver()
: base()
{
this.IgnoreSerializableInterface = false;
}
protected override JsonISerializableContract CreateISerializableContract(Type objectType)
{
var contract = base.CreateISerializableContract(objectType);
var constructor = contract.ISerializableCreator;
contract.ISerializableCreator = args =>
{
var obj = constructor(args);
if (obj is IObjectReference)
{
var context = (StreamingContext)args[1];
obj = ((IObjectReference)obj).GetRealObject(context);
}
return obj;
};
return contract;
}
}
Now, modify your psuedo-enum Test type to implement ISerializable and IObjectReference:
public class Test : ISerializable, IObjectReference
{
readonly int a;
public int A { get { return a; } }
public Test(int A)
{
this.a = A;
}
public static readonly Test B = new Test(100);
#region ISerializable Members
protected Test(SerializationInfo info, StreamingContext context)
{
a = info.GetInt32("A");
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("A", A);
}
#endregion
#region IObjectReference Members
public object GetRealObject(StreamingContext context)
{
// Check all static properties to see whether the key value "A" matches. If so, return the static instance.
if (this.A == B.A)
return B;
return this;
}
#endregion
}
I also made the type immutable since that is clearly the requirement here.
Now your unit test will pass when using this contract resolver:
Test C = Test.B;
Console.WriteLine(C == Test.B); //Returns true
string Json = JsonConvert.SerializeObject(C, new JsonSerializerSettings { ContractResolver = ISerializableRealObjectContractResolver.Instance });
Console.WriteLine(Json);
C = JsonConvert.DeserializeObject<Test>(Json, new JsonSerializerSettings { ContractResolver = ISerializableRealObjectContractResolver.Instance });
Console.WriteLine(C == Test.B); //Still returns true
if (!object.ReferenceEquals(C, Test.B))
{
throw new InvalidOperationException("!object.ReferenceEquals(C, Test.B)");
}
else
{
Console.WriteLine("Global singleton instance deserialized successfully.");
}
Note however that Json.NET only supports the ISerializable interface in full trust.
Not possible by default, since the JSON deserializer doesn't care about existing references or static objects in your class.
You could compare for equality using a custom Equals method, but I guess that isn't what you want.
Don't serialize MyObj.Test, suppress that with an Ignore attribute. Instead, expose a property MyObj.TestID that returns MyObj.Test.ID. When TestID is set on MyObj, load the Test from a static collection keyed by the ID and set MyObj.Test to that value.
First of all, Type Object patterns are supposed to be used when you don't want to go through the inheritance hierarchy every time you define a new derivative of a base class. Having a type object attached as static didn't make sens to be at the first place to be honest. As you mentioned it's a variation Im not going to jump on that.
Looks like you want to be able to keep the reference even after deserialization using json.net.
Now if you want to do that you might want to have a look here.
Taking snippets from the aforementioned link as it's better to have a sample here as this is a StackOverflow answer. It should sustain even the provided link is dead.
Your first option is to use default PreserveReferencesHandling. The associated sample is following where you can reference same objects in a list and point to it. I don't think it actually keeps the old reference but sure helps when you have same things in a list and you dont want to go with your own IEqualityComparer or IEquatable implementations:
string json = JsonConvert.SerializeObject(people, Formatting.Indented,
new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
//[
// {
// "$id": "1",
// "Name": "James",
// "BirthDate": "1983-03-08T00:00Z",
// "LastModified": "2012-03-21T05:40Z"
// },
// {
// "$ref": "1"
// }
//]
List<Person> deserializedPeople = JsonConvert.DeserializeObject<List<Person>>(json,
new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
Console.WriteLine(deserializedPeople.Count);
// 2
Person p1 = deserializedPeople[0];
Person p2 = deserializedPeople[1];
Console.WriteLine(p1.Name);
// James
Console.WriteLine(p2.Name);
// James
bool equal = Object.ReferenceEquals(p1, p2);
// true
You can use IsReference attribute to control which properties would be kept as references:
[JsonObject(IsReference = true)]
public class EmployeeReference
{
public string Name { get; set; }
public EmployeeReference Manager { get; set; }
}
Now if you want to keep the exact same reference in the code for yourself (I don't think this is really a good design anyway, you might just need a Equality comparison method and be done with it), you need a custom IReferenceResolver defined here.
Furthermore, if you want to have something like that, look no further than Json.net's source code here.
It's an IdReferenceResolver that you can possibly use to preserve your object reference as Guid and possibly use it your way.
And if you want to know how DefaultReferenceResolver works you can have a look at this stackoverflow thread.

How do I copy an object by value instead of by reference in C#

I am writing a simple hillclimber algorithm in C# and am trying the following approach:
Get initial Solution
Copy solution to new object
Apply algorithm to copy
Compare obj value of initial solution with obj value of copy
if better - copy back into initial solution.
I am aware of the fact that this topic has been touched on in a previous post and tried implementing the suggestion there - Using the IClonable class. This is what I have tried:
My Solution Class:
class Solution : ICloneable
{
public Dictionary<Room, List<Patient>> solution { get; set; }
public Solution()
{
solution = new Dictionary<Room, List<Patient>>();
}
public object Clone()
{
return this.MemberwiseClone();
}
}
The algorithm:
public static void swap (Solution solution, Output input, Random rand)
{
Solution intSoln = new Solution();
intSoln = (Solution)solution.Clone();
//Moving things around in intSoln here
Console.WriteLine("new solution = " + objValue(intSoln, input));
Console.WriteLine("old solution = " + objValue(solution, input));
if (objValue(intSoln, input) < objValue(solution, input))
{
solution = (Solution)intSoln.Clone();
}
}
Looking at the printouts for the new and old solutions, they are always the same, which means that obviously the code still copies by reference. I am quite stuck and not sure what to do. Any help would be much appreciated.
MemberwiseClone will do a shallow copy, which means you'll get a new instance, whose fields have the same references as the initial object.
You want to do a deep copy instead. Here's a copy with one more level:
public object Clone()
{
var copy = new Solution();
foreach (var pair in solution)
copy.solution.Add(pair.Key, pair.Value);
return copy;
}
This will copy the dictionary, but its keys and values will still point to the same instances. So you may perform a deeper copy with something like that:
public object Clone()
{
var copy = new Solution();
foreach (var pair in solution)
copy.solution.Add(new Room(pair.Key), pair.Value.ToList());
return copy;
}
Or:
public object Clone()
{
var copy = new Solution();
foreach (var pair in solution)
copy.solution.Add(new Room(pair.Key), pair.Value.Select(i => new Patient(i)).ToList());
return copy;
}
You need to write some copy constructors for Room and Patient for that. Hopefully you get the idea.
You need to do a deep cloning of the type Solution. So Implement ICloneable interface:
public class Solution : ICloneable
{
public object Clone()
{
// creating a new dictionnary
}
}

Creating a non-static version of compiler-based "dictionary" where keys are types

There is a very easy trick which creates a dictionary-like structure where keys are types.
The structure acts like a Dictionary<Type, T?> where keys are Type objects and values are instances of the corresponding types.
This wonderful structure is as fast as just a variable or array since the "lookup" is only done once by the compiler/JITter and the proper value reference is compiled into your program.
public static class MyDict<T> {
public static T Value { get; set; }
}
You can work with that structure like this:
MyDict<string>.Value = MyDict<int>.Value.ToString();
The problem is that this "dictionary" is global. The only way to create different dictionaries is to create different classes.
How can create a similar (fastest "lookup", no boxing) non-static structure? (Without code generation.)
Simply said: I want to have multiple Dictionary<Type, object>-like objects without lookup costs, casting and boxing.
Here's an approach that extends the method described in the question:
public class TypeDict
{
public T Get<T>()
{
return MyDict<T>.Values[this];
}
public void Set<T>(T value)
{
MyDict<T>.Values[this] = value;
}
private static class MyDict<T>
{
public static Dictionary<TypeDict, T> Values { get; private set; }
static MyDict()
{
Values = new Dictionary<TypeDict, T>();
}
}
}
Now we can use the TypeDict like this:
void X()
{
var a = new TypeDict();
var b = new TypeDict();
a.Set<int>(1);
a.Set<double>(3.14);
a.Set("Hello, world!");
//Note that type inference allows us to omit the type argument
b.Set(10);
b.Set(31.4);
b.Set("Hello, world, times ten!");
Console.WriteLine(a.Get<int>());
Console.WriteLine(a.Get<double>());
Console.WriteLine(a.Get<string>());
Console.WriteLine();
Console.WriteLine(b.Get<int>());
Console.WriteLine(b.Get<double>());
Console.WriteLine(b.Get<string>());
}
Ark-kun is using generics to essentially generate unique types at compile time. With a generic type, any static members are unique to that specific closed generic type. This way it's processed as fast as a standard static member lookup.
The above usage is equivalent to something like this:
public static class MyDict_String
{
public static string Value { get; set; }
}
public static class MyDict_Int32
{
public static int Value { get; set; }
}
MyDict_String.Value = MyDict_Int32.Value.ToString();
AFAIK, types are "static" (in that you can't define more than one that way) so I don't know of a way to cheat around this and maintain the same performance of a statically compiled member lookup.
Your best bet otherwise (I think) is to create a generic instance type that wraps its own dictionary that uses System.Type for its keys and System.Object for its values to which you have to perform boxing/casting when inserting/retrieving values.
EDIT: Here's a simple implementation wrapping a dictionary:
public class MyTypedDict
{
private Dictionary<Type, object> Values = new Dictionary<Type, object>();
public T Get<T>()
{
object untypedValue;
if (Values.TryGetValue(typeof(T), out untypedValue))
return (T)untypedValue;
return default(T);
}
public void Set<T>(T value)
{
Values[typeof(T)] = value;
}
}
Thinking about it more, it might be possible to achieve a more property-like syntax using an ExpandoObject (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) through some tomfoolery, but I feel like this would be pretty abusive and I can only assume terribly prone to runtime errors. (plus it would afford you nothing at compile time)
EDITx2: If you really want to have different sets of values, you could nest it within another generic type:
public static class ValueSets<T>
{
public static class MyDict<U>
{
public static U Value { get; set; }
}
}
With usage like:
ValueSets<int>.MyDict<string>.Value = "Hello ";
ValueSets<bool>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<int>.MyDict<string>.Value + ValueSets<bool>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
But then the initial type int and bool in this case become "magical" and without meaning, plus you would need to provide a unique type per distinct set of values you'd like to use. Plus you could not pass it around and modify as an instance variable, rather it'd be statically accessible (so long as you have access to use the type T). So perhaps you could declare minimally visible types that are named with meaning and use those:
internal class MyFirstWords {}
internal class MySecondWords {}
ValueSets<MyFirstWords>.MyDict<string>.Value = "Hello ";
ValueSets<MySecondWords>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<MyFirstWords>.MyDict<string>.Value + ValueSets<MySecondWords>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
Regardless, I think this is quite wacky and I wouldn't recommend it.
A more complicated version. Don't know if it's closer:
Define a generic dictionary:
public class MyDictionary<T>
{
Dictionary<string, T> dict;
public MyDictionary()
{
dict = new Dictionary<string, T>();
}
public T this[string name]
{
get
{
if (dict.ContainsKey(name))
return dict[name];
else
return default(T);//or throw
}
set
{
dict[name] = value;
}
}
}
Then a repository to store those dictionaries:
public class MyRepository
{
List<object> repo;
public MyRepository()
{
repo = new List<object>();
}
public void Add<T>(string name, T value)
{
if (!repo.OfType<MyDictionary<T>>().Any())
repo.Add(new MyDictionary<T>());
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
dict[name] = value;
}
public T GetValue<T>(string name)
{
if (!repo.OfType<MyDictionary<T>>().Any())
return default(T);//or throw
else
{
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
return dict[name];
}
}
}
And finally you may use this repository:
MyRepository repo = new MyRepository();
repo.Add("A", 1);
repo.Add("B", 1);
int i = repo.GetValue<int>("A") + repo.GetValue<int>("B");
In this example, there is MyDictionary<T> boxing to object is left.
From the other side, if your are working with some certain types you may not use thie repository class at all. But utilize separate dictionaties.
MyDictionary<int> intDict = new MyDictionary<int>();
intDict["A"] = 1;
intDict["B"] = 2;
int i = intDict["A"] + intDict["B"];
However it's the same as working with
Dictionary<string, int> intDict = new Dictionary<string, int>();
So the MyRepository class may be edited to use Dictionary<string, T> instead of MyDictionary<T>.
#Konstantin's answer made me remember that there is actually a very fast lookup method - array indexing. This crude PoC code shows a variant of the required structure.
public class TypeDictionary {
static int _maxId = 0;
int _id;
static class Store<T>{
internal static List<T> Values = new List<T>();
}
public TypeDictionary() {
_id = _maxId++;
}
public T GetValue<T>() {
return Store<T>.Values[_id];
}
public void SetValue<T>(T value) {
while(Store<T>.Values.Count < _id) {
Store<T>.Values.Add(default(T));
}
Store<T>.Values[_id] = value;
}
}
This code can be used as follows:
var dict1 = new TypeDictionary();
dict1.SetValue("my string");
string result = dict1.GetValue<string>();
The problem with this solution is it's memory usage caused by the repository being not sparse. This also makes first time value setting more expensive.
Try this:
public class MyDictionary
{
List<object> values;
public MyDictionary()
{
values = new List<object>();
}
public T GetValue<T>()
{
return values.OfType<T>().FirstOrDefault();
}
public bool Add<T>(T value)
{
if (values.OfType<T>().Any())
return false;
else
{
values.Add(value);
return true;
}
}
}
and use it:
var md = new MyDictionary();
md.Add("!!!");
string s = md.GetValue<string>();
This class may store up to one value of type T. But there could corner cases with derived classes and interfaces I guess. You may check, if it suits your need, and probably modify it as you need, if it's close to what you need in general.
What you are looking for is impossible in C#. The language does not support a container that could store multiple objects of different types yet provides a look up method that does not involve casting, boxing or unboxing. You could accomplish something like this with macros in C++, or via a language like javascript where the structure of types can be changed at run-time.
The usage case you are describing fits quite closely with the purpose for which ConditionalWeakTable<TKey,TValue> was added to .NET 4.0. For the purpose you describe, you would include such a table in a static generic class, and then for every class object that's supposed to contain a reference to an item of a particular type you would store into that type's table a reference to object that's supposed to contain the item along with either a reference to the item, or else a reference to a simple item-holder object (note that entries in ConditionalWeakTable will evaporate when an object ceases to exist, but are otherwise immutable, so if you want a mutable association you'll need to create an object to hold it).
Building on #phoog's example with #supercat's suggestion
public class TypeDict
{
public T Get<T>() where T : class
{
T value;
InnerDict<T>.Values.TryGetValue(this, out value);
return value;
}
public void Set<T>(T value) where T : class
{
var cwt = InnerDict<T>.Values;
// lock+remove+add https://github.com/dotnet/coreclr/issues/4545
lock (cwt)
{
cwt.Remove(this);
cwt.Add(this, value);
}
}
private static class InnerDict<T> where T : class
{
public static ConditionalWeakTable<TypeDict, T> Values { get; private set; }
static InnerDict()
{
Values = new ConditionalWeakTable<TypeDict, T>();
}
}
}

Creating a copy of an object in C# [duplicate]

This question already has answers here:
How do you do a deep copy of an object in .NET? [duplicate]
(10 answers)
Closed 3 years ago.
Please have a look at the code below (excerpt from a C# book):
public class MyClass
{
public int val;
}
public struct myStruct
{
public int val;
}
public class Program
{
private static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
I understands it produces the output below:
objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40
The last two lines of the output I have no problem with, but the first two tell me that objectA and objectB are pointing to the same memory block (since in C#, objects are reference types).
The question is how do make objectB, a copy of objectA so that it points to a different area in memory. I understand that trying to assign their members may not work since those members may be references, too. So how do I go about making objectB a completely different entity from objectA?
You could do:
class myClass : ICloneable
{
public String test;
public object Clone()
{
return this.MemberwiseClone();
}
}
then you can do
myClass a = new myClass();
myClass b = (myClass)a.Clone();
N.B. MemberwiseClone() Creates a shallow copy of the current System.Object.
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.
The easiest way to do this is writing a copy constructor in the MyClass class.
Something like this:
namespace Example
{
class MyClass
{
public int val;
public MyClass()
{
}
public MyClass(MyClass other)
{
val = other.val;
}
}
}
The second constructor simply accepts a parameter of his own type (the one you want to copy) and creates a new object assigned with the same value
class Program
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = new MyClass(objectA);
objectA.val = 10;
objectB.val = 20;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.ReadKey();
}
}
output:
objectA.val = 10
objectB.val = 20
There's already a question about this, you could perhaps read it
Deep cloning objects
There's no Clone() method as it exists in Java for example, but you could include a copy constructor in your clases, that's another good approach.
class A
{
private int attr
public int Attr
{
get { return attr; }
set { attr = value }
}
public A()
{
}
public A(A p)
{
this.attr = p.Attr;
}
}
This would be an example, copying the member 'Attr' when building the new object.

Categories