rksoftware

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

C# 2.0 以降の新機能の確認 - C# 9.0 - ラムダ ディスカード パラメーター

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

ラムダ ディスカード パラメーター

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/lambda-expressions#input-parameters-of-a-lambda-expression
 ラムダ式のパラメータで使わないものが複数ある場合に、_ と書くと該当のパラメータを使えなくできる。

// 一つ目のパラメータも二つ目のパラメータも使わない場合
new int[0].Select((_, _) => 0);
// _ は破棄なので変数名になっていない。次のコードはエラーとなってくれてうれしい
new int[0].Select((_, _) => _);  // 現在のコンテキストに '_' という名前は存在しません  

C# 2.0 以降の新機能の確認 - C# 9.0 - foreach ループの拡張機能 GetEnumerator サポート

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

foreach ループの拡張機能 GetEnumerator サポート

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/foreach-in
 拡張メソッドで GetEnumerator メソッドを作ればどんな型のオブジェクトでも foreach できる。

var data = new Data { MyProperty1 = "Saitama", MyProperty2 = "Chiba", MyProperty3 = "Ibaraki" };

// 拡張メソッド GetEnumerator で foreach
foreach (string datum in data)
    Console.WriteLine(datum);

// GetEnumerator を持たない型
class Data
{
    public string MyProperty1 { get; set; }
    public string MyProperty2 { get; set; }
    public string MyProperty3 { get; set; }
}

// 拡張メソッド GetEnumerator
static class DataExtensions
{
    internal static System.Collections.IEnumerator GetEnumerator(this Data data)
        => new string[] { data?.MyProperty1, data?.MyProperty2, data?.MyProperty3 }.GetEnumerator();
}

C# 2.0 以降の新機能の確認 - C# 9.0 - 共変の戻り値の型

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

共変の戻り値の型

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/override
 戻り値の型を共変できる。override したメソッドの戻り値の型を、スーパークラスのメソッドの戻り値の型のサブクラスにできる。

A a = new B();
IEnumerable<int> list = a.Method(); // return 値の型は List<int>

internal class A
{
    public virtual IEnumerable<int> Method() { return null; }
}

internal class B : A
{
    // 以前は戻り値の型を変えられなかった。今はサブクラスに変えられる
    public override List<int> Method() { return new List<int>(); }
}

C# 2.0 以降の新機能の確認 - C# 9.0 - ターゲットにより型指定された条件式

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

ターゲットにより型指定された条件式

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/conditional-operator
 三項演算の型の解決が賢くなった。

// 以前はエラーになったコード。List<int> でも int[] でも IEnumerable<int> に代入できるはずだが、
// それ以前に三項演算の結果の型が推論できずにエラーになっていた。今は大丈夫
IEnumerable<int> list = true ? new List<int>() : new int[0];

C# 2.0 以降の新機能の確認 - C# 9.0 - 静的な匿名関数

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

静的な匿名関数

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/lambda-expressions#capture-of-outer-variables-and-variable-scope-in-lambda-expressions
 ラムダ式と匿名関数に static 修飾子をつけられるようになった。 ※例では匿名関数は省略。

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

mac をきれいにするときに苦労した話

mac をきれいに (再インストール) するときは、ディスクを消去してインターネットからダウンロードして OS を再インストールするらしいです。
かなりはまったのでメモ。普通はきれいにしたりしないのかもしれませんが、几帳面なので。

はまりポイントは 2 箇所。

  1. インターネットからダウンロード
    インターネット接続が必要です。知らなかったのでここでだいぶハマりました。また、ディスク消去前の設定もなくなる (そこもきれいになって欲しいしまあそうですよね) ようでそこもはまりポイント。
  2. 再インストールは起動時に command+R で開くメニューから行うらしいですが
    このメニューから再インストールしても途中でエラーになってうまくいかず
    対策は起動時に option+command+R で開くメニューから再インストール。

command+R と option+command+R ではインストールされる OS バージョンが違うみたいです。

これで何とかなりました。

C# 2.0 以降の新機能の確認 - C# 9.0 - ターゲット型の新しい式

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

ターゲット型の新しい式

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/new-operator
 new 式 という式が追加された。 型がわかっているところで new するときに型を書く必要がなくなった。

// 変数宣言
System.Collections.Generic.List<int> hoge1 = new();

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

// 初期化子
System.Collections.Generic.List<int> hoge2 = new() { 0, 1, 2 };

class Class
{
    // フィールド
    internal static System.Collections.Generic.List<int> Hoge3 = new();
    // プロパティ
    internal static System.Collections.Generic.List<int> Hoge4 { get; set; } = new();
}