技术开发 频道

ToString(string format) 扩展

我们最后再来看一下更复杂的应用,Peoplee有Friends属性,这是一个集合属性,我们想获取朋友的个数,并列出朋友的名字,如下:

People p5 = new People { Id = 1, Name = "鹤冲天"};

p5.AddFriend(
new People { Id = 11, Name = "南霸天" });

p5.AddFriend(
new People { Id = 12, Name = "日中天" });

string s5 = p5.ToString5("[Name] 目前有 [Friends: .Count] 个朋友:[Friends: .Name]。");

  注意,行4中的Count及Name前都加了个小点,表示是将集合进行操作,这个小点是我看着方便自己定义的。再来看实现代码,到版本五了:

public static string ToString5(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(propertyFormat) == false)
             {
                
if (propertyFormat.StartsWith("."))
                 {
                    
string subPropertyName = propertyFormat.Substring(1);
                     IEnumerable
<object> objs = ((IEnumerable)propertyValue).Cast<object>();
                    
if (subPropertyName == "Count")
                        
return objs.Count().ToString();
                    
else
                     {
                        
string[] subProperties = objs.Select(
                             o
=> o.GetPropertyValue(subPropertyName).ToString()).ToArray();
                        
return string.Join(", ", subProperties);
                     }
                 }
                
else
                    
return string.Format("{0:" + propertyFormat + "}", propertyValue);
             }
            
else return propertyValue.ToString();
         };
        
string pattern = @"\[(?<Name>[^\[\]:]+)(\s*[:]\s*(?<Format>[^\[\]:]+))?\]";
        
return Regex.Replace(format, pattern, evaluator, RegexOptions.Compiled);
     }

 执行结果:

 比较不可思议吧,下面简单分析一下。行22~行33是对集合进行操作的相关处理,这里只是简单实现了Count,当然也可以实现Min、Max、Sum、Average等等。“.Name”这个表示方法不太好,这里主要是为了展示,大家能明白了就好。 

 ToString(string format)扩展带来便利性的同时,也会带来相应的性能损失,两者很难兼得。

 

 最后重申下,本系列文章,侧重想法,所给的代码仅供演示、参考,没有考虑性能、异常处理等,如需实际使用,请自行完善。

查看原文

0
相关文章