Сохраните объект, который не отмечен как сериализуемый

Я должен сохранить объект, который не отмечен с сериализуемым атрибутом. Объект из сторонней библиотеки, которую я не могу изменить.

Я должен сохранить его в сохранять месте, как, например, файловая система, таким образом, оптимальное решение состояло бы в том, чтобы сериализировать объект в файл, но так как это не отмечено как сериализуемое, который не является прямым решением.

Это - довольно сложный объект, который также содержит набор других объектов.

Вы парни кто-либо ввел о том, как решить это? Код никогда не будет работать в продуктивной среде, таким образом, я соглашусь почти с любым решением и производительностью.

22
задан lasseeskildsen 7 April 2010 в 20:28
поделиться

4 ответа

XmlSerializer может быть полезным первым делом, которое стоит попробовать, если типы являются общедоступными и т. Д.

Если это не удается, v2 protobuf-net (в процессе, вам нужно собрать из исходного кода, но я могу help) работает с объектами без атрибутов, поэтому идеально подходит для типов, находящихся вне вашего контроля - вам просто нужно указать ему, что включить (через DSL). Код v2 не завершен, но он охватывает наиболее распространенные сценарии, включая коллекции и т. Д. (Незавершенная работа - это в основном обратные вызовы и перечисления).

9
ответ дан 29 November 2019 в 05:43
поделиться

Это один из способов сделать это:

http://www.codeproject.com/KB/dotnet/Surrogate_Serialization. aspx

вот ссылка на msdn, показывающая это:

http://msdn.microsoft.com/en-us/magazine/cc188950.aspx

3
ответ дан 29 November 2019 в 05:43
поделиться

Вы могли бы написать рекурсивный метод, который запускал бы граф объекта, используя отражение для сохранения объекта ... Вернуть его обратно может быть намного сложнее. Кто знает, содержит ли какой-либо из этих объектов ссылки на неуправляемые или системные ресурсы. Если бы я сделал что-нибудь такое, я бы выбрал метод .GetFields (...) для типа.

Еще одна идея ...

Если вы делаете это только для ускорения разработки, почему бы не обернуть их классы своими собственными классами адаптеров. Это позволит вам заменить сторонние библиотеки вашими собственными упрощенными фиктивными классами и даст больше шансов для замены и повторного использования позже.

Как бы то ни было ... Это было проще, чем я думал. (Хотя это работает ... пожалуйста, подумайте о том, чтобы обернуть сторонние классы.)

public static class Tools
{
    public static XElement AsXml(this object input)
    {
        return input.AsXml(string.Empty);
    }
    public static XElement AsXml(this object input, string name)
    {
        if (string.IsNullOrEmpty(name))
            name = input.GetType().Name;

        var xname = XmlConvert.EncodeName(name);

        if (input == null)
            return new XElement(xname);

        if (input is string || input is int || input is float /* others */)
            return new XElement(xname, input);

        var type = input.GetType();
        var fields = type.GetFields(BindingFlags.Instance |
                                    BindingFlags.NonPublic)
                         .Union(type.GetFields(BindingFlags.Instance |
                                               BindingFlags.Public));

        var elems = fields.Select(f => f.GetValue(input)
                                        .AsXml(f.Name));

        return new XElement(xname, elems);
    }
    public static void ToObject(this XElement input, object result)
    {
        if (input == null || result == null)
            throw new ArgumentNullException();

        var type = result.GetType();
        var fields = type.GetFields(BindingFlags.Instance |
                                    BindingFlags.NonPublic)
                         .Union(type.GetFields(BindingFlags.Instance |
                                               BindingFlags.Public));

        var values = from elm in input.Elements()
                     let name = XmlConvert.DecodeName(elm.Name.LocalName)
                     join field in fields on name equals field.Name
                     let backType = field.FieldType
                     let val = elm.Value
                     let parsed = backType.AsValue(val, elm)
                     select new
                     {
                         field,
                         parsed
                     };

        foreach (var item in values)
            item.field.SetValue(result, item.parsed);            
    }

    public static object AsValue(this Type backType,
                                      string val,
                                      XElement elm)
    {
        if (backType == typeof(string))
            return (object)val;
        if (backType == typeof(int))
            return (object)int.Parse(val);
        if (backType == typeof(float))
            return (float)int.Parse(val);

        object ret = FormatterServices.GetUninitializedObject(backType);
        elm.ToObject(ret);
        return ret;
    }
}
public class Program
{
    public static void Main(string[] args)
    {
        var obj = new { Matt = "hi", Other = new { ID = 1 } };
        var other = new { Matt = "zzz", Other = new { ID = 5 } };
        var ret = obj.AsXml();
        ret.ToObject(other);
        Console.WriteLine(obj); //{ Matt = hi, Other = { ID = 1 } }
        Console.WriteLine(other); //{ Matt = hi, Other = { ID = 1 } }
    }
}
5
ответ дан 29 November 2019 в 05:43
поделиться

Не знаю, не слишком ли это для вашего использования, но в последнее время я играю с db4o. Он сохранит любой объект, просто вызовите IObjectContainer.Store(object), и он легкий и основанный на файлах. Не требует установки.

У меня пока не было никаких проблем с ним.

2
ответ дан 29 November 2019 в 05:43
поделиться
Другие вопросы по тегам:

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