Cloning dynamic object in c# - c#

I have a problem cloning dynamic object with the code like this:
public void Execute(IPrepareData entity)
{
try
{
dynamic data = entity.Primary as dynamic;
data.PreviousInfo = deepClone(data.Info);
}
catch (Exception ex)
{
data.Errors.Add(ex.Message);
}
}
private static T deepClone<T>(T obj)
{
if (typeof(T).IsClass || typeof(T).IsArray)
{
if (ReferenceEquals(obj, null))
{
return default(T);
}
}
using (var memoryStream = new MemoryStream())
{
BinaryFormatter fieldFormatter = new BinaryFormatter();
fieldFormatter.Serialize(memoryStream, obj);
memoryStream.Position = 0;
return (T)fieldFormatter.Deserialize(memoryStream);
}
}
dynamic data;
I don't know the structure of entity in advance (only that it will contain Info, and I don't know the structure of info) and that it won't be marked serializable. I need to copy this info to previous info section of entity.
Result of execution of this code is 'Object reference not set to an instance of an object' on fieldFormatter.Serialize line.
How can I check if it is an instance of an object?
There might be (most probably will be) circular references, so I am not trying reflection as I am not sure how to deal with that. Also speed is not an issue.

What about
var clone = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));

If you don't know that the data will be marked serializable, then you can't rely on using BinaryFormatter.
If the object is likely to have circular references, a lot of other serializers are out of the question.
If we assume it is the general case of dynamic (and not just ExpandoObject), then there is no way of getting information about the members, since they can be invented as they are queried.
Basically, this scenario *has no good answer. There is no magic way to just deep clone "a thing".

I have been using JSON.net for serializing user defined types and it has been working well.
There are flags to ignore null properties, or it will by default save as
{propname: 'undefined'}
I know you mentioned speed as not being an issue, but the serializer is very fast.
Here is the nuget package.

Related

Automate a copy constructor in C#

I'm trying to find the best way to make copies of a pretty big class. It has somewhere around 80 properties. I could of course code them all in a normal copy constructor, but I'm not sure how nice that would look in code.
So I'm thinking... Is there a way to iterate through the properties of obj A and assign the the values to the corresponding properties of obj B?
This queston is marked as a duplicate, but it is not. My question is not how to make a deep copy, the question is how to iterate through the properties and thus make a normal copy constructor with many properties.
Here is one way:
public static T DeepClone<T>(T original)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "original");
}
if (ReferenceEquals(original, null))
{
return default(T);
}
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Clone)
};
formatter.Serialize(stream, original);
stream.Position = 0;
return (T) formatter.Deserialize(stream);
}
}
This is adapted from CLR via C# by Jeffrey Richter.
You use it like this:
var objB = DeepClone(objA);
The type must be serializable for this to work, though.

Implementing IFormatter recursively

I'm trying to implement a custom formatter using the .NET IFormatter interface.
After a couple of hours of search, I just found a very basic sample which unfortunately doesn't include recursion. I also tried with Reflector to look at BinaryFormatter and SoapFormatter, but they are rather complex.
My question is:
Should I implement recursion myself, or there's something I've missed in FormatterServices?
Following my code:
public void Serialize(Stream serializationStream, object graph)
{
// Get fields that are to be serialized.
MemberInfo[] members = FormatterServices.GetSerializableMembers(graph.GetType(), Context);
// Get fields data.
object[] data = FormatterServices.GetObjectData(graph, members);
// Write class name and all fields & values to file
StreamWriter sw = new StreamWriter(serializationStream);
string accumulator = string.Empty;
for (int i = 0; i < data.Length; ++i)
{
// Skip this field if it is marked NonSerialized.
if (Attribute.IsDefined(members[i], typeof(NonSerializedAttribute)))
continue;
FieldInfo field = (FieldInfo)members[i];
if (field.FieldType.IsPrimitive)
{
}
else //TODO: What should I do here?
}
sw.Close();
}
If by recursion you mean traversing through the object tree then yes, it up to you when you implement your own IFormatter.
Simply check if the value of the property is not null and if it is implementing IFormatter interface. If it is then just call it and use the value it returns.
If not then it is up to you again: you may throw an exception saying that IFormatter must be implemented, or just fall-back to some sort of default formatter (XML or Binary one).
The recursion per se is tricky. When, let's say, the object references itself, you need to be smart enough to handle this situation and not to end up with the infinite loop:
public class A {
public object SomeProperty { get; set; }
}
var a = new A();
a.SomeProperty = a;
There are a number of tricky aspects in implementing formatters, like what if two properties are actually reference the same object? Will you serialize/format it twice or just once and keep the information about these references somehow?
You don't probably need this if you want just one-way serialization, but if you want to be able to restore the object it might be important...

