為什么隱式轉換[byte]有效,但用它替換時byte不再bool有效?
IE。以下作品...
Add-Type -TypeDefinition @'
public readonly struct MyByte
{
private readonly byte value;
public MyByte( byte b ) => this.value = b;
public static implicit operator byte( MyByte b ) => b.value;
public static explicit operator MyByte( byte b ) => new MyByte( b );
public override string ToString() => $"{value}";
}
'@
[byte] $d = [MyByte]::new( 1 ) # OK
...雖然這個非常相似的代碼沒有:
Add-Type -TypeDefinition @'
public readonly struct MyBool
{
private readonly bool value;
public MyBool( bool b ) => this.value = b;
public static implicit operator bool( MyBool b ) => b.value;
public static explicit operator MyBool( bool b ) => new MyBool( b );
public override string ToString() => $"{value}";
}
'@
[bool] $b = [MyBool]::new( $true ) # Error
這會產生以下錯誤:
無法將值“MyBool”轉換為型別“System.Boolean”。布爾引數僅接受布林值和數字,例如 $True、$False、1 或 0。
請注意,在 C# 中,隱式轉換為bool按預期作業:
public class MyBoolTest {
public static void Test() {
bool b = new MyBool( true ); // OK
}
}
所以這似乎只是一個 PowerShell 問題。
(PS版本:7.2.2)
uj5u.com熱心網友回復:
在Santiago Squarzon的協助下,您自己已經完成了大部分發現,但讓我嘗試總結一下:
您會看到兩種不同的有問題的 PowerShell 行為:
有問題的行為 A: PowerShell 有自己的內置布爾轉換邏輯,不幸的是,它不支持隱式或顯式 .NET 轉換運算子。
這個答案的底部總結了這個內置邏輯的規則,這解釋了為什么它會考慮你的型別的任何實體
[MyBool]- 甚至[MyBool]::new($false)-$true不幸的是。只有在實體不首先被強制轉換為布林值的操作中,轉換運算子才會受到尊重,這對于大多數運算子來說意味著在LHS上使用實體:
[MyBool]::new($false) -eq $false # -> $true [MyBool]::new($false), 'other' -contains $false # -> $true # With -in, it is the *RHS* that matters $false -in [MyBool]::new($false), 'other' # -> $true相比之下,如果您強制使用布爾背景關系 - 通過在(通常)LHS 上使用布林值或使用隱式到布林值強制 - PowerShell 的內置邏輯 - 不支持轉換運算子 - 會啟動:
$false -eq [MyBool]::new($false) # -> !! $false $false, 'other' -contains [MyBool]::new($false) # -> !! $false # With -in, it is the *RHS* that matters [MyBool]::new($false) -in $false, 'other' # -> !! $false # Most insidiously, with *implicit* coercion. if ([MyBool]::new($false)) { 'what?' } # -> !! 'what?'
有問題的行為 B:當您使用對變數進行型別約束
[bool]時,即當您將型別字面量放置在被分配變數的左側時(例如,[bool] $b = ...與開始,這 - 與任何型別接受的內置到布爾轉換不同 - 非常嚴格,如錯誤訊息所示。$b = [bool] (...)[bool]也就是說,只有
$true和$false數字(零映射到$false和任何非零值到$true)可以傳遞給型別為 的引數[bool]。- 請注意,
[bool]引數本身很少見,因為布爾邏輯是 PowerShell 慣用的用[switch]引數表示的,當它(非典型地)給出顯式引數時,它甚至更具限制性并且只$true接受$false。
- 請注意,
這種有問題的行為 - 不恰當地將引數邏輯應用于(非引數)變數- 是GitHub 問題 #10426的主題。
[1] The difference between the two is that type-constraining - [bool] $b = ... - effectively locks in the data type of variable $b, so that latter attempts to assign new values are coerced to the same type. By contrast, $b = [bool] (...) merely applies an ad hoc cast to force a conversion, without preventing later assignments from assigning values with different data types.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/449953.html
標籤:C# 电源外壳 隐式转换 powershell-7.0 PowerShell-7.2
上一篇:C#提高鏈表的性能
下一篇:在C#中使用引數創建泛型工廠
