2010-01-04 8 views
5

Comme je sais si j'ai déclaré un dictionnaire, je pourrais appeler myDict.Clear() à des fins de réutilisation.Comment réutiliser StringBuilder obj?

Maintenant, si j'ai déclaré un sb comme un objet StingBuilder.

StringBuilder sb = new StringBuilder(); 

Comment réutiliser sb? Je vous remercie. En pratique, j'ai besoin d'imprimer toutes les conditions possibles pour mainDict.

une d'expression sb comme celui-ci (dans le code inclued ci-dessous)

sb.AppendFormat("{0}/{1}/{2}/{3}, {4}", pair1.Key, pair2.Key, pair3.Key, pair4.Key, pair4.Value); 
Console.WriteLine(sb.ToString()); 

Si je déclarais beaucoup de StringBuilder objs, je ne peux toujours pas détecter le nombre obj est suffisant pour moi. acturally le mainDict est très complexe. Le code ci-dessus est une pratique seulement. Merci.


code mis à jour à Jan 04.

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Text; 


class test 
{ 
    private static Dictionary<string, object> mainDict = new Dictionary<string, object>(); 

    public static void Main() 
    { 
     Dictionary<string, object> aSubDict = new Dictionary<string,object>(); 
     Dictionary<string, object> aSub1Dict = new Dictionary<string, object>(); 
     Dictionary<string, object> aSub2Dict = new Dictionary<string, object>(); 
     Dictionary<string, object> aSub3Dict = new Dictionary<string, object>(); 
     Dictionary<string, object> aSub4Dict = new Dictionary<string, object>(); 

     mainDict.Add("ADKey", aSubDict); 
     mainDict.Add("ASKey", "AValue"); 
     aSubDict.Add("BDKey", aSub1Dict); 
     aSubDict.Add("BSKey", "BValue"); 
     aSub1Dict.Add("CDKey", aSub2Dict); 
     aSub1Dict.Add("CSKey", "CValue"); 
     aSub2Dict.Add("DDKey",aSub3Dict); 
     aSub2Dict.Add("DSKey", "DValue"); 
     aSub3Dict.Add("EDKey", aSub4Dict); 
     aSub3Dict.Add("ESKey", "EValue"); 
     aSub4Dict.Add("FKey", "FValue"); 


     StringBuilder sb; 

     foreach (KeyValuePair<string, object> pair1 in mainDict) 
      // watch out for NullReferenceException 
      if (!ReferenceEquals(null, mainDict[pair1.Key]) && (mainDict[pair1.Key] is string)) 
      { 
       Console.WriteLine("Key = {0}, Value = {1}", pair1.Key, pair1.Value); 
       sb = new StringBuilder(); 
       sb.AppendFormat("{0}, {1}", pair1.Key, pair1.Value); 
       Console.WriteLine(sb.ToString()); 
      } 
      // IDictionary is not the one from the Generics namespace, it is the one from the System.Collections namespace 
      else if (!ReferenceEquals(null, mainDict[pair1.Key]) && (mainDict[pair1.Key] is Dictionary<string, object>)) 
      { 
       foreach (KeyValuePair<string, object> pair2 in (Dictionary<string, object>)pair1.Value) 
        if (!ReferenceEquals(null, ((Dictionary<string, object>)pair1.Value)[pair2.Key]) && (((Dictionary<string, object>)pair1.Value)[pair2.Key] is string)) 
        { 
         Console.WriteLine("SubKey = {0}, Value = {1}", pair2.Key, pair2.Value); 
         sb = new StringBuilder(); 
         sb.AppendFormat("{0}/{1}, {2}", pair1.Key, pair2.Key, pair2.Value); 
         Console.WriteLine(sb.ToString()); 
        } 
        else if (!ReferenceEquals(null, ((Dictionary<string, object>)pair1.Value)[pair2.Key]) && (((Dictionary<string, object>)pair1.Value)[pair2.Key] is Dictionary<string, object>)) 
        { 
         foreach (KeyValuePair<string, object> pair3 in (Dictionary<string, object>)pair2.Value) 
          if (!ReferenceEquals(null, ((Dictionary<string, object>)pair2.Value)[pair3.Key]) && (((Dictionary<string, object>)pair2.Value)[pair3.Key] is string)) 
          { 
           Console.WriteLine("SubKey = {0}, Value = {1}", pair3.Key, pair3.Value); 
           sb = new StringBuilder(); 
           sb.AppendFormat("{0}/{1}/{2}, {3}", pair1.Key, pair2.Key, pair3.Key, pair3.Value); 
           Console.WriteLine(sb.ToString()); 
          } 
          else if (!ReferenceEquals(null, ((Dictionary<string, object>)pair2.Value)[pair3.Key]) && (((Dictionary<string, object>)pair2.Value)[pair3.Key] is Dictionary<string, object>)) 
          { 
           foreach (KeyValuePair<string, object> pair4 in (Dictionary<string, object>)pair3.Value) 
            if (!ReferenceEquals(null, ((Dictionary<string, object>)pair3.Value)[pair4.Key]) && (((Dictionary<string, object>)pair3.Value)[pair4.Key] is string)) 
            { 
             Console.WriteLine("SubKey = {0}, Value = {1}", pair4.Key, pair4.Value); 
             sb = new StringBuilder(); 
             sb.AppendFormat("{0}/{1}/{2}/{3}, {4}", pair1.Key, pair2.Key, pair3.Key, pair4.Key, pair4.Value); 
             Console.WriteLine(sb.ToString()); 
            } 
            else if (!ReferenceEquals(null, ((Dictionary<string, object>)pair3.Value)[pair4.Key]) && (((Dictionary<string, object>)pair3.Value)[pair4.Key] is Dictionary<string, object>)) 
            { 
             foreach (KeyValuePair<string, object> pair5 in (Dictionary<string, object>)pair4.Value) 
              if (!ReferenceEquals(null, ((Dictionary<string, object>)pair4.Value)[pair5.Key]) && (((Dictionary<string, object>)pair4.Value)[pair5.Key] is string)) 
              { 
               Console.WriteLine("SubKey = {0}, Value = {1}", pair5.Key, pair5.Value); 
               sb = new StringBuilder(); 
               sb.AppendFormat("{0}/{1}/{2}/{3}/{4}, {5}", pair1.Key, pair2.Key, pair3.Key, pair4.Key, pair5.Key, pair5.Value); 
               Console.WriteLine(sb.ToString()); 
              } 
              else if (!ReferenceEquals(null, ((Dictionary<string, object>)pair4.Value)[pair5.Key]) && (((Dictionary<string, object>)pair4.Value)[pair5.Key] is Dictionary<string, object>)) 
              { 
               foreach (KeyValuePair<string, object> pair6 in (Dictionary<string, object>)pair5.Value) 
                if (!ReferenceEquals(null, ((Dictionary<string, object>)pair5.Value)[pair6.Key]) && (((Dictionary<string, object>)pair5.Value)[pair6.Key] is string)) 
                { 
                 Console.WriteLine("SubKey = {0}, Value = {1}", pair6.Key, pair6.Value); 
                 sb = new StringBuilder(); 
                 sb.AppendFormat("{0}/{1}/{2}/{3}/{4}/{5}, {6}", pair1.Key, pair2.Key, pair3.Key, pair4.Key, pair5.Key, pair6.Key, pair6.Value); 
                 Console.WriteLine(sb.ToString()); 
                } 
                else if (!ReferenceEquals(null, ((Dictionary<string, object>)pair5.Value)[pair6.Key]) && (((Dictionary<string, object>)pair5.Value)[pair6.Key] is Dictionary<string, object>)) 
                { 
                 Console.WriteLine("sub Dict Found"); 
                } 
              } 
            } 
          } 
        } 
      }   
    } 

} 