C# Cloning- working with nonserializable data types

I've hit a bit of a stumbling block in my quest to implement object cloning in my game engine.
My goal is to have a cloning system that I don't have to maintain on a class by class basis, unless the class needs special treatment.
My game engine's setup revolves around a base class Object2D, which contains some image data in the form of a Texture2D. Well, the long story is that it contains a DisplayObject, which contains a Sprite, which contains a Texture2D. Naturally, other classes e.g. "Player", "Enemy", "Projectile", etc. all derive from the basic Object2D class.
Unfortunately, I found that XNA's Texture2D class isn't serializable. Which makes sense, as we wouldn't want to be duplicating texture data in memory all willy-nilly.
This creates a dilemma for me. I was using deep cloning methods to clone objects, but since it's not serializable I can no longer do that. I tried just marking the Texture2D [NonSerializable], but this causes problems when I try to draw, as the clone's texture is null. I wasn't able to find any hidden trick that allows me to assign it after cloning (like some sort of an "onClone()" method).
So I figured I'd do this. For objects that can't be deep cloned generically, I implement a "SpecialClone" interface that allows me to specify a clone() method.
However, because the class that can't be deep cloned generically is the base class, I'm right back where I started: writing a clone method on a class by class basis.
public static T clone<T>(T obj) {
if (obj == null) return default(T);
if (!typeof(T).IsSerializable) {
if (obj is SpecialClone) {
object obj2 = ((SpecialClone)obj).clone();
return (T)obj2;
} else {
throw new ArgumentException("Object type is not serializable.", "obj type: " + Type.GetTypeHandle(obj));
}
} else {
return deepClone(obj);
}
}
public static T deepClone<T>(T obj) {
if (obj == null) return default(T);
if (typeof(T).IsSerializable) {
try {
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
T obj2 = (T)bf.Deserialize(ms);
ms.Dispose();
return obj2;
}
catch (Exception e) {
Console.WriteLine(e);
return default(T);
}
} else {
Console.WriteLine(typeof(T) + " is not marked as serializable!");
return default(T);
}
}
I'm not the best with C# yet, so I'm not sure if I'm missing some trick that I can use or if this is really how I'll have to deal with this problem. The main purpose of this cloning is for Object2D types, so it'd be a real pain to have to write clone methods for each new subclass I make.
Is there any way to avoid this?
you do not want to clone the Texture2d.
You should consider Textures (and models, wave files, etc...) as a "shared asset", it could be many megabytes in size. Cloning that would leave you in a world of out-of-memory hurt real quick (in addition to the time it takes to clone)
your ideal solution: instead, you want to clone the reference.
if each of your Object2D instances are not meant to be serialized, then you can just reference-assign the same Texture2D to the various Object2D's. If you want to serialize, then pass the Texture2D reference, as mentioned, plus copy a string textureFilePath, which is what gets serialized.
Also note that this is what XNA's ContentManager does for you automatically: if you request "myPic.xnb" 10 times, it will automagically load it once and return that reference to you 10 times.
ICloneable (.Net core interface) is better than SpecialClone. You could also implement the ISerializable interface allong with a protected constructor
ctor(SerializationInfo info, StreamingContext context).
This would allow for custom serialization (SerializationInfo is a bag that can hold anything you need to deserialize the object later and is passed to you in the protected constructor).
So thats all there is to know about serialization. If you can do it or not depends on whether there is something in the non-serializable class (i.e. a key, a filename, a buffer) which you can use on deserialization to recreate that object.

