在我看來,你可以使用泛型來實現你想要的。
所以在基地,你將有
protected virtual string GetFormattedAttribute<T>(string propertyName, T propertyValue)
如果所有類型有某種共同的通用格式這將是有益的。
初次檢查看起來不錯,但如果你的類型沒有一些通用的格式化模式(我認爲是這種情況)會怎麼樣。我不是在一個類中實現所有的格式化,而是更願意去實現和征服,實現一些與他們正在格式化的類型緊密相關的小型專用格式化類。這樣的類將實現通用接口IPropertyFormatter<T>
public interface IPropertyFormatter<T> {
string FormatValue(T value);
}
,將需要實現這個接口中最通用類只是當你爲Object.ToString()
做的就是價值,因此,我們有ObjectPropertyFormatter爲最通用的實現IPropertyFormatter
public class ObjectPropertyFormatter : IPropertyFormatter<Object>
{
public string FormatValue(Object value)
{
//object fallback formatting logic
return value.ToString();
}
}
現在假設某些類型需要特殊處理。然後我們繼續爲它們實現特定的屬性格式化器。因此,您不必爲所有特定情況擁有一個具有大量重載的類,而是擁有處理格式邏輯的專用類。在這個例子中有一個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";
}
}
你可以有更多的類,如List等,每個都有自己的格式邏輯與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));
}
如果您格式化邏輯也依賴於propertyName的那麼所有你需要做的是界面修改到:
public interface IPropertyFormatter<T> {
string FormatValue(string propertyName, T value);
}
並實現派生類相應
你可以聲明它作爲通用? – abatishchev
不,這不是一個選項 – wasimbhalli
你可以顯示你使用調用方法的代碼嗎?看到你的嘗試是有用的。 –