Короче, я явно переработал.
Последние три дня писал сериализацию функтора для юнити.
Сегодня проснулся от ночных кошмаров.
Снилось будто я в департаменте США работаю, и короче такой говорю ребятам: «ФУНКТОРЫ НУЖНО СЕРИАЛИЗОВАТЬ ПОКА НЕ ПОЯВИЛИСЬ ПРОБЛЕМЫ».
Ну и всё в таком духе. Меня никто не слушал. Мол что это еще за функторы такие, будем еще на них время тратить. Фигня какая-то.
И вот, функторы стали нападать. Все бегали в панике и не знали, что делать. И я весь остаток сна всем твердил, мол «я же говорил, никто меня не слушал!».
И джен псаки такая на брифинге «мы держим ситуацию под контролем». Ну а сами знаем, что ничего не под контролем. Функторы то не сериализованы.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
20
10 лет назад
Отредактирован Mihahail
0
Ну сериализуем объект-функтор и всё. Или так нельзя?
Если что, сорри за нубские вопросы, сишарп систематически не изучал.
А тебе похорошело. Видимо после изучения.
0
27
10 лет назад
Отредактирован Devion
0
Mihahail, функтор состоит из 85 подвидов выражений, каждое из которых имеет собственные подвиды. И каждый случай надо разобрать и закрепить/создать под него сериализатор. Потому так долго и пишется сериализация.
0
20
10 лет назад
0
0
27
10 лет назад
Отредактирован Devion
0
Mihahail, неа. Она описывает те классы, которые помечены атрибутом Serializable и некоторые другие. Такие классы неплохо и сами сериализуются (нативно сама юнити тоже их умеет хранить).
Если кратко сериализация Unity умеет сохранять:
  • классы с атрибутом Serializable, с потерей ссылки при ребилде (будут вести себя как структуры, типа это значения, и плодить экземпляры)
  • классы, наследуемые от Object, с сохранением ссылочности
  • массивы, списки
  • стандартные типы int, float, string, bool и так далее
Ну вот тип выше, статья, касается всего кроме наследников Object. Просто преобразует их в byte[] и радуется.
А сериализаторы юзаются для классов, которые не подходят под эти параметры и обнуляются при ребилде
Среди таких - MethodInfo, Type и прочие.
Потому что по сути они отражают объекты, существующие в этой сессии сборки. При ребилде такие могут быть скажем удалены или еще чего-нибудь.
Соответственно бинарная сериализация тоже на такие объекты не действует. Она их просто не упакует, выпадет с еррором, ибо они не описаны для таких операций.
Но у таких объектов обычно есть способ их поднятуть.
Скажем,
Type подтягивается через Type.GetType(x)
MethodInfo через type.GetMethodInfo(параметры);
Соответственно если сохранять эти данные, с помощью которых можно извлечь текущую версию объекта, то можно и описать их сериализацию.
Далее такие красоты как кеширование делают свое дело.
Соответственно на примере выше ты можешь заметить например, что для извлечения метода например нужно сохранить тип, который тоже не сериализуем. Соответственно это говорит о том что сериализаторы связаны друг с другом тесно.
И в итоге:
  • Сериализатор сериализуем, сериализует свои поля
  • Сериализатор имеет методы для сохранения и загрузки нужных нам данных
  • Они кешируются и обрабатываются при первом вызове.
Для лямбда выражений нужно такие вещи сделать для каждого наследующего от класса Expression и всех вспомогательных классов, которые сохраняются в этих выражениях и имеют такие же проблемы.
Вот и весь профит.
Кстати на byte[] тоже строится один сериализатор - для типа object. Unity в дефолте не умеет обрабатывать этот тип, но мы можем самостоятельно конвертить данные в byte[] и если эти данные можно бинарно хранить, они соответственно будут там храниться. Ну и вкупе с сериализатором UnityEngine.Object они представляют "любой сериализуемый тип Unity".
Сами сериализаторы так же реализуются через атрибут, либо наследником от ScriptableObject.
Даже хз куда еще проще. Мы просто раскладываем несериализуемые объекты на части, которые можем сериализовать, а потом достаем новый экземпляр объекта при перезапуске сборки.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.