2

PowerShell似乎在算术运算和转换之后执行边界检查。例如,下面的操作失败:如何抑制PowerShell中的溢出检查?

[byte]$a = 255 
$a++ 

$a = [byte]256 

有没有办法强制执行溢出或类型转换,而不通过模数或C#和添加型求助于人工计算?

+1

操作失败,因为您明确地投了一个类型并尝试为此类型分配一个太大的值。此行为是设计使然。 PowerShell在溢出时应该做什么?在MAXVALUE处关闭该值?用模操作来包装这个值?将溢出值分配给新变量? PowerShell无法猜测在特定情况下处理溢出的正确方法是什么,因此抛出错误是唯一合理的做法。 –

+1

正如我所说的,我正在寻找大多数其他(所有?)编程语言的行为,它们不执行溢出检查:模操作。许多加密和散列算法都依赖于此,所以PowerShell支持它会非常有意义。 – Chrysler

+0

当然,PowerShell支持模操作。它只是没有盲目猜测什么是你现在想要做的“明显的事情”。如果你想要一个模操作:应用一个模操作。问题解决了。 –

回答

1

PowerShell是一种脚本语言,不是一种编程语言,它不支持像重载操作符(在这种情况下会很方便)等许多高级技术。

要添加你已经建议的东西,你可以抓住错误。

[byte]$a = 255 
try {$a++} catch {$a=1} 

或者写你自己的功能,并在那里做一些模乐趣。

1

你想在PowerShell中实现的行为是可以实现的,不过,这有点破绽;也许还有更好的办法。

如果你只是想要加密功能,那么值得一提的是,BCL中已经内置了一个TON,并且可以从PowerShell完全访问(MD5,SHA,RSA,X509,其他很多其他的东西也是)。

但是,如果你在PowerShell中执行算术选中死心塌地,这是一个黑客工具,应该给你你想要的东西(基本上我们要嵌入C#代码,并使用未经检查的关键字):

$members = @' 
public static UInt32 ToUInt32(int value) 
{ 
    unchecked 
    { 
     return (UInt32)value; 
    } 
} 


public static byte ToByte(int value) 
{ 
    unchecked 
    { 
     return (byte)value; 
    } 
} 
'@; 

$type = Add-Type -Name "Convert" -Namespace "Helpers" ` 
     -MemberDefinition $members -PassThru -ErrorAction SilentlyContinue; 

用法:

PS C:\Some\Folder> [Helpers.Convert]::ToUInt32(-1); 
4294967295 

PS C:\Some\Folder> [Helpers.Convert]::ToByte(-1); 
255 

PS C:\Some\Folder> [Helpers.Convert]::ToByte(256); 
0 

注:

  • 我们打电话[Helpers.Convert]::To...不是[System.Convert]::To...
  • 如果您需要其他方法,则需要将实际的C#方法插入代码顶部的$members块中。
  • 如果在同一个PowerShell会话中同一个NamespaceName组合连续多次运行Add-Type,它将会失败;并且您将留下以前注册的类型。 - 我已添加-ErrorAction SilentlyContinue以忽略此特定场景。 - 这样,您可以将这些代码转储到.ps1脚本中,并在每次使用它们之前调用它,并且它们将始终存在。 - 但是,如果您正在修改C#代码并重新测试,则需要在每次更改后更改类型名称;这有点痛苦。