質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

Q&A

解決済

1回答

1248閲覧

powershell で クラス を変数に格納するときに どの型を指定したらいいのか分からない

kamikazelight

総合スコア305

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

0グッド

0クリップ

投稿2019/02/08 05:44

編集2019/02/08 06:37

前提・実現したいこと

最近変数にクラスを格納することが増えてきたのですが
気持ちの問題ですが
後で見やすいように明示的に型を指定したいです。
Objectにしてしまうとあまり意味がないので
それ以外だと
どの型を指定したらいいでしょうか?

試したこと

単純にGetType()で調べればいいと思ったのですが
帰ってきた型だと型が見つかりません。とエラーになります。

powershell

1 2<# 3 全ての結果で System.RuntimeType が帰ってくる 4#> 5$test = [int] 6Write-host $($test.gettype().fullname) 7 8$test = [String] 9Write-host $($test.gettype().fullname) 10 11Write-host $([int].gettype().fullname) 12 13Write-host $([String].gettype().fullname) 14class test 15{ 16} 17Write-host $([test].gettype().fullname) 18 19 20 21<# 22 System.RuntimeType の 型は 見つからない 23#> 24Write-host $([System.RuntimeType].gettype().fullname) 25 26<# 27 当然できない 28#> 29[System.RuntimeType]$test2 = [test] 30

補足情報(FW/ツールのバージョンなど)

Win10
PowerShell V5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kunai

2019/02/08 06:12

どの型って・・・そりゃ格納したいクラスじゃないんですか? 実際にやりたい事のソースコードを提示頂いた方が、何がしたいのかわかりやすいです。
ozwk

2019/02/08 06:21

こういうことでなく? $x = 1 Write-host $($x.gettype().fullname) //=>System.Int32
kunai

2019/02/08 06:38

[MultiThread]$MTL = &".\MultiThread.ps1" ということ?
kamikazelight

2019/02/08 06:49 編集

試してみましたが出来ませんね。 [MultiThread]の定義が使う側ではされていからだと思うのですが 追記 違いました [int]$int = [int] もできないですね [int] は int型ではないので 混乱していました。 追記 変数に格納したいのはインスタンスではありません クラス定義 そのものです。
kamikazelight

2019/02/08 06:54

すみません。 質問文の不備以外は 以降 回答欄にお願い致します。
guest

回答1

0

ベストアンサー

[int] は RuntimeType 型です。これは型を表すクラスの型ですが、Public ではなくシステム内部で Internal として宣言されている型なので、PowerShell など外部から使うことができません。かわりにその基本型である Type 型を使ってください。

参考 : What's the difference between System.Type and System.RuntimeType in C#?
ソース : System.Runtime.Type

[int]$i = 1 [Type]$t = [int] [Type]$t2 = $i.GetType()

test クラスのインスタンスは test 型です。test 型の型は Type 型(RuntimeType 型)です。

class test {} [test]$test = [test]::new() [Type]$typeOfTest = [test] [Type]$typeOfTest2 = $test.GetType()

投稿2019/02/08 12:13

編集2019/02/08 12:31
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2019/02/08 21:43

今回も有難うございました。
kamikazelight

2019/02/09 00:42

もしも自力で [Type] という答えにたどり着こうと思ったら PowerShellの機能だけではやはりたどり着けないのでしょうか?
Zuishin

2019/02/09 01:38

型を入れる型は Type というのを知っていれば解決は早いと思いますが、RuntimeType 型にアクセスできないことを不審に思い、それを重点的に調べることでも解決は可能です。 PowerShell は .NET を使っているので、その知識があるかないかが解決に影響を及ぼすことはそれほど珍しくないのではないでしょうか。 Get-Help で得られるヘルプには載っていなかったように記憶していますし、ヘルプがあまり充実していないのが残念ですね。.NET の問題は .NET のドキュメントを読めというスタンスなのでしょう。
kamikazelight

2019/02/09 02:10

