3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PowershellでGenericクラスにインテリセンスが効かないけど効かせる!

Last updated at Posted at 2021-02-08

今日も心の声はダダもれ

~~ああ、サボりたい。~~みなさんこんにちは。
動的型付の言語で、あえて型付をするのは、インテリセンスでサボりたいから
可読性やメンテナンス性、データ型の保証などの理由からです。

動機は単純

C#でいつも使っているList<T>って便利ですよね。

PowershellにあるPSCustomObject、なんとなく使いたくないです。
いつも使っている便利なものを持ちこんで、面倒なことはサボりたい。
自分の作業の効率化のためにも、どう使うのか見てみましょう。

とりあえず宣言してみよう

:thinking: 「C#で書くと、Listはこうなりますね。」

List<string> SharpList = new List<string>();
SharpList.Add("So Smart!");

:thinking: 「う~ん、Powershellだとどう書くんでしょう?」
:thinking: 「ふむふむ、こうやるのか。」

$DullList = New-ObjectGeneric -className List -typeParameters "string"

※問題はここからです。

要素を追加してみよう

:smile: 「初期化もできたし、追加してみましょう。」

$DullList.Add("feel heavy....")

(なんだと?ありえない!) ピリオドを打った時点で入力候補が出ないではないですか!!
入力補完機能でサボりたいな。ラクしようと思ったのに逆効果ですよ。 素早く入力できるといいですよね。

他の方法は?

:smile: 「他の書き方もあるらしいですね!」

$InertList = New-ObjectGeneric List "string"

:smile: 「やってみましょう。」

$InertList.Add("feel so tired....")

:thinking: 「ああ、これもダメだ。」

インテリセンスが欲しい

インテリセンスが効く書き方は無いのか探していたら、ありました。

$HappyList = New-Object System.Collections.Generic.List[string]

:smile: 「初期化しているので、さっそく要素の追加ですね。」

image.png

:smile: 「入力候補が出ましたね!」

$HappyList.Add("feel light!!★!☆!★!☆!★!☆!★!☆!★!☆!★!☆!★!☆!★!☆!★!☆!")

:flushed:「なんだかハッピー過ぎて、お星さまが出てしまいました。お恥ずかしい。」

ちなみに

:smile: 「こんな書き方でも入力候補が出ました。」

$HappyList = New-Object System.Collections.Generic.List[string]
$HappyList = [System.Collections.Generic.List[string]]::new()
[System.Collections.Generic.List[string]]$HappyList = [System.Collections.Generic.List[string]]::new()

:smile: 「とてもハッピーになれそうです。」

辞書はどう?

Listはインテリセンス使って上手くやれそうです。
それでは辞書も同じようにできるといいですね。

Dictionary<string,List<string>> SharpDict = new Dictionary<string,List<string>>();
SharpDict.Add("So Smart", new List<string>{"be", "so", "smart", "!"});

C#だとこんな感じですね。

だるいやつ入力候補が出ない方法

$DullDict = New-ObjectGeneric -className Dictionary -typeParameters ("string",$list.GetType().FullName)
$InertDict = New-ObjectGeneric Dictionary ("string", $list.GetType().FullName)

入力候補が出る方法?

:slight_smile:「同じライブラリにあるクラスなので、当然のようにDictionaryも同じ書き方で大丈夫ですよね!」

$UnHappyDict = New-Object [System.Collections.Generic.Dictionary[[string,string]]]

:slight_smile:「きっとそうですよ!宣言して、次は…」

$UnHappyDict.Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah!

:punch: :angry:「入力候補、出ないじゃないですか!激おこですよ!」

今度こそ

これはムズムズしますね。同じライブラリなのにどうして挙動が違うのでしょうか?
そういえば、Listの時、別の書き方でもインテリセンス効きましたよね?
:smile: 「試してみましょうか。」

$HappyDict = [System.Collections.Generic.Dictionary[string, string]]::new()

:smile: 「さあ、早く出して欲しいです。」

image.png

:thinking: 「んっ!これは!」

$HappyDict.Add("It came out!","Oh Yeah!")

:smile: 「いっぱい出ましたね。入力候補が!ハッピーになれそうです。」

どうやら

:smile: 「インテリセンスを効かせて書こうと思うと、これがベストなようですね。」

