クライアントが取得するフィールドのタイプを正確に知っていると仮定すると、プロパティ定義を次のようにジェネリックを使用する関数に変更できます。
private object fieldValue;
public T GetFieldValue<T>() {
return (T)fieldValue;
}
ユーザーは次のようにこのメソッドを呼び出す必要があります。
MyItem item = itemField.GetFieldValue<MyItem>();
ただし、キャストはまだ存在しており、ジェネリック型パラメーターとして提供する型をユーザーがどのように知っているかは明確ではありません。
より良いアプローチは、ある種のダブルディスパッチメカニズム、たとえばビジターパターンを使用して、方向を「反転」し、フィールドに値を呼び出し元に「プッシュ」させることです。
interface IItemFieldVisitor {
void VisitString(string val);
void VisitMyItem(MyItem val);
void VisitList(IList<MyItem> val);
}
interface IItemField {
string Name {get;set;}
void Accept(IItemFieldVisitor visitor);
}
class StringItemField : IItemField {
public string Name {get;set;}
private string val;
public void Accept(IItemFieldVisitor visitor) {
visitor.VisitString(val);
}
}
class MyItemItemField : IItemField {
public string Name {get;set;}
private MyItem val;
public void Accept(IItemFieldVisitor visitor) {
visitor.VisitMyItem(val);
}
}
class MyItemListItemField : IItemField {
public string Name {get;set;}
private IList<MyItem> val;
public void Accept(IItemFieldVisitor visitor) {
visitor.VisitList(val);
}
}
これで、インターフェイスのインスタンスを作成し、それらをオブジェクトIItemFieldVisitor
に渡すことができます。訪問者は、訪問されているオブジェクトIItemField
のタイプを知らなくても、特定の値を持つコールバックを受け取ります。IItemField