.NET は今まで利用するものだけしか見ていなかったのですが 一度全体を見ておいた方がいい気がしてきました。 時間を作ってみてみます またよろしくお願いいたします。
imihito

2019/02/09 05:37

参考程度の話ですが… PowerShellの機能だけで頑張る場合は [int].GetType().BaseType.BaseType ~と継承元の型を辿っていって、 IsPublicがTrueなものを探すのも手かもしれません
kamikazelight

2019/02/09 18:50

なるほど この方法で行くと今回の場合はTypeの手前にある[System.Reflection.TypeInfo]で 大丈夫そうですね。 いまさらかもしれないですが [int]$Int = "5" のように左辺で型が指定されていた場合 右辺が左辺の型にキャストされる、っと思い込んでいたのですが もしかして 左辺で指定された型が右辺の型のBaseTypeを辿った先にあるいずれかの型で 尚且つ、現在の型のメンバーに指定された型が一つ以上ある場合キャストはされない 感じでしょうか?
Zuishin

2019/02/09 23:45 編集

確かに TypeInfo でも良さそうですが、違和感がありますね。 TypeInfo はリフレクションに使うもので、型を表すのは Type を使うのが通例です。 [int]$Int = "5" の場合、int 型として宣言された変数 $Int に文字列型である "5" が代入されているので型変換が起こっています。ある型のオブジェクトを別の型として扱うことをキャストと言いますが、型変換によるキャストはむしろ例外で、型を宣言するときに「この型をこの型にキャストする時にはこのようにしてください」とわざわざコンバーターを定義するか、あるいは PowerShell がキャストによって文字列を数値に自動的に変換する機能を提供しているように、特別な機能が必要です。 ほとんどの場合、キャストには型変換でなくポリモーフィズムが使われます。つまり、派生型を基本型にキャストできます。この機能は .NET が提供しているもので、特別に定義しなくてもすべてのクラスで使えるものです。 Type クラスの BaseType プロパティで取得できるのは、その Type クラスが表す型の基本型なのでキャスト可能です。 たとえば [int].BaseType は System.ValueType なので int 型である 1 は [System.ValueType]1 のように ValueType にキャストできます。 しかし [System.Action]1 は失敗します。Action 型は int の基本型ではないからです。これを成功させるには、PowerShell に新たな機能を実装するか、Action 型もしくは int 型に相互変換のためのメソッドを実装する必要があります。 同様に Type → TypeInfo → RuntimeType と派生しているので、RuntimeType 型のオブジェクトは TypeInfo や Type にキャストでき、TypeInfo 型のオブジェクトは Type 型にキャストできます。 その逆はできません。 この時には型変換は起こりません。つまりキャストされた時に古いオブジェクトが破棄されて新しいオブジェクトが作られるのではなく、古いオブジェクトがそのまま自分の基本型としてふるまいます。これをポリモーフィズムと呼びます。
kamikazelight

2019/02/11 06:36

キャスト と 型変換 は違うのですね 知りませんでした。 intからValueTypeへのキャストは型変換ということで良いのでしょうか? そして型変換の時は古いオブジェクトが破棄されて新しいオブジェクトが作られる という事で合っていますか?
Zuishin

2019/02/11 06:58

それは型変換ではなくポリモーフィズムです。オブジェクトは自分の基本型として振る舞うことができます。 ValueType は int の基本型です。
Zuishin

2019/02/11 07:03

例えば string を int にキャストする場合、string は int 型のメソッドやプロパティを持っていないので int 型として振る舞う能力がありません。 その場合には string が破棄されて新しくそれをもとにした int 型が作られます。 しかし int 型は ValueType から派生したものでその全てのメソッドとプロパティを持っており、ValueType として振る舞うことができます。 そのため、インスタンスを作り直す必要がなく、そのまま使われます。
kamikazelight

2019/02/11 14:53

記憶違いだったのですが intをValueTypeにキャストしたら型がValueTypeに変わった気がしたので 型変換かなと 勘違いしてしまいました。 大体は理解できたと思います。 丁寧な説明をありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問