2017-01-20 3 views
0

私はjsonオブジェクトを解析する必要があるいくつかのクラスがあります。このjsonオブジェクトの初期ループは、サブメソッドを除くすべてのクラスでほぼ同じです。例えばCで反復メソッドの実装を避ける

、Class1.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(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) 
{ 
    ... 
} 

とクラス2.cs内では、両方のクラスを比較すると、FindObject()は、子メソッドの呼び出しを除いてほとんど同じである

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) 
{ 
    ... 
} 

です。私はいくつかのクラスでこれを実装する必要があります。私はこの複数の重複したメソッドの作成を避けるようにしています。

誰もがこれを設計するより良い方法を提案できますか?

私はここで同様の投稿を見ましたが、この代理人を私のシナリオに適用することはできません。

Avoiding repetitive code in multiple similar methods (C#)

+0

なぜあなたは、デリゲートを適用することができません。メソッドは 'FindObject(JToken token、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

関連する問題