第一个和我们理想的有点差距,就是日期上,我们应该给日期加上"yyyy-MM-dd"的格式,这个我们稍后改进,我们现在有一个更大的问题:
如果我们想输出:“People: Id 1, Name 鹤冲天”,format怎么写呢?写成format="People: Id Id, Name Name",这样没法处理了,format中两个Id、两个Name,哪个是常量,哪个是变量啊?解决这个问题,很多种方法,如使用转义字符,可是属性长了不好写,如format="\B\r\i\t\h\d\a\y Brithday"。我权衡了一下,最后决定采用类似Sql中对字段名的处理方法,在这里就是给变量加上中括号,如下:
People p2 = new People { Id = 1, Name = "鹤冲天", Brithday = new DateTime(1990, 9, 9) };
string s2 = p1.ToString2("People:Id [Id], Name [Name], Brithday [Brithday]");
string s2 = p1.ToString2("People:Id [Id], Name [Name], Brithday [Brithday]");
版本二的实现代码如下:
public static string ToString2(this object obj, string format)
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties(
BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
MatchEvaluator evaluator = match =>
{
string propertyName = match.Groups["Name"].Value;
PropertyInfo property = properties.FirstOrDefault(p => p.Name == propertyName);
if (property != null)
{
object propertyValue = property.GetValue(obj, null);
if (propertyValue != null) return propertyValue.ToString();
else return "";
}
else return match.Value;
};
return Regex.Replace(format, @"\[(?[^\]]+)\]", evaluator, RegexOptions.Compiled);
}
{
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties(
BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
MatchEvaluator evaluator = match =>
{
string propertyName = match.Groups["Name"].Value;
PropertyInfo property = properties.FirstOrDefault(p => p.Name == propertyName);
if (property != null)
{
object propertyValue = property.GetValue(obj, null);
if (propertyValue != null) return propertyValue.ToString();
else return "";
}
else return match.Value;
};
return Regex.Replace(format, @"\[(?[^\]]+)\]", evaluator, RegexOptions.Compiled);
}
调试执行一下: