あなたが欲しいものを達成するためにジェネリックを使用することができることを私には思えます。
だから、ベースでは、すべてのタイプが共通の一般的なフォーマットのいくつかの並べ替えを持っている場合、これは有用であろう
protected virtual string GetFormattedAttribute<T>(string propertyName, T propertyValue)
だろう。
最初の検査でうまくいくようですが、タイプに一般的な書式設定パターンがない場合はどうなりますか?すべての書式を1つのクラスに実装するのではなく、フォーマットしている型に密接に結びついた小さな専用の書式付きクラスを実装することをむしろ克服して克服することになります。このようなクラスはObject.ToString()
が値を取得するためにあなたがしたときにこのインタフェースを実装する必要があります最も一般的なクラスは、単に、それゆえ我々はの最も一般的な実装としてObjectPropertyFormatterを持っているIPropertyFormatter<T>
public interface IPropertyFormatter<T> {
string FormatValue(T value);
}
ジェネリックインターフェイスを実装しますIPropertyFormatter
ここで、特殊な処理が必要な種類があるとします。次に、特定のプロパティフォーマッタを実装します。したがって、すべての特定のケースで過負荷のクラスを1つ持つのではなく、書式設定ロジックを処理するクラスを用意しています。この例ではDateTimePropertyFormatter
とBooleanPropertyFormatter
があり、彼らはそのように実装されるだろう:
public class DateTimePropertyFormatter : IPropertyFormatter<DateTime>
{
public string FormatValue(DateTime value)
{
//DateTime customised formatting logic
return "<b>" + value.ToString("yyyyMMdd") + "</b>";
}
}
public class BoolPropertyFormatter : IPropertyFormatter<bool>
{
public string FormatValue(bool value)
{
//bool customised formatting logic
if (value)
return "yeaaah";
else
return "nope";
}
}
あなたはこのようなリストなど、より多くのクラスを持っている可能性があり、その上、自分のフォーマッティングロジックと、それぞれがsingle responsibility principle
でインラインを保ちます
フォーマッタがあるので、すべてのフォーマッタを実行するにはどうすればよいですか?これがFormatterResolver
が出場する場所です。書式を登録することができます。
/// <summary>
/// Class responsible for getting the right format resolver for a given type
/// </summary>
public class FormatterResolver
{
private ObjectPropertyFormatter _objectPropertyFormatter;
private Dictionary<Type, object> _registeredFormatters;
public FormatterResolver()
{
_registeredFormatters = new Dictionary<Type, object>();
_objectPropertyFormatter = new ObjectPropertyFormatter();
}
public void RegisterFormatter<T>(IPropertyFormatter<T> formatter)
{
_registeredFormatters.Add(typeof(T), formatter);
}
public Func<string> GetFormatterFunc<T>(T value)
{
object formatter;
if (_registeredFormatters.TryGetValue(typeof(T), out formatter))
{
return() => (formatter as IPropertyFormatter<T>).FormatValue(value);
}
else
return() => (_objectPropertyFormatter.FormatValue(value));
}
}
formatResolverのインスタンスを格納し、すべてのフォーマッタを登録する必要があります。
public FormatterResolver _formatResolver;
public void RegisterFormatResolvers()
{
_formatResolver = new FormatterResolver();
_formatResolver.RegisterFormatter(new BoolPropertyFormatter());
_formatResolver.RegisterFormatter(new DateTimePropertyFormatter());
//...etc
}
あなたの方法は、このようなものになりますので、
public string GetFormattedAttribute<T>(T propertyValue)
{
return _formatResolver.GetFormatterFunc(propertyValue)();
}
を、テストにそれを置くための時間は、このすべての作業をしますか?これは、上記のコードが期待どおりに機能することを示す迅速な健全性テストです。そして、あなたがする必要があるだろうすべてはとのインタフェースを改正ある
[TestMethod]
public void TestFormatResolvers()
{
RegisterFormatResolvers();
Assert.AreEqual("yeaaah", GetFormattedAttribute(true));
Assert.AreEqual("nope", GetFormattedAttribute(false));
Assert.AreEqual("<b>20120120</b>", GetFormattedAttribute(new DateTime(2012, 01, 20)));
Assert.AreEqual("5", GetFormattedAttribute(5));
}
書式設定ロジックはまた、プロパティ名に依存している場合:
public interface IPropertyFormatter<T> {
string FormatValue(string propertyName, T value);
}
と
応じ子孫クラスを実装するには、あなたはとしてそれを宣言することができますジェネリック? – abatishchev
いいえ、それはオプションではありません – wasimbhalli
あなたはメソッドを使用しているコードを表示できますか?あなたの試みを見ておくと便利です。 –