sortie comme celui-ci

SubKey = FKey, Value = FValue 
ADKey/BDKey/CDKey/DDKey/EDKey/FKey, FValue 
SubKey = ESKey, Value = EValue 
ADKey/BDKey/CDKey/DDKey/ESKey, EValue 
SubKey = DSKey, Value = DValue 
ADKey/BDKey/CDKey/DSKey, DValue 
SubKey = CSKey, Value = CValue 
ADKey/BDKey/CSKey, CValue 
SubKey = BSKey, Value = BValue 
ADKey/BSKey, BValue 
Key = ASKey, Value = AValue 
ASKey, AValue 

Répondre

17

Vous pouvez définir le Length à 0. Dans .NET 4.0 il y a une méthode trop Clear(). Comme la documentation pour Clear état:

Clear est une méthode pratique qui est équivalent à définir la propriété Longueur de l'instance actuelle à 0 (zéro).

Il est donc pas une grosse affaire :)

Je voudrais éviter personnellement le faire, sauf si vous avez vraiment besoin de bien - je normalement juste créer une nouvelle StringBuilder. À mon avis, c'est plus simple à comprendre - il est clair que vous n'avez plus besoin de quoi que ce soit de l'objet précédent.

Avez-vous une raison particulière de vouloir réutiliser l'objet? Si c'est pour des raisons de performances, avez-vous mesuré la performance et trouvé que c'est un goulot d'étranglement? Je suppose que cela pourrait être important si vous avez une instance avec une très grande capacité, et vous voulez éviter de l'allouer à nouveau ... mais cela me semble un peu un casse-tête.

(Tout cela vaut pour les dictionnaires ainsi, d'ailleurs. Je ne me souviens pas la dernière fois que je franchis un dictionnaire.)

+0

Salut Jon, j'ai joint mon exemple de code. Je pense que je ne peux pas créer beaucoup de nouveaux obj StringBuilder .... Je ne connais pas le nombre exact si le mainDict a changé, mon mainDict va changer dynamiquement ... –

+0

Pourquoi pensez-vous que vous ne pouvez pas créer beaucoup de nouveaux objets StringBuilder? Je ne suggère pas de déclarer plus de variables StringBuilder * - mais quand vous voulez un nouveau StringBuilder, utilisez simplement 'sb = new StringBuilder()'. J'ai bien peur de comprendre ce que votre code essaie de faire ... –

+0

Le mainDict créé à partir d'un résultat d'analyse du fichier XSD, le fichier XSD maintenu par une autre équipe. J'ai besoin de créer un autre fichier xsd2cs.cs (string [] map et type [] map) au moment du compilateur.C'est pourquoi j'ai besoin d'imprimer tous les éléments liés séparés par '/' en tant que chaîne jointe. alors un autre programme d'exécution pourrait valider le XML réalisé basé sur le fichier .cs. –

2

Je pense plutôt que de réutiliser un objet StringBuilder exting, vous devez créer un nouveau StringBuilder objet.

+2

Une raison quelconque? Je ne vois vraiment aucun avantage à créer une nouvelle instance pour réutiliser l'instance existante. Cela dépend du contexte. –

+0

@Upul, pour mon cas, je pense que je préfère réutiliser l'instance existante. meilleur? –

+0

@Jaco: Si vous ne voulez pas d'informations de l'ancien StringBuilder, pourquoi les réutiliser? Cela ajoute de la complexité logique à l'OMI quand vous voulez vraiment dire: «Je n'ai besoin de rien de l'ancien, donnez-en un nouveau. –