Сумки для свойства
Комплект свойств — это сопутствующий объект для заданного типа объекта .NET. Комплект содержит коллекцию свойств для сопутствующего типа. Комплект свойств можно использовать для эффективного прохождения, доступа и изменения данных для экземпляра объекта сопутствующего типа.
Создание сумок для свойства
Unity использует один из следующих методов для создания сумок свойств для типа:
- Отражение: По умолчанию Unity использует отражение для создания сумки свойств для типа. Отражение удобно и происходит лениво только один раз на тип, когда сумка свойств еще не зарегистрирована.
-
Генерация кода: Для повышения производительности можно включить генерацию кода. Чтобы генерировать сумки свойств с помощью генерации кода, необходимо выполнить следующие действия:
- Аннотировать тип с помощью атрибута
[Unity.Properties.GeneratePropertyBag]. - Обозначьте сборку атрибутами
[assembly: Unity.Properties.GeneratePropertyBagsForAssembly]. Созданные кодом пакеты свойств регистрируются автоматически при загрузке домена.
- Аннотировать тип с помощью атрибута
Включенные члены
Оба метода создания пакетов свойств генерируют свойства для следующих членов типа:
- Общественные поля.
- Закрытые или внутренние поля, помеченные
[SerializeField],[SerializeReference], или[CreateProperty]. - Открытые, закрытые или внутренние свойства, помеченные
[Unity.Properties.CreateProperty].
Добавление [DontCreateProperty] атрибут к открытым, закрытым или внутренним полям исключает их из набора свойств.
Созданное свойство является только для чтения, если поле только для чтения или свойство имеет только геттер. Вы также можете использовать [Unity.Properties.CreateProperty(ReadOnly = true)] сделать созданное свойство доступным только для чтения.
Следующий пример объединяет систему серийного номера Unity с системой свойств Unity:
using UnityEngine;
using Unity.Properties;
public class PropertyBagExample : MonoBehaviour
{
// Serialization go through the field.
[SerializeField, DontCreateProperty]
private int m_Value;
// Bindings go through the property rather than the field.
// This allows you to do validation, notify changes, and more.
[CreateProperty]
public int value
{
get => m_Value;
set => m_Value = value;
}
// This is a similar example, but for the backing field of an auto-property.
// Note that the name of the auto-property is postfixed with k_BackingField.
[field: SerializeField, DontCreateProperty]
[CreateProperty]
public float floatValue { get; set; }
}
Создание свойств в пакете свойств с использованием атрибутов сериализации для удобства не всегда является предпочтительным подходом. Система сериализации в Unity может работать только с полями и автосвойствами, что затрудняет эффективную проверку или распространение изменений.
В отличие от системы сериализации Unity, свойства в пакете свойств не являются типами значений с [SerializeField]. Вместо этого структурные типы распознаются как типы-значения, а классовые — как ссылки.
В сериализации Unity, хотя полиморфизм поддерживается, для явного включения необходимо использовать атрибуты [SerializeReference]. В противном случае экземпляры сериализируются как типы значений. Обратите внимание, что типы UnityEngine.Object являются исключением из этого правила и автоматически сериализируются как типы ссылок.
Соображения, касающиеся эффективности
Создание пакетов свойств путем отражения может привести к увеличению затрат на производительность при первом запросе пакета свойств для данного типа контейнера. Создание свойств для членов поля путем отражения может выделить память и увеличить затраты сборщика мусора в сборках IL2CPP.
Чтобы избежать отражения и повысить производительность, генерировать сумки свойства путем генерации кода вместо этого. Однако учтите, что такая оптимизация во время выполнения может обернуться более долгой компиляцией. Чтобы набор свойств получил доступ к внутренним и закрытым полям и свойствам, сделайте тип partial.