Сохранение определения класса C # - PullRequest
1 голос
/ 29 ноября 2010

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

Я использую [Сериализуемый] тег и 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 () на нем - и функция работает точно так же, как это было до того, как патч удалил класс из системы


Есть ли способ сделать это без хитрости отражения / выброса?

Ответы [ 3 ]

3 голосов
/ 29 ноября 2010

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

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

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

0 голосов
/ 29 ноября 2010

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

0 голосов
/ 29 ноября 2010

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

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

...