属性访问器是在属性 API 之上构建的算法。
您可以使用访问器向类型添加功能,而无需直接修改。您可以创建高度通用的访问器来控制算法本身和访问过程。这与访问者模式的经典实现不同,在经典实现中,访问通常发生在已知的提前类型结构上。它支持诸如序列化、类似检查器的UI(用户界面) 允许用户与您的应用程序交互。Unity 目前支持三种 UI 系统。 更多信息
参见 术语表生成等功能。
以下是访问器的基本模式。它发生在属性包和属性伴随对象上。
您可以使用以下方法创建访问器以获取属性
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。这可能导致第一次在对象上接受访问器时执行速度变慢。