技术开发 频道

ToString(string format) 扩展

与版本一类似,不过这里没有动态构建正则表达式,因为有了中括号,很容易区分常量和变量,所以我们通过“属性名”来找“属性”(对应代码中第10行)。如果某个属性找不到,我们会将这“[Name]”原样返回(对就第17行)。另一种做法是抛出异常,我不建议抛异常,在ToString(string format)是不合乎“常理”的。

  版本二相对版本一效率有很大提高,主要是因为版本二只使用一个简单的正则表达式:@"\[(?[^\]]+)\]"。而版本一中的如果被扩展类的属性特别多,动态生成的正则表达式会很长,执行起来也会相对慢。

  我们现在来解决两个版本中都存在的时间日期格式问题,把时间日期格式"yyyy-MM-dd"也放入中括号中,测试代码如下:

People p3 = new People { Id = 1, Name = "鹤冲天", Brithday = new DateTime(1990, 9, 9) };

string s3 = p3.ToString3("People:Id [Id: d4], Name [Name], Brithday [Brithday: yyyy-MM-dd]");

  版本三实现代码:

public static string ToString3(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;

  
string propertyFormat = match.Groups["Format"].Value;

  

   PropertyInfo propertyInfo
= properties.FirstOrDefault(p => p.Name == propertyName);

  
if (propertyInfo != null)

   {

  
object propertyValue = propertyInfo.GetValue(obj, null);

  
if (string.IsNullOrEmpty(propertyFormat) == false)

   return
string.Format("{0:" + propertyFormat + "}", propertyValue);

  
else return propertyValue.ToString();

   }

  
else return match.Value;

   };

  
string pattern = @"\[(?[^\[\]:]+)(\s*:\s*(?[^\[\]:]+))?\]";

   return Regex.Replace(format, pattern, evaluator, RegexOptions.Compiled);

   }

  测试一下,可OK了:

0
相关文章