$HappyWay = [T[T]]::new()

もっとラクしたい

C#の時って、Listの時には、List<T>って書けば使えましたよね。

あれって、あらかじめusing System.Collections.Generic;を書いていたからです。

Powershellだと、毎回[System.Collections.Generic.List[T]]って長々書かなければいけないのでしょうか?
そんなのは嫌です。「アンパンマンマーチ」の「♪そ~んなのは い~やだ!」の部分を歌いたいです。

どうなの出来るの?

ググってみましょう!ぐぐらびりてぃ(Googlability)は最低ですが、何とか見つかりました!公式ドキュメントに書いてあるのは内緒。

:slight_smile:「これを、ps1ファイルの先頭に書いておけば、」

using namespace System.Collections.Generic

:slight_smile:「先ほどのロングスタイル初期化は、なんと!」

[List[string]]$HappyList = [List[string]]::new()

:open_mouth:「こんなに短く出来てしまいました!」

これで言うことなし

本当に良かったです!これでみんなハッピー!

:smiling_imp:「そうですか?それで満足なんですか?え?」
:smile: 「なんか聞こえるー。幻聴かなー。」
:smiling_imp: 「こういうのはどうするんだい?」

List<List<int>> DevilList = new List<List<int>>();

:smile: 「ああ、見たくないものが見える。目を背けよう」
:smiling_imp: 「さあ、このC#のコードをPowershellで表現してみなさい。」

:smiling_imp: 「もしできなければ…お前のたま」
:scream: 「やめて!お嫁に行けなくなっちゃう!」
:smiling_imp: 「…」

ネストもできる

:grinning:「めげずにやってみましょう。」

[List[List[int]]]$AngelList = [List[List[int]]]::new()

:thinking: 「インテリセンスは、」

$AngelList.Add()

:grinning:「効きました!」

あれ?初期化どうやるの?

:imp: 「これ、初期化ってどうやると思う?」
:imp: 「C#だと、こう書くやつ」

AngelNestList.Add(new List<int> { 1, 2, 3 });

:expressionless: 「やべーわかんねー」
:imp: 「こんなのもあるよな」

List<List<int>> AngelNestList = new List<List<int>>{
    new List<int>{1,2,3},
    new List<int>{4,5,6},
    new List<int>{7,8,9},
};

:scream: 「もうやだ!だれか助けてー!」
:angel_tone2: 「こんにちは!普通のGeneric Listはこうやって初期化するのよ」

[List[string]]$LinearList =[List[string]]@("1","2","3")
Write-Host $LinearList[2]

:heart_eyes:「うわ!マジ天使!」
:thinking:「てことは、ネストするときはこんな感じかな??」

[List[List[int]]]$GoList =[List[List[int]]]@(
    @(1,2,3),
    @(4,5,6),
    @(7,8,9)
)
Write-Host $GoList[1][1]

:laughing:「やった!ちゃんと5が表示された!」
:laughing:「ありがとう天使さん!…あれ?いない…。」

辞書は?

:imp: 「どうやら、初期化までインテリセンスを効かせられたようだな」
:smile: 「はい!おかげさまで!スパルタ指導ありがとうございます。」
:imp: 「それじゃあ、Dictionary<T>の初期化はどうするかな?こんなやつ」

List<Dictionary<string, string>> MyFamily = new List<Dictionary<string, string>>()
{
    new Dictionary<string, string>{{Name = "Mickey"},{Kind = "Mouse"}},
    new Dictionary<string, string>{{Name = "Pluto"},{Kind = "Dog"}},
};

:tired_face: 「もうつかれた!PSCustomObjectで代用するから許して~~~~~!」

$MyFamily = [List[PSCustomObject]]@(
    [PSCustomObject]@{ Name = "Mickey"; Kind = "Mouse" },
    [PSCustomObject]@{ Name = "Pluto"; Kind = "Dog" }
)
Write-Host $MyFamily[0].Kind

さて、続きはまたの機会に…。

ごめんなさい

「インテリセンス」の事を、「入力補完」と言ったり、「入力候補」と言ったりして分かりにくいかもです。ご容赦ください。
また、「この書き方もあるよ!」みたいなものがございましたら、コメントにて教えていただけると、はしゃぎます。

Excelsior!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?