技术开发 频道

ToString(string format) 扩展

对于简单的值类型属性没问题了,但对于复杂一些类型如,如People的属性Son(Son就是儿子,我一开始写成了Sun),他也是一个People类型,他也有属性的,而且他也可能有Son...

  先看下调用代码吧:

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

p4.Son
= new People { Id = 2, Name = "鹤小天", Brithday = new DateTime(2015, 9, 9) };

p4.Son.Son
= new People { Id = 3, Name = "鹤微天", Brithday = new DateTime(2040, 9, 9) };

string s4 = p4.ToString4("[Name] 的孙子 [Son.Son.Name] 的生日是:[Son.Son.Brithday: yyyy年MM月dd日]。");

  “鹤冲天”也就是我了,有个儿子叫“鹤小天”,“鹤小天”有个儿子,也就是我的孙子“鹤微天”。哈哈,祖孙三代名字都不错吧(过会先把小天、微天这两个名字注册了)!主要看第4行,format是怎么写的。下面是版本四实现代码,由版本三改进而来:

public static string ToString4(this object obj, string format)

   {

   MatchEvaluator evaluator
= match =>

   {

  
string[] propertyNames = match.Groups["Name"].Value.Split('.');

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

  

  
object propertyValue = obj;

   try

   {

   foreach (
string propertyName in propertyNames)

   propertyValue
= propertyValue.GetPropertyValue(propertyName);

   }

   catch

   {

   return match.Value;

   }

  

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

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

  
else return propertyValue.ToString();

   };

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

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

   }

  为了反射获取属性方法,用到了GetPropertyValue扩展如下(版本三的实现用上这个扩展会更简洁)(考虑性能请在此方法加缓存):

public static object GetPropertyValue(this object obj, string propertyName)

   {

   Type type
= obj.GetType();

   PropertyInfo info
= type.GetProperty(propertyName);

  
return info.GetValue(obj, null);

   }

  先执行,再分析:

  执行正确! 版本四,8~17行用来层层获取属性。也不太复杂,不多作解释了。说明一下,版本四是不完善的,没有做太多处理。

0
相关文章