3つのビューモデルに、フルネームの計算に使用されるフィールドを備えた共通のインターフェイスIFormattablePersonを実装させ、String.Formatに依存させます。
これにより、カスタムフォーマッタに新しい文字列フォーマットを追加するだけで、表示を拡張する非常に便利な方法が可能になります。
これは次のようなものになります:
ビューモデルが実装する必要のある共通のインターフェイス:
public interface IFormattablePerson: IFormattable
{
string FirstName{get;set;}
string LastName{get;set;}
}
各ビューモデルでの同じToString()実装(変更されることはありません)
public string ToString(string format, IFormatProvider formatProvider)
{
if (formatProvider == null)
return ToString(format, new FormatProviderIFormattablePerson());
else
return (formatProvider.GetFormat(typeof(IFormattablePerson)) as ICustomFormatter).Format(format, this, formatProvider);
}
これは、IFormattablePersonにFormatProviderとCustomFormatterを使用します。次に、CustomFormatterで新しいフォーマットを追加して実装する必要があります
public class FormatProviderIFormattablePerson : IFormatProvider
{
// String.Format calls this method to get an instance of an
// ICustomFormatter to handle the formatting.
public object GetFormat(Type service)
{
if (service == typeof(IFormattablePerson))
{
return new CustomFormatterIFormattablePerson();
}
else
{
return null;
}
}
}
public class CustomFormatterIFormattablePerson : ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider provider)
{
if (string.IsNullOrEmpty(format))
format = "full";
if (arg is IFormattablePerson)
{
IFormattablePerson t = (IFormattablePerson) arg;
switch (format)
{
case "f":
return t.FirstName;
case "l":
return t.LastName;
case "full":
default:
return string.Format("{0} {1}",
t.FirstName,
t.LastName).Trim();
}
}
if (arg is IFormattable)
return string.Format(String.Format("{{0:{0}}}",format), arg);
else
return arg.ToString();
}
}