Клонирование объектов без сериализации

Я нашел множество решений здесь, в SO и других, которые касаются глубокого клонирования объекта посредством сериализации/десериализации (в память и обратно).

Это требует, чтобы классы, которые нужно клонировать, помечены [Serializable]. У меня есть мои классы (ну большинство из них), отмеченные [DataContract], потому что я использую DataContractSerializer для сериализации в XML.

Я представил только атрибут [Serializable] из-за необходимости глубокого клонирования некоторых из этих экземпляров класса. Однако теперь что-то случилось с сериализацией/десериализацией через DCS, потому что оно больше не работает - ошибки в ожидании использования другого элемента XML при десериализации. Если я удалю [Serializable], ошибки исчезнут.

Каковы мои варианты? Я просто хочу глубоко клонировать мои объекты как можно проще.

+6
источник поделиться
3 ответа

Это работает

    public static T DeepClone<T>(this T a)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            DataContractSerializer dcs = new DataContractSerializer(typeof(T));
            dcs.WriteObject(stream, a);
            stream.Position = 0;
            return (T)dcs.ReadObject(stream);
        }
    }
+10
источник

Сериализация и десериализация Json должны работать, но не требует, чтобы классы имели сериализацию аннотации.

public static T DeepCopy<T>(this T source)
{
    return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source));
}
+1
источник
другие ответы

Связанные вопросы


Похожие вопросы

Вот как это использовать:

var oldList = new List<int>();
var newList = oldList.Clone();

используя эти методы:

public static T Clone<T>(this T o) where T : new()
{
    return (T)CloneObject(o);
}
static object CloneObject(object obj)
{
    if (ReferenceEquals(obj, null)) return null;

    var type = obj.GetType();
    if (type.IsValueType || type == typeof(string))
        return obj;
    else if (type.IsArray)
    {
        var array = obj as Array;
        var arrayType = Type.GetType(type.FullName.Replace("[]", string.Empty));
        var arrayInstance = Array.CreateInstance(arrayType, array.Length);

        for (int i = 0; i < array.Length; i++)
            arrayInstance.SetValue(CloneObject(array.GetValue(i)), i);
        return Convert.ChangeType(arrayInstance, type);
    }
    else if (type.IsClass)
    {
        var instance = Activator.CreateInstance(type);
        var fields = type.GetFields(BindingFlags.Public |
                    BindingFlags.NonPublic | BindingFlags.Instance);

        foreach (var field in fields)
        {
            var fieldValue = field.GetValue(obj);
            if (ReferenceEquals(fieldValue, null)) continue;
            field.SetValue(instance, CloneObject(fieldValue));
        }
        return instance;
    }
    else
        return null;
}
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос