PowerShell Et StringBuilder

Je suis nouveau en PowerShell mais je suis familier avec les classes .NET.

j'utilise System.Text.StringBuilder EN script PowerShell. Le script est qu'

Function MyStringFunc([String]$line) {
    $r = New-Object -TypeName "System.Collections.Generic.List``1[[System.String]]";
    $sb = New-Object -TypeName "System.Text.StringBuilder";

    foreach ($c in $line) {
        $sb.Append($c);
        $r.Add($sb.ToString());
    }

    return $r;
}

$line1 = "123";
$a = MyStringFunc $line1;
$a

j'attend le résultat est

1
12
123

Cependant, le résultat est

                  Capacity                MaxCapacity                    Length
                  --------                -----------                    ------
                        16                 2147483647                         3
123

ai-je Fait quelque chose de mal?

30
demandé sur Alex Yeung 2011-10-18 05:59:21

3 réponses

plusieurs des méthodes sur StringBuilder comme Ajouter IIRC, retournez le StringBuilder pour que vous puissiez appeler plus de méthodes StringBuilder. Toutefois, la façon dont PowerShell fonctionne est qu'il affiche tous les résultats (valeurs de retour dans le cas des appels de méthode .NET). Dans ce cas, lancez le résultat à [void] pour ignorer la valeur de retour par exemple:

[void]$sb.Append($c)

Notez que vous n'avez pas besoin de fin de lignes ; en PowerShell. Cependant, si vous mettez plusieurs commandes sur la même ligne, puis utiliser ;' séparer les commandes.

38
répondu Keith Hill 2011-10-18 02:13:44

parce que vous dites que vous êtes nouveau en PowerShell. Ma réponse est un peu plus sur la façon dont vous écrivez PowerShell.

PowerShell est un langage de script, il est utilisé par des programmeurs non développeurs tels que des administrateurs. Vous êtes un C# développeur avec toutes vos connaissances, mais vous pouvez écrire la chose que vous voulez écrire plus simplement. Dans PowerShell, il existe une syntaxe pour utiliser les listes et Hastables, essayez ce qui suit:

$a = @()
$a += "Bonjour"
$a += "Salut"
$a
$a | get-member
Get-Member -InputObject $a

$rwc = @{}
$rwc += @{1="Blues"}
$rwc += @{2="Blacks"}
$rwc
$rwc | get-member
Get-Member -InputObject $rwc

Voici trois fonctions faisant la même chose, je sais que stringbuilders sont un peu plus efficace en mémoire, mais dans ce cas qui s'en soucie.

Function MyStringFunc([String]$line)
{ 
  $r = New-Object -TypeName "System.Collections.Generic.List``1[[System.String]]"; 
  $sb = New-Object -TypeName "System.Text.StringBuilder"; 

  foreach ($c in [Char[]]$line)
  { 
    $a = $sb.Append($c); 
    $r.Add($sb.ToString()); 
  }  
  return $r; 
} 

# A more simple way
Function MoreReadableStringFunction([String]$line)
{
  $r = @() # an untyped list

  foreach ($c in [Char[]]$line)
  { 
    $a += $c; 
    $r += $a;
  } 
  return $r;
}

# More simple but not so readable
Function MoreSimpleStringFunction([String]$line)
{
  $r = @() # an untyped list

  [Char[]]$line | % {$a += $_; $r += $a} 
  return $r;
}


Clear-Host
$line1 = "123";

$t1 = MyStringFunc $line1; 
$t1

$t2 = MoreReadableStringFunction $line1
$t2

$t3 = MoreSimpleStringFunction $line1
$t3
4
répondu JPBlanc 2011-10-18 03:20:06
  1. foreach ne itère pas les caractères d'une chaîne de caractères, elle les traite comme un seul élément. De sorte que nous devons lancer une corde à [char[]] (ou utiliser $line.GetEnumerator()).

  2. $sb.Append($c) obtient l'instance builder. Dans PowerShell il est écrit à la sortie. Dans la mesure où elle est non désirée, nous devrions supprimer cette sortie ($null = ... ou ... > $null ou ... | Out-Null).

Le résultat attendu est produit par ce code:

Function MyStringFunc([String]$line) {
    $r = New-Object -TypeName "System.Collections.Generic.List``1[[System.String]]";
    $sb = New-Object -TypeName "System.Text.StringBuilder";

    foreach ($c in [char[]]$line) {
        $null = $sb.Append($c);
        $r.Add($sb.ToString());
    }

    return $r;
}

$line1 = "123";
$a = MyStringFunc $line1;
$a
3
répondu Roman Kuzmin 2011-10-18 02:14:36