Клонирование объекта с помощью отражения со специальными ограничениями - PullRequest
1 голос
/ 08 декабря 2010

предположим, объект с этими свойствами

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; }

Я могу скопировать prop1 и prop2 с помощью этого метода:

    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);
        }
    }

но я не знаю как скопировать каждый из prop3, prop4 и prop5 в другой объект !

Edit: я должен не Serialize объект! Я делаю эту работу, потому что у моего объекта большие данные, и с помощью этого трюка я могу скопировать некоторые данные.

Забавно сказать, если я скажу первоисточник этой проблемы! я использую EF как ORM и использую объекты данных в клиентах Silverlight через WCF. Когда я отправляю List<Foo> в WCF, он отправляет List<Foo> и данные об отношениях !! и клиенты умерли!

Ответы [ 2 ]

1 голос
/ 08 декабря 2010

Вы должны заменить следующую строку

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

С этими утверждениями

        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);
        }

Вы должны заменить IList на какой-нибудь подходящий интерфейс, возможно, ICollection или что-то еще, что будет работать с EntityCollection. У меня не было ничего для тестирования, поэтому я просто опубликовал этот пример.

1 голос
/ 08 декабря 2010

Что бы я сделал, это сделал бы объекты Serializable.Затем вы можете сериализовать объект в памяти и десериализовать его как новый клонированный объект.

У меня есть две функции:

    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);
    }

С вашим классом, подобным этому

[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; }
}

теперь вы можете сериализовать класс в память и создать из него клон.

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

    var ms = ToMemoryStream(myclass);

    var myNewObject = FromMemoryStream<MyClass>(ms);
    return myNewObject;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...