meysam_pro
meysam_pro

Reputation: 235

Cloning object via reflection with special constraints

suppose an object with this properties

public int? Prop1 { get; set; }
public string Prop2 { get; set; }
public EntityCollection<X> Prop3 { get; set; }
public EntityCollection<Y> Prop4 { get; set; }
public EntityCollection<Z> Prop5 { get; set; }

i can copy prop1 and prop2 with this method:

    public static void SetProperties(PropertyInfo[] fromFields,
                                             object fromRecord,
                                             object toRecord)
    {
        PropertyInfo fromField;

        if (fromFields == null)
        {
            return;
        }

        foreach (PropertyInfo t in fromFields)
        {
            fromField = t;

            fromField.SetValue(toRecord,
                               fromField.GetValue(fromRecord, null),
                               null);
        }
    }

but i don't know how copy each of prop3 , prop4 and prop5 to another object!

Edit: i should not Serialize object! I do this work because my object has big data and with this trick i can copy some data.

it is funny to say if i say original source of this problem! i use EF as ORM and use data objects in a Silverlight clients via WCF. When i send List<Foo> in WCF , it sends List<Foo> and its relationships data!! and clients died!

Upvotes: 1

Views: 516

Answers (2)

Akash Kava
Akash Kava

Reputation: 39916

You have to replace following line

  fromField.SetValue(toRecord, 
                           fromField.GetValue(fromRecord, null), 
                           null);

With these statements,

        if (typeof(IList).IsAssignableFrom(t.PropertyType))
        {
            IList fromList = fromField.GetValue(fromRecord, null);
            IList toList = fromField.GetValue(toRecord, null);
            foreach (var item in fromList)
                toList.Add(item);
        }
        else
        {
            fromField.SetValue(toRecord,
                               fromField.GetValue(fromRecord, null),
                               null);
        }

You have to replace IList to some suitable interface probably ICollection or something else that will work with EntityCollection, I didnt have anything to test so I just posted this example.

Upvotes: 1

jvanrhyn
jvanrhyn

Reputation: 2824

What I would do is make the objects Serializable. You can then Serialize the object in Memory and deserialize it as a new Cloned object.

I have these two functions:

    public static MemoryStream ToMemoryStream(object entity)
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();

        formatter.Serialize(ms, entity);
        return ms;
    }

    public static T FromMemoryStream<T>(Stream stream)
    {
        BinaryFormatter formatter = new BinaryFormatter();
        stream.Position = 0;
        return (T)formatter.Deserialize(stream);
    }

With your Class like this

[Serializable]
public class MyClass 
{
    public int? Prop1 { get; set; }
    public string Prop2 { get; set; }
    public EntityCollection<X> Prop3 { get; set; }
    public EntityCollection<Y> Prop4 { get; set; }
    public EntityCollection<Z> Prop5 { get; set; }
}

you can now serialize the class to Memory and Create a clone from that.

public MyClass Clone()
{
    var myclass = new MyClass();
    /* Do Some init */

    var ms = ToMemoryStream(myclass);

    var myNewObject = FromMemoryStream<MyClass>(ms);
    return myNewObject;
}

Upvotes: 1

Related Questions