What is the most appropriate way to handle corrupt input data in a C# constructor?

I'm reading data in from a file and creating objects based on this data. The data format is not under my control and is occasionally corrupt. What is the most appropriate way of handling these errors when constructing the objects in C#?
In other programming languages I have returned a null, but that does not appear to be an option with C#.
I've managed to figure out the following options, but I would appreciate advice from more experienced C# programmers:
Option 1. Read the file inside the constructor and throw an exception when the source data is corrupt:
try
{
obj = Constructor(sourceFile);
... process object ...
}
catch (IOException ex)
{
...
}
Option 2. Create the object, then use a method to read data from the source file:
obj = Constructor();
obj.ReadData(sourceFile);
if (obj.IsValid)
{
... process object ...
}
or possibly throw exceptions on error:
obj = Constructor();
try
{
obj.Read(sourceFile);
... process object ...
}
catch
{
...
}
Option 3. Create the object using a static TryParse method:
if (ObjClass.TryParse(sourceFile, out obj))
{
... process object ...
}
and if so, should I implement option 3 internally using option 1?
public static bool TryParse(FileStream sourceFile, out ObjClass obj)
{
try
{
obj = Constructor(sourceFile);
return true;
}
catch (IOException ex)
return false;
}
I would do something along the lines of option 3):
class ObjectClass
{
protected ObjectClass(...constructor parameters your object depends on...)
{
}
public static ObjectClass CreateFromFile(FileStream sourceFile)
{
.. parse source file
if (parseOk)
{
return new ObjectClass(my, constructor, parameters);
}
return null;
}
}
And then use it like this:
ObjClass.CreateFromFile(sourcefile);
In general the constructor should take as parameters all properties which essentially define the class. Doing heavyweight calculations (like parsing a file) is best left to factory methods as it is usually not expected for the constructor to perform complex and potentially long running tasks.
Update: As mentioned in comments a better pattern is this:
public static ObjectClass CreateFromFile(FileStream sourceFile)
{
.. parse source file
if (!parseOk)
{
throw new ParseException(parseErrorDescription);
}
return new ObjectClass(my, constructor, parameters);
}
public static bool TryCreateFromFile(FileStream sourceFile, out ObjectClass obj)
{
obj = null;
.. parse source file
if (!parseOk)
{
return false;
}
obj = new ObjectClass(my, constructor, parameters);
return true;
}
I would not put anything into a constructor that might throw an exception - except for if something goes really wrong.
If your constructor has a possible return value other than a valid object, you should encapsulate it.
The safest way would probably be to create a factory method (public static function in the class that accepts a file reference and returns a new instance of the class or null). This method should first validate the file and its data and only then create a new object.
If the file data has a simple structure, you can first load it into some local variable and construct the object with this data.
Otherwise, you can still decide - inside of your factory method - if you rather want to try / catch the construction or use any of the other points mentioned above.
Both Options #1 and #3 are good choices and common in the .Net framework. It's also common to provide both for the same type. Consider Int32.TryParse and Int32.Parse. Providing both gives developers a bit more flexibility without detracting from the integrity of the type.
I would strongly advise you to avoid #2. This pattern forces both the type author and type consumer to handle instances of the type in multiple states
Constructed but not fully initialized
Initialized and valid
Initialized and invalid
This puts a burden on every consumer to deal with instances being in all different states (even if the response is to just throw). Additionally it forces a non-standard pattern on consumers. Developers have to understand your type is special and that it needs to be constructed and then initialized. It goes against the standard way objects are created in .Net.
Note for #3 though I would approach it a bit different. The exception form should be implemented in terms of the try form. This is the standard pattern when providing both options to the user. Consider the following pattern
class MyType {
struct ParsedData {
// Data from the file
}
public MyType(string filePath) : this(Parse(filePath)) {
// The Parse method will throw here if the data is invalid
}
private MyType(ParsedData data) {
// Operate on the valid data. This doesn't throw since the errors
// have been rooted out already in TryParseFile
}
public static bool TryParse(string filePath, out MyType obj) {
ParsedData data;
if (!TryParseFile(filePath, out data)) {
obj = null;
return false;
}
obj = new MyType(data);
return true;
}
private static ParsedData Parse(string filePath) {
ParsedData data;
if (!TryParseFile(filePath, out data)) {
throw new Exception(...);
}
return data;
}
private static bool TryParseFile(string filePath, out ParsedData data) {
// Parse the file and implement error detection logic here
}
}
From Microsoft Constructor Design Guidelines (MSDN),
Do throw exceptions from instance constructors if appropriate.
Constructors should throw and handle exceptions like any method. Specifically, a constructor should not catch and hide any exceptions that it cannot handle.
Factory Method is not the right way to approach this problem. See Constructors vs Factory Methods
From Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries
5.3 Constructor Design
Consider using a static factory method instead of a constructor if the
semantics of the desired operation do not map directly to the construction
of a new instance, or if following the constructor design guidelines
feels unnatural.
Do throw exceptions from instance constructors if appropriate.
.NET BCL implementations do throw exceptions from constructors
For example, the List Constructor (Int32), throws an ArgumentOutOfRangeException when the capacity argument of the list is negative.
var myList = new List<int>(-1); // throws ArgumentOutOfRangeException
Similarly, your constructor should throw an appropriate type of exception when it reads the file. For example, it could throw FileNotFoundException if the file does not exist at the specified location, etc.
More Information
Code Contracts
Throwing exceptions from constructor in .Net
Throwing ArgumentNullException in constructor?
Constructor parameter validation in C# - Best practices
All these solutions work, but as you said, C# doesn't allow to return null from a constructor. You either get an object or an exception. Since this is the C# way to go, I wouldn't choose option 3, because that merely mimics that other language you're talking about.
Lots of people [edit] among which is Martin, as I read in his answer :) [/edit] think it is good to keep your constructor clean and small. I'm not so sure about that. If your object is of no use without that data, you could read in the data in the constructor too. If you want to construct the object, set some options, and then read the data (especially with the possility to try again if the read fails), a separate method would be fine as well. So option 2 is a good possibility too. Even better maybe, depending mainly on taste.
So as long as you don't choose 3, choose the one you're the most comfortable with. :)

