2010-11-29 1 views
1

Есть ли способ сохранить полное определение класса для объекта C# в хранилище файлов/данных?Сохранение определения класса C#

Я использую [Serializable] тег и интерфейс ISerializable сделать это уже, но оба они опираются на определение объекта, находящегося в сборке во время выполнения.

Что я ищу это решение по следующему сценарию:

1) Пользователь создает объект MyClass в моем программном обеспечении и сохраняет его

Для этого примера, MyClass является автономным объектом, который не полагается на какой-либо другой класс в системе:

т.е. это может быть весь определенный Тион:

public class MyClass 
{ 
    public int MyProperty { get; set; } 
    public void DoSomething() { /* do something, like Console.Write(""); */ } 
} 

2) Мы выпустить патч, который удаляет MyClass из системы

3) Пользователь загружает сохраненные MyClass шаг 1 и вызывает DoSomething() на нем - и функция работает точно так же, как и до того, как патч удалил класс из системы


Можно ли это сделать без отражения/испускания обмана?

+0

Вы уверены, что не хотите определять интерфейсы? –

+1

Это кажется очень надуманным. –

+0

Воля, я согласен. Часто, когда небольшие компании-разработчики программного обеспечения «обновляют» свой продукт, они делают это с оговоркой, что «ваши старые вещи, скорее всего, больше не будут работать». Я пытаюсь получить свой торт и съесть его, сказав им: «Ваш старый материал, безусловно, все еще будет работать, мы просто его не поддерживаем». – Michael

ответ

3

Нет, это не сработает без определения типа. То, что вы пытаетесь сделать, на самом деле сберечь код (в противном случае, как бы работало DoSomething?) - это то, что делает компилятор для вас. Обычная сериализация никогда не будет работать для вас здесь.

Итак, если вам нужно сохранить поведение, а также состояние, вам нужно либо сохранить исторический код, использовать какой-то тип отражения, испускать обман, чтобы сохранить определение типа как загружаемую сборку, либо использовать динамические трюки программирования, которые обрабатывать данные как исполняемый код.

Когда я раньше делал сериализацию с версией, у меня обычно есть пользовательская логика сериализации и атрибут «версия» для объекта - с помощью этого я могу создать тип, который я переместил и переименовал, - скажем SomeClass - Archive.SomeClassV3. Вы можете использовать Version Tolerant Serialization для этого, но я предпочитаю реализовать ISerializable и использовать прокси сериализации, если это необходимо. (Ну, на самом деле я предпочитаю вообще избегать этой проблемы!)

0

Ну, вы можете сохранить все эти сериализуемые классы в своих собственных DLL, упаковать библиотеки DLL с приложением и загружать библиотеки во время выполнения. Таким образом, даже если вы удалите классы из последней версии приложения, загруженные библиотеки DLL будут работать.

Это похоже на страшный подход, хотя ... теперь у вас есть клиенты, которые запускают древний код, который больше не существует в вашем репозитории управления версиями.Как вы должны отлаживать это?

+0

Согласен, это определенно страшная идея. Я просто пытаюсь «думать за пределами коробки», если хотите. – Michael

+0

Это все еще в вашем реестре исходного кода, контроль источника навсегда.

0

Вы говорите о не сериализации класса, а о процедурной сериализации (или методе -, не имеет значения). Но в отличие от сериализации свойств, это должно содержать MSIL-код, который запускается, когда вам это нужно. Поэтому вы должны каким-то образом перевести его в бин-код, а затем запустить Assembly.Load, например. Я думаю, это не простой способ сделать это. Итак, если это возможно - сохраните реализацию MyClass в отдельной dll или в виде строки (на языке C#) для дальнейшей компиляции и выполнения путем отражения.