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#代碼並重新測試,則需要在每次更改後更改類型名稱;這有點痛苦。