6

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.

4
  • 2
    data.Info is null. That's why you are getting the exception. Commented Sep 26, 2012 at 12:53
  • How does it pass if(ReferenceEquals(obj, null)) check then? Commented Sep 26, 2012 at 12:55
  • Interesting. What is typeof(T) and typeof(T).IsClass? Commented Sep 26, 2012 at 13:02
  • typeof(T).IsClass is true, Name = "Info" FullName = "Project.Entities.Info", so it get to the check and passes it. Commented Sep 26, 2012 at 13:12

3 Answers 3

10

What about

var clone = JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));
Sign up to request clarification or add additional context in comments.

Comments

5

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".

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.