3

I have the following classes:

public partial class AuthorizationSetObject
{
   public AuthorizationObjectList AuthorizationObjects { get; set; }
}

public partial class AuthorizationObject
{
   public string Text { get; set; }
}

public partial class AuthorizationObjectList : List<AuthorizationObject>
{
}

I need now a deep copy of AuthorizationSetObject. How can I do this?

I tried it like this:

public static bool CopyProperties(object source, object target)
{
    var customerType = target.GetType();
    foreach (var prop in source.GetType().GetProperties())
    {
        var propGetter = prop.GetGetMethod();
        if (propGetter != null)
        {
            PropertyInfo pi = customerType.GetProperty(prop.Name);
            if (pi != null)
                {
                var propSetter = pi.GetSetMethod();
                if (propSetter != null)
                {
                    var valueToSet = propGetter.Invoke(source, null);
                    propSetter.Invoke(target, new[] { valueToSet });
                }
            }
        }
    }
    return true;
}

The problem is, that the AuthorizationObjectList is not a real deep copy. If I change the property "Text" from the target after the deep copy, the "Text" from source is changed a well.

Probably I need an implementation like "pi.PropertyType.BaseType.IsGenericType" and then do something else...but what??

Does anybody has an idea?

Piotr Kula
  • 9,597
  • 8
  • 59
  • 85
Marc
  • 137
  • 3
  • 10
  • 4
    http://stackoverflow.com/questions/13244161/how-to-keep-a-generic-list-unmodified-when-its-copy-is-modified/13244309#13244309 – Hardrada Nov 11 '12 at 09:40
  • 1
    The typical solution for a deep copy in languages that don't provide value semantics is to serialize the object and then deserialize it in another. – Alex Nov 11 '12 at 09:41
  • 1
    Because the AuthorizationSetObject is you own class, you can implement IClonable interface. – Hamlet Hakobyan Nov 11 '12 at 09:49
  • possible duplicate of [How do I clone a generic list in C#?](http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c) – Matthew Strawbridge Nov 11 '12 at 10:01
  • You could just use `struct` instead instead of `class`.... because they are by value and not by reference.I suggest you research the differences in depth as this a core C# principle you should know. You are over engineering your problem and making it look like the solution is highly complex. There usually are reason why the framework does not implement certain things, like deep copy. Probably because you may be in a code smell situation and just need to refactor a bit. – Piotr Kula Sep 19 '18 at 08:08

1 Answers1

0

The comments posted to your question are all pointing to the right direction. The problem is, that in the line

propSetter.Invoke(target, new[] { valueToSet });

valueToSet is a reference which means that you add a reference to the same object to your list. Now the ICloneable comes into place. If the type of valueToSet implements ICloneable you could use

propSetter.Invoke(target, new[] { valueToSet.Clone() });

instead, which will generate a new deep copy of this instance.

Alexander Schmidt
  • 5,631
  • 4
  • 39
  • 79
  • Thank you very much for your answer. How does it work exactly? valueToSet is of type object and doesn't have a known clone method. Is there a cast to ICloneable needed? – Marc Nov 12 '12 at 07:03
  • Can you use something more specialized which is implemented by you? – Alexander Schmidt Nov 12 '12 at 17:55