以下のようにすると変数 $f に "" を代入した際にエラーとなる。
PS C:\Users\kou\a> $f = [Io.FileInfo] "a\x"
PS C:\Users\kou\a> $f.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True FileInfo System.IO.FileSystemInfo
PS C:\Users\kou\a> $f = ""
PS C:\Users\kou\a> $f.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS C:\Users\kou\a> [Io.FileInfo] $f = "a\x"
PS C:\Users\kou\a> $f.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True FileInfo System.IO.FileSystemInfo
PS C:\Users\kou\a> $f = ""
Cannot convert value "" to type "System.IO.FileInfo". Error: "パスの形式が無効です。"
At line:1 char:1
+ $f = ""
+ ~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
PS C:\Users\kou\a> remove-variable f
PS C:\Users\kou\a> $f = ""
PS C:\Users\kou\a>
どうやら、[クラス名] って書き方にダブルミーニングがあって、上記の動作から推測するに C++ っぽい書き方をすると以下のような対応になる。
[Io.FileInfo] $f # new Io.FileInfo($f) って意味
[Io.FileInfo] $f = "a\x" # Io.FileInfo $f("a\x") って意味
自分は、後者の書き方で、$f へは String 型 を代入すると共に、全体としては Io.FileInfo 型を返してほしかったのだが、そうは問屋が卸してくれなかった。
どうもそれは、以下のように書く必要があるらしい。
[Io.FileInfo] ($f = "a\x") # new Io.FileInfo($f = "a\x") って意味
いや、まぁ C 言語でも
int *x = 0; // x = 0 の代入
*x = 0; // *x = 0 の代入
みたいなダブルミーニングはあるけどさぁ。
しかし、PowerShell では
更に、$f の初期化の仕方によっては、その後の = オペレーターの挙動が変わってしまっている。
$f = [Io.FileInfo] "a\x" # $f へは任意のオブジェクトを代入可能。言うなれば ::operator=()?
[Io.FileInfo] $f = "a\x" # $f へは Io.FileInfo のみ代入可能。Io.FileInfo::operator=() もしくは右辺が勝手に Io.FileInfo() で括られる?
しかも、これは少なくとも .GetType() メソッドでは区別が付いてない。
この状態は remove-variable で変数を削除すると解除される。
後者のやり方は $f を [Io.FileInfo] 型に固定していると考えると、単純に $f = "" とするのではなく、自動的に $f = Io.FileInfo("") ってしてくれてるとも考える事が出来で、慣れるとこれは結構便利に使えそうな気はするんだけど、慣れないと凄い気持ち悪い。
あと、1liner 的な書き方する時には結構変な挙動があるみたいで、未定義状態から1回目と2回目で全体の型が異なったりする。
PS C:\Users\kou> remove-variable f
PS C:\Users\kou> echo ([Io.FileInfo] $f=".")
.
PS C:\Users\kou> echo ([Io.FileInfo] $f=".")
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2017/01/13 9:33 .
PS C:\Users\kou> remove-variable f
PS C:\Users\kou> ([Io.FileInfo] $f=".").GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
PS C:\Users\kou> ([Io.FileInfo] $f=".").GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True FileInfo System.IO.FileSystemInfo
PS C:\Users\kou> remove-variable f
PS C:\Users\kou> [Io.FileInfo] $f="."; $f.getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True FileInfo System.IO.FileSystemInfo
PS C:\Users\kou> [Io.FileInfo] $f="."; $f.getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True FileInfo System.IO.FileSystemInfo
PS C:\Users\kou>