プロパティビジターは、Properties API の上にビルドされたアルゴリズムです。
ビジターを使用すると、直接変更することなく型に機能を追加できます。高度にジェネリックなビジターを作成して、アルゴリズム自体と訪問プロセスの両方を制御できます。これは、訪問が通常は既知の事前型構造で発生する、ビジターパターンの従来の実装とは異なります。シリアル化、インスペクターのような UI 生成などの機能が可能になります。
以下は、ビジターの基本的なパターンです。これは、プロパティバッグとプロパティコンパニオンオブジェクトで発生します。
以下のアプローチを使用して、ビジターを作成してプロパティを取得できます。
Unity.Properties.PropertyVisitor 基本クラスを使用します。例については、PropertyVisitor を使用してプロパティビジターを作成する を参照してください。IPropertyBagVisitor インターフェースと IPropertyVisitor インターフェースを実装します。例については、低レベル API を使用してプロパティビジターを作成する を参照してください。最初のアプローチは、使用を開始する最も簡単な方法です。ただし、プロパティバッグとプロパティの両方の訪問動作をより広範囲にカスタマイズするには、柔軟性が高くパフォーマンスが向上する可能性がある 2 番目のアプローチを使用します。
以下の例では、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 を生成することです。その結果、オブジェクトに対して初めてビジターが受け入れられたときに実行が遅くなる可能性があります。