Any automated way to clone a data object?

I have a bunch of simple data objects of different types (all properties are writable, no hidden state). Is there any automated way to clone such objects?
(yes, I know the way to clone them manually. Just don't want to ^_^)
Serialize them in a (memory)stream and deserialize them back.
Serializing and deserializing would clone your object. Of course, the object would need to be serializable.
public static T Clone<T>(T source)
{
IFormatter formatter = new BinaryFormatter();
using (Stream stream = new MemoryStream())
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
The best approach is to implement IClonable interface in all objects but in case that objects developed not by you its not appropriate way for you.
The second way ( most universal in my opinion) is to use reflection:
public T CommonClone<T>(T Source)
{
T ret = System.Activator.CreateInstance<T>();
Type typeDescr = typeof(T);
if (typeDescr.IsClass != true)
{
ret = Source;
return ret;
}
System.Reflection.FieldInfo[] fi = typeDescr.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
for (int i = 0; i < fi.Length; i++)
{
fi[i].SetValue(ret, fi[i].GetValue(Source));
}
return ret;
}
The code above will copy both public and private fields. If you need to cope only public ones, just remove BindingFlags.NonPublic from GetFields method call.
This way not specified any limitation on objects which can use. Its working both for classes and structures.
using System.Web.Helpers;
public static T Clone<T>(T source)
{
return Json.Decode<T>(Json.Encode(source));
}
You might see this
Deep cloning objects
Take a look at second answer. I use it all the time and it works great. The only drawback of this solution is the fact that class must be serializable

Categories