.net PowerShell 和 StringBuilder

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7801651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 15:58:02  来源:igfitidea点击:

PowerShell And StringBuilder

.netpowershellstringbuilder

提问by Alex Yeung

I am new in PowerShell but am familiar with .NET classes.

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

I am using System.Text.StringBuilderin PowerShell script. The script is that

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

I expected the result is

我预计结果是

1
12
123

However the result is

然而结果是

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

Did I do something wrong?

我做错什么了吗?

回答by Keith Hill

Several of the methods on StringBuilder like Append IIRC, return the StringBuilder so you can call more StringBuilder methods. However the way PowerShell works is that it outputs all results (return values in the case of .NET method calls). In this case, cast the result to [void]to ignore the return value e.g.:

StringBuilder 上的一些方法(如 Append IIRC)返回 StringBuilder,以便您可以调用更多 StringBuilder 方法。然而,PowerShell 的工作方式是输出所有结果(在 .NET 方法调用的情况下返回值)。在这种情况下,将结果强制转换[void]为忽略返回值,例如:

[void]$sb.Append($c)

Note that you don't need to end lines in ;in PowerShell. However if you put multiple commands on the same line then use ;' to separate those commands.

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

回答by JPBlanc

Because you say your are new in PowerShell. My answer is a bit more on the way you are writting PowerShell.

因为你说你是 PowerShell 的新手。我的回答更多是关于您编写​​ PowerShell 的方式。

PowerShell is a script language, it's used by non developper programmers such as administrators. You are a C# developper with all your knowledge, but you can write the thing you want to write more simply. In PowerShell it exists syntax to use Lists and Hastables, try the following :

PowerShell 是一种脚本语言,供非开发人员(例如管理员)使用。您是一名拥有所有知识的 C# 开发人员,但您可以更简单地编写您想要编写的内容。在 PowerShell 中,它存在使用 Lists 和 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

Here are three functions doing the same thing, I know that stringbuilders are a bit more efficient in memory, but in this case who cares.

这里有三个函数做同样的事情,我知道 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

回答by Roman Kuzmin

  1. foreachdoes not iterate through characters in a string, it treats it as a single item. So that we have to cast a string to [char[]](or use $line.GetEnumerator()).

  2. The expression $sb.Append($c)gets the builder instance. In PowerShell it gets written to the output. As far as it is unwanted we should suppress this output ($null = ...or ... > $nullor ... | Out-Null).

  1. foreach不遍历字符串中的字符,而是将其视为单个项目。所以我们必须将字符串转换为[char[]](或使用$line.GetEnumerator())。

  2. 该表达式$sb.Append($c)获取构建器实例。在 PowerShell 中,它被写入输出。就不需要的情况而言,我们应该抑制此输出($null = ...... > $null... | Out-Null)。

The expected output is produced by this 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