在我看来,你可以使用泛型来实现你想要的。
所以在基地,你将有
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
你可以显示你使用调用方法的代码吗?看到你的尝试是有用的。 –