2017-01-20 33 views
0

我有幾個類,其中我需要解析json對象。我看到這個json對象的初始循環在除了子方法之外的所有類中都非常相似。避免重複的方法在C#中的實現

例如,中Class1

private static void FindObject(JToken token) 
{ 
    switch (token.Type) 
    { 
     case JTokenType.Array:   
     JArray array = token as JArray; 
     array.ForEach(a => FindObject(a)); 
     break;   
     case JTokenType.String: 
     token.Replace(GetNewImgTag(token.ToString())); 
     break; 
     case JTokenType.Object: 
     token.Children().ForEach(t => FindObject(t)); 
     break; 
     case JTokenType.Property: 
     JProperty prop = token as JProperty; 

     if (prop.Value.Type == JTokenType.Array) 
     { 
      FindObject(prop.Value); 
      return; 
     } 

     prop.Value = GetNewImgTag(prop.Value.ToString()); 
     break; 
     default: 
     throw new NotImplementedException(token.Type + " is not defined"); 
    }  
} 

private static JToken GetNewImgTag(string text) 
{ 
    ... 
} 

和Class 2.cs是

private static void FindObject(JToken token) 
{ 
    switch (token.Type) 
    { 
     case JTokenType.Array:   
     JArray array = token as JArray; 
     array.ForEach(a => FindObject(a)); 
     break;   
     case JTokenType.String: 
     token.Replace(ReplaceLinks(token.ToString())); 
     break; 
     case JTokenType.Object: 
     token.Children().ForEach(t => FindObject(t)); 
     break; 
     case JTokenType.Property: 
     JProperty prop = token as JProperty; 

     if (prop.Value.Type == JTokenType.Array) 
     { 
      FindObject(prop.Value); 
      return; 
     } 

     prop.Value = ReplaceLinks(prop.Value.ToString()); 
     break; 
     default: 
     throw new NotImplementedException(token.Type + " is not defined"); 
    }  
} 

private static JToken ReplaceLinks(string text) 
{ 
    ... 
} 

如果你比較這兩個類,FindObject(),除了孩子的方法調用幾乎相同。我需要在幾個班裏實施這個。我試圖避免這種多重複方法的創建。

任何人都可以提出一個更好的方式來設計這個?

我在這裏看到類似的帖子,但我無法將這個代表應用於我的場景。

Avoiding repetitive code in multiple similar methods (C#)

+0

爲什麼你不能申請委託。該方法將更改爲'FindObject(JToken標記,Func getValue)'並應用'prop.Value = getValue(prop.Value.ToString());' – Nkosi

+0

對於'case JTokenType.Property:',爲什麼你不檢查值是否是一個字符串?它可能是一個整數或嵌套對象或日期或其他。 – dbc

回答

2

直接的方法是識別不同的部分,讓你進入一個單獨的函數的委託。

下面是一個工作示例。

public static class MyTokenReaderUtilities 
{ 
    public static void ConvertEachProperty(JToken token, Func<string, JToken> convertString) 
    { 
     switch (token.Type) 
     { 
      case JTokenType.Array:   
       JArray array = token as JArray; 
       array.ForEach(a => ConvertEachProperty(a, convertString)); 
       break;   
      case JTokenType.String: 
      token.Replace(convertString(token.ToString())); 
      break; 
      case JTokenType.Object: 
       token.Children().ForEach(t => ConvertEachProperty(t, convertString)); 
       break; 
      case JTokenType.Property: 
       JProperty prop = token as JProperty; 

       if (prop.Value.Type == JTokenType.Array) 
       { 
       ConvertEachProperty(prop.Value, convertString); 
       return; 
       } 
       prop.Value = convertString(prop.Value.ToString()); 
       break; 
      default: 
      throw new NotImplementedException(token.Type + " is not defined"); 
     } 
    } 
} 

現在,在1類:

private static void FindObject(JToken token) 
{ 
    MyTokenReaderUtilities.ConvertEachProperty(token, GetNewImgTag); 
} 

而在2類:

private static void FindObject(JToken token) 
{ 
    MyTokenReaderUtilities.ConvertEachProperty(token, ReplaceLinks); 
} 
+0

看起來像重構主題,因此我會建議來自Martin Fowler的[book](https://martinfowler.com/books/refactoring.html) – dstar55