rksoftware

Visual Studio とか C# とかが好きです

C# 9.0 の確認「静的な匿名関数」

C# 9.0 の確認の目次はこちら

■ 静的な匿名関数

ドキュメントはこちら

適合性と完成度の機能 という項目の割と読み進めた所の 「C# 9.0 以降では、」 から始まるブロックです。
名前の通りにラムダ式と匿名関数に static 修飾子をつけられるようになりました。シンプルなのでドキュメントに書いてあることしか言えませんね。

公式ドキュメントだけで十分という気がしますが試してみましょう。

■ 検証コードと結果

■ ラムダ式

冷静に見ないと一瞬わからなくなるかもしれませんが、こんな感じです。

new[] { 0 }.Select(static x => x);

static なので外部の変数をキャプチャできません。素晴らしいですね。

var i = 0;
new[] { 0 }.Select(static x => x + i); // これはエラー

変数 i はラムダ式の外の変数なのでエラーになります。

■ 匿名関数

匿名関数とか 10,000 年ぶりに書いた気がします。

new[] { 0 }.Select(static delegate (int x) { return x; });

static なので外部の変数をキャプチャできません。素晴らしいですね。

var i = 0;
new[] { 0 }.Select(static delegate (int x) { return x + i; }); // これはエラー

変数 i は匿名関数の外の変数なのでエラーになります。

■ まとめ

変数キャプチャができなくなるのはうれしいですね。積極的に使っていきましょう

Visual Studio の 16.8.3 がリリースされました

Visual Studio のアップデート 16.8.3 がリリースされました。

今回は誰でも踏みえる脆弱性の対応も含まれています。私も素早くアップデートします。

■ 更新内容

今回も複数の問題がありますが、いくつかは結構大問題もあります。ただ今回はたいてい箇条書きだけで詳細がわかりません。
そこから読み取れるものだけ観てみます(再現条件も原因もよくわからないですし)。

問題の解決

次の問題が対策されました。

  • 最初の 3 県は C++ 関連のようです。
  • .NET Core の WinForms のデザイナを触っていると Visual Studio がクラッシュする問題
  • UI コンテキストのツール ウィンドウが Visual Studio のクラッシュを起こす問題
  • リモードブランチがない場合の Git nプッシュの動作を修正
  • 関数(functions?)を Azure にパブリッシュしようとすると System.ArgumentException: Event name should have at least 3 parts separated by slash. というエラーになる
  • ツールバーのカスタマイズが記憶されない。Visual Studio を終了するとリセットされる

機能追加

  • .NET 5.0.1 対応
  • Xcode 12.2 対応

■ 脆弱性

リポジトリをクローンする際にリモートコード実行の脆弱性対策

なるべく早くアップデート

今回は誰もが踏む可能性のある脆弱性が対策されています。迷わずアップデートしておきましょう。

■ 更新方法

Visual Studio の更新はメニューの ツール > ツールと機能を取得 で開くインストーラーから行えます。

C# 9.0 の確認「ターゲット型の新しい式」

C# 9.0 の確認の目次はこちら

■ ターゲット型の新しい式

ドキュメントはこちら
適合性と完成度の機能 という項目の一つ目のブロックです。

機能の名前だけを見ても想像しづらいですが、 new 式 という式が追加されました。雑にいうと型がわかっているところで new するときに型を書く必要がなくなりました。最近流行りの言語でよくあるやつですね。

公式ドキュメントだけで十分という気がしますが試してみましょう。

■ 検証コードと結果

■ 変数

変数は宣言時に型を書いていれば、これからは new で型を書く必要はありません。変数の型を書いているので var で書くのと長さはあまり変わりませんが *1。

System.Collections.Generic.List<int> hoge = new();
Console.WriteLine(hoge.GetType().FullName);

結果

System.Collections.Generic.List`1[[System.Int32,......

*1 都市伝説として語られる var 禁止の現場でこの式が受け入れられるか注目したいです。

■ フィールド

フィールドは宣言で型を絶対に書くので、常に new で型を書く必要はありません。フィールドを書く機会自体がそれほどはない方も多いかもしれませんが *2。

static System.Collections.Generic.List<int> Hoge = new();

static void Main(string[] args)
{
    Console.WriteLine(Hoge.GetType().FullName);
}

結果

System.Collections.Generic.List`1[[System.Int32,......

*2 都市伝説として語られる var 禁止の現場ではプロパティよりフィールドが主流かもしれないので、フィールドでのこの式の使用が流行るか注目したいです。

■ プロパティ

プロパティでも、これからは new だけで OK です *3。

static System.Collections.Generic.List<int> Hoge { get; set; } = new();

static void Main(string[] args)
{
    Console.WriteLine(Hoge.GetType().FullName);
}

結果

System.Collections.Generic.List`1[[System.Int32,......

*3 都市伝説として語られる var 禁止の現場は自動実装プロパティが禁止されているかもしれないので、この式が受け入れられるかと共にそろそろ自動実装プロパティが許されるか注目したいです。

■ 引数

メソッドの引数でも、new だけで引数の型で作られます。これは今後基本になりそうですね *4。

static void Fuga(System.Collections.Generic.List<int> hoge)
    => Console.WriteLine(hoge.GetType().FullName);

static void Main(string[] args)
{
    Fuga(new());
}

4 都市伝説として語られる var 禁止の現場で、禁止の理由のマイナーな方に「ソースコードを紙に印刷したときに型がわからない」というのがあると聞いています。それが理由ならこの式も何気に厳しそうです。ソースコードを紙に印刷して確認している現場でこの式が受け入れられるか注目したいです 5。

■ 初期化子

new() の後ろに初期化子も書けます。これは少し気持ち悪い気もしますが。

System.Collections.Generic.List<int> hoge = new (){ 0, 1, 2 };
Console.WriteLine(string.Join(", ", hoge));
0, 1, 2

何となく気持ち悪いのは、残念ながらこうは書けなかったところですね。

List<int> hoge = new { 0, 1, 2 };

よく考えたらこれは別の意味になってしまうから仕方ないですね。

■ まとめ

タイプ数が短くなるのでいいと思います。慣れないと気持ち悪いという方もいるかもしれませんが、ほかの言語では大体こうなっているので時代ですね。
これから急激に主流になってくるはずです *6。備えましょう。

5 var 禁止の理由のメジャーな方は「var で宣言した変数には型がない」と言語仕様を誤って認識していることのようです。
6 都市伝説として語られる var 禁止の現場はずっと .NET Framework 4.8 で .NET に移行しない可能性もありますが、.NET に移行できて主流になれるのか注目したいです。

秋葉原 C# もくもく会 #146 勉強会を開催しました

■ C# もくもく会

C# もくもく会 #146 を開催しました。

C# もくもく会 は東京の秋葉原で毎週木曜日に開催している .NET 系の勉強会です。
もくもく自習を基本とし、分からないことを教えあったり情報共有したりしている会です。 定期開催していますので、お時間のある時に遊びに来ていただければと思います。
ちょっと詰まった時、ネット上で聞くのははずかしいなぁ、という課題のできた時などにも思い出していただけると嬉しいです。

f:id:rksoftware:20201205192654j:plain

写真は会場近くの串屋さんのハムです。

■ 新タイプの会場

今週も、もくもくの日でした。
最近世間が暗い感じ(個人の感想です。個人差があります)なので、この会が良い灯になっていると思います。

  • 焚火がしたいです。都内や埼玉・千葉でも焚火のできる場所はあるのですね。
  • ソロキャンプもくもく会?

ちなみにこの勉強会ですが、実は公序良俗に反しなければどのような技術を扱っても大丈夫です。そもそも C# エンジニアが C# だけしか使わないというわけではありませんし。

■初心者歓迎

このもくもく会には、入門者の方も多くご参加いただいています。 突然 C# やらなければならなくなって途方に暮れている方、何となく C# をやってきたけど改めて見直してみたい方なども大歓迎です。
入門セミナー代わりでのご参加も歓迎です。プログラミング入門者の方も是非遊びに来てください。

特に C# で課題をお持ちでなくても是非遊びに来てください。

■ 目指す勉強会スタイル

世界一敷居の低い勉強会を目指しています。

何か聞きたいことがある場合は、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

何か共有したい情報を見つけた場合も、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

そんなスタイルでやっています。

■ 次回予定

最近の情勢により今後の開催は不透明ですが、とりあえず
次回は 2020/12/10 に開催予定です。

C# に関心のある方、是非遊びに来てください。

.NET 5 の確認「単一ファイルの配置と実行可能ファイル」

■ .NET 5 の単一ファイルの配置と実行可能ファイル

ドキュメントはこちら

.NET Core 3.1 までは単一ファイルとはいうものの、自己展開形式書庫ファイルのようなものでした。実行時に OS の Temp フォルダに必要なファイルが展開されるというものでした。
これは配布は楽だったのですが、マシンのディスク領域を圧迫するし、ユーザーが自分で Temp に展開されたファイルを狙って削除する (アンインストール的な) のも簡単ではなかったです。

.NET 5 ではファイルが展開されることなく実行されます。これはうれしいですね。単一ファイルの機能ができたとき当初こちらの動作を期待した方も多かったのではないでしょうか?

■ 注意点

この .NET 5 の単一ファイルを使うと使えない API や動作の変わる API があります。
といってもそう気にする必要はなく、Assembly のパスなどが取得できなかったりするだけです。代替手段のドキュメントに記載があるので安心です。

ちなみに私は検証コードで最初 Assembly.Location を書いてはまりました (.NET 5 の単一ファイルでは常に null)。

■ 使い方

使い方は簡単です。というか何もする必要がありません。
プロジェクトのターゲット フレームワークが .NET 5 であれは新しい動作になります。

■ 検証コード

コードを書いて発行、実行して確認してみます。
プロジェクトは ClassLibrary1.dll というライブラリを参照をしています。ファイルが展開されていてば、2 つ目の出力が True になるはずです。

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(AppContext.BaseDirectory);
        Console.WriteLine(System.IO.Directory.GetFiles(AppContext.BaseDirectory).Any(f => f.EndsWith("ClassLibrary1.dll")));
    }
}

■ 結果

.NET Core 3.1

C:\Users\<ユーザー名>\AppData\Local\Temp\.net\ConsoleApp1\<ランダムな文字列>\
True

.NET 5

※発行した .exe ファイルをその場で実行しています。

<プロジェクトのディレクトリ>\ConsoleApp1\bin\Release\net5.0\publish\
False

■ まとめ

実行時に展開されなくなったことで、より扱いやすくなりました。
.NET 5ClickOnce が復活しましたが、ものによっては配布はこの単一ファイル機能で事足りるかもしれません。

ClickOnce 参考

選択肢として備えましょう。

C# 9.0 の確認「ネイティブ サイズの整数」

C# 9.0 の確認の目次はこちら

■ ネイティブ サイズの整数

ドキュメントはこちら

パフォーマンスと相互運用 という項目の二つ目のブロック (3行目の「ネイティブサイズの整数~」)です。
ninnuint という型が追加されました。雑にいうと 32 ビット環境では 32 ビット整数型に 64 ビット環境では 64 ビット整数型になるとのことです。

整数型についてのドキュメントはこちら

32 ビットでは int と同じ、64 ビットでは long と同じサイズ。

■ 検証コード

次のようなコードを動かしてみました。

Console.WriteLine($"int   : Type = {typeof(int).FullName, 14} : MinValue = {int.MinValue, 20} : MaxValue : {intMaxValue, 20}");
Console.WriteLine($"nint  : Type = {typeof(nint).FullName,14} : MinValue = {nint.MinValue,20} : MaxValue : {nintMaxValue,20}");
Console.WriteLine($"long  : Type = {typeof(long).FullName,14} : MinValue = {long.MinValue,20} : MaxValue : {longMaxValue,20}");
Console.WriteLine($"uint  : Type = {typeof(uint).FullName,14} : MinValue = {uint.MinValue, 20} : MaxValue : {uintMaxValue, 20}");
Console.WriteLine($"nuint : Type = {typeof(nuint).FullName,14} : MinValue = {nuint.MinValue, 20} : MaxValue : {nuintMaxValue, 20}");
Console.WriteLine($"ulong : Type = {typeof(ulong).FullName,14} : MinValue = {ulong.MinValue,20} : MaxValue : {ulongMaxValue,20}");

■ 結果

64 ビット (x64)

int   : Type =   System.Int32 : MinValue =          -2147483648 : MaxValue :           2147483647
nint  : Type =  System.IntPtr : MinValue = -9223372036854775808 : MaxValue :  9223372036854775807
long  : Type =   System.Int64 : MinValue = -9223372036854775808 : MaxValue :  9223372036854775807
uint  : Type =  System.UInt32 : MinValue =                    0 : MaxValue :           4294967295
nuint : Type = System.UIntPtr : MinValue =                    0 : MaxValue : 18446744073709551615
ulong : Type =  System.UInt64 : MinValue =                    0 : MaxValue : 18446744073709551615

32 ビット (x86)

int   : Type =   System.Int32 : MinValue =          -2147483648 : MaxValue :           2147483647
nint  : Type =  System.IntPtr : MinValue =          -2147483648 : MaxValue :           2147483647
long  : Type =   System.Int64 : MinValue = -9223372036854775808 : MaxValue :  9223372036854775807
uint  : Type =  System.UInt32 : MinValue =                    0 : MaxValue :           4294967295
nuint : Type = System.UIntPtr : MinValue =                    0 : MaxValue :           4294967295
ulong : Type =  System.UInt64 : MinValue =                    0 : MaxValue : 18446744073709551615```

実態としては System.IntPtr で、サイズはそれぞれ longint と同じになりました。

■ まとめ

この機能は誰もが使う機能というわけではないかもしれません。
しかし、こういった機能が強化されるということはそういったことにも当たり前に C# が使われるようになっているという証拠だと思います。今はなくとも、いずれそういった機能を使う日が来るでしょう。備えましょう。

秋葉原 C# もくもく会 #145 勉強会を開催しました

■ C# もくもく会

C# もくもく会 #145 を開催しました。

C# もくもく会 は東京の秋葉原で毎週木曜日に開催している .NET 系の勉強会です。
もくもく自習を基本とし、分からないことを教えあったり情報共有したりしている会です。 定期開催していますので、お時間のある時に遊びに来ていただければと思います。
ちょっと詰まった時、ネット上で聞くのははずかしいなぁ、という課題のできた時などにも思い出していただけると嬉しいです。

f:id:rksoftware:20201128175002j:plain

写真は会場近くのカレー屋さんです。秋葉原にお越しの際はお勧めです!

■ 新タイプの会場

今週も、もくもくの日でした。

  • C# 9!。
  • OpenCV!
  • Unity!
  • Vue.js

ちなみにこの勉強会ですが、実は公序良俗に反しなければどのような技術を扱っても大丈夫です。そもそも C# エンジニアが C# だけしか使わないというわけではありませんし。

■初心者歓迎

このもくもく会には、入門者の方も多くご参加いただいています。 突然 C# やらなければならなくなって途方に暮れている方、何となく C# をやってきたけど改めて見直してみたい方なども大歓迎です。
入門セミナー代わりでのご参加も歓迎です。プログラミング入門者の方も是非遊びに来てください。

特に C# で課題をお持ちでなくても是非遊びに来てください。

■ 目指す勉強会スタイル

世界一敷居の低い勉強会を目指しています。

何か聞きたいことがある場合は、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

何か共有したい情報を見つけた場合も、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

そんなスタイルでやっています。

■ 次回予定

最近の情勢により今後の開催は不透明ですが、とりあえず
次回は 2020/12/03 に開催予定です。

C# に関心のある方、是非遊びに来てください。