PowerShell和StringBuilder

Ale*_*ung 33 .net powershell stringbuilder

我是PowerShell的新手,但我熟悉.NET类.

System.Text.StringBuilder在PowerShell脚本中使用.脚本就是这样

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
Run Code Online (Sandbox Code Playgroud)

我预计结果是

1
12
123
Run Code Online (Sandbox Code Playgroud)

但结果是

                  Capacity                MaxCapacity                    Length
                  --------                -----------                    ------
                        16                 2147483647                         3
123
Run Code Online (Sandbox Code Playgroud)

我做错什么了吗?

Kei*_*ill 42

StringBuilder上的几个方法如Append IIRC,返回StringBuilder,因此可以调用更多的StringBuilder方法.但是,PowerShell的工作方式是输出所有结果(在.NET方法调用的情况下返回值).在这种情况下,将结果转换[void]为忽略返回值,例如:

[void]$sb.Append($c)
Run Code Online (Sandbox Code Playgroud)

请注意,您不需要;在PowerShell中结束行.但是,如果您将多个命令放在同一行上,则使用;'来分隔这些命令.

  • MSDN正确指出StringBuilder.Append(...)返回StringBuilder.在像C#这样的语言中,这不是问题,因为您可以忽略返回值.但是在PowerShell中,它隐式输出任何返回的值.如果您不希望PowerShell输出返回值,*您必须将表达式转换为`[void]`(或将表达式传递给Out-Null).这只是C#和基于shell的脚本语言(如PowerShell)之间的根本区别. (14认同)

JPB*_*anc 5

因为您说您是PowerShell中的新手。我的答案是关于编写PowerShell的方式。

PowerShell是一种脚本语言,供非开发人员的程序员(例如管理员)使用。您是一个拥有全部知识的C#开发人员,但是您可以更轻松地编写要编写的东西。在PowerShell中,存在使用列表和Hastables的语法,请尝试以下操作:

$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
Run Code Online (Sandbox Code Playgroud)

这里有三个函数在做同样的事情,我知道stringbuilders在内存上效率更高,但是在这种情况下,谁在乎。

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
Run Code Online (Sandbox Code Playgroud)