属性访问者是在 Properties API 的基础上构建的算法。
可使用访问者向类型添加功能,而无需直接修改。可以创建高度通用的访问者来控制算法本身和访问过程。这与访问者模式的典型实现方式不同,后者的访问过程通常发生在一个事先已知的类型结构上。它支持序列化、类似于检视视图的__ UI__(即用户界面,User Interface)让用户能够与您的应用程序进行交互。Unity 目前支持三种 UI 系统。更多信息
See in Glossary 生成等功能。
以下是访问者的基本模式。它发生在属性包和属性伴生对象上。
可以使用以下方法来创建访问者以获取属性:
Unity.Properties.PropertyVisitor 基类。有关示例,请参阅使用 PropertyVisitor 创建属性访问者。IPropertyBagVisitor 和 IPropertyVisitor 接口。有关示例,请参阅使用低级 API 创建属性访问者。第一种方法是最简单的入门方法。但是,为了更广泛地自定义属性包和属性的访问行为,请使用第二种方法,这种方法具有更大的灵活性和改进性能的潜力。
以下示例使用 PropertyVisitor 类来创建一个简单的访问者,该访问者可获取特定类型并带有特定属性标签的属性:
public class BindableAttribute
: Attribute
{
}
public class GatherBindablePropertiesVisitor
: PropertyVisitor
{
public List<PropertyPath> BindableProperties { get; set; }
protected override void VisitProperty<TContainer, TValue>(Property<TContainer, TValue> property, ref TContainer container, ref TValue value)
{
if (property.HasAttribute<BindableAttribute>())
BindableProperties.Add(PropertyPath.AppendProperty(default, property));
}
}
以下是使用 IPropertyBagVisitor 接口创建访问者的对应示例:
public class BindableAttribute
: Attribute
{
}
public class GatherBindablePropertiesVisitor
: IPropertyBagVisitor
{
public List<PropertyPath> BindableProperties { get; set; }
void IPropertyBagVisitor.Visit<TContainer>(IPropertyBag<TContainer> propertyBag, ref TContainer container)
{
// Loop through the properties of the container object.
foreach (var property in propertyBag.GetProperties(ref container))
{
if (property.HasAttribute<BindableAttribute>())
BindableProperties.Add(PropertyPath.AppendProperty(default, property));
}
}
}
低级访问者的性能更佳,因为它不需要循环访问属性包的所有属性并提取它们的值。还可以使用低级访问者访问不属于属性包的属性。
属性包、属性和访问者都使用通用类型实现,以便可以保持尽可能强的类型,并在许多情况下避免在访问期间发生装箱分配。使用通用类型的利弊在于 JIT 编译器将在第一次调用指定方法时为其生成 IL。这可能导致第一次接受对象的访问者时执行速度变慢。