C#好きの勉強ノート

C#やUnityを仕事で使ってきたエンジニアの勉強ノートです。

ChatGPT製 C#クイズ 2023/8/25 Unsafe、async/await、ジェネリクスの成約、with

ChatGPT製 C#クイズ Unsafe、async/await、ジェネリクスの成約、with について 2023/8/25

C#の勉強のために、ChatGPTにC#に関するクイズを出してもらいました。

入力

C# 4択の上級クイズ いくつか出して 答えはまとめて末尾に書いて

返答

もちろんです、以下にC#に関する4択の上級クイズをいくつか出題します。

クイズ1:

Unsafeコードの目的は何ですか?

  1. 非同期処理を高速化する
  2. ポインタ操作やメモリ操作を可能にする
  3. セキュリティを強化する
  4. データベース接続を安定化する

クイズ2:

async/awaitを使用すると何が可能になりますか?

  1. マルチコアの効率的な使用
  2. 非同期プログラミング
  3. インメモリデータベースの操作
  4. ジェネリクスの効率的な利用

クイズ3:

C#ジェネリクスの制約を指定するために用いられるキーワードは何ですか?

  1. where
  2. constraint
  3. limit
  4. restrict

クイズ4:

C# 9.0で導入されたwithキーワードは何のために使用されますか?

  1. 既存のオブジェクトを複製して変更する
  2. ファイル操作を簡単に行う
  3. データのシリアライゼーション
  4. 例外処理の簡略化

答え: 1. 2
2. 2
3. 1
4. 1

ChatGPTによる解説

クイズ1:

Unsafeコードの目的は何ですか? 2. ポインタ操作やメモリ操作を可能にする

C#unsafe コードは、ポインタ操作や直接的なメモリ操作が必要な場合に使用されます。通常、C# はメモリ安全な言語ですが、unsafe キーワードを用いることで、CやC++のような低レベルのメモリ操作が可能になります。

目的:

  1. パフォーマンス: 直接的なメモリ操作をすることで、特定のケースでパフォーマンスが向上する可能性があります。

  2. 相互運用性: CやC++などの他の言語で書かれたライブラリとの連携が必要な場合、unsafe コードが役立つことがあります。

  3. 特定のアルゴリズム: 低レベルのメモリ操作が必要な特定のアルゴリズムやデータ構造を実装する際にも使用されます。

例:

unsafe
{
    int var = 10;
    int* ptr = &var;
    Console.WriteLine("Data at ptr: " + *ptr); 
}

この機能はリスクが高く、メモリ不正アクセスバッファオーバーフローなどの問題を引き起こす可能性があるため、慎重に使用する必要があります。そのため、一般的なアプリケーション開発では推奨されませんが、特定のケースで非常に便利であることもあります。

参考資料・クイズ1

unsafe キーワード - C# リファレンス | Microsoft Learn https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/unsafe

unsafe - C# によるプログラミング入門 | ++C++; // 未確認飛行 C https://ufcpp.net/study/csharp/sp_unsafe.html

クイズ2は基本的すぎるので省略

クイズ3:

where キーワードは、C#ジェネリクスで型パラメータに制約を適用するために使用されます。これにより、ジェネリクスを使用する際により柔軟かつ安全なコードが書けます。

目的:

  • 型の制限: 特定の基底クラスを継承している、または特定のインターフェイスを実装しているなど、型に制約をかけることができます。

  • メンバの利用: 制約によって確定した型が持つメソッドやプロパティにアクセスできます。

  • インスタンス作成: new() 制約を用いると、ジェネリクス内で新しいインスタンスを生成することが可能になります。

具体的な使い方:

  1. 基底クラス制約
public class MyGenericClass<T> where T : MyBaseClass
{
    // ...
}
  1. インターフェイス制約
public class MyGenericClass<T> where T : IEnumerable
{
    // ...
}
  1. new() 制約
public class MyGenericClass<T> where T : new()
{
    public T CreateInstance()
    {
        return new T();
    }
}
  1. 複数の制約
public class MyGenericClass<T> where T : MyBaseClass, IEnumerable, new()
{
    // ...
}

where キーワードを用いることで、ジェネリクスをより効率的かつ安全に使うことができます。制約を使って型の能力を明示することで、コンパイル時にエラーを早期に発見したり、必要なメソッドやプロパティに安全にアクセスしたりできます。

参考資料・クイズ3

where (ジェネリック型制約) - C# リファレンス | Microsoft Learn https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/where-generic-type-constraint

ジェネリック - C# によるプログラミング入門 | ++C++; // 未確認飛行 C https://ufcpp.net/study/csharp/sp2_generics.html

クイズ4:

C# 9.0で導入されたwithキーワードは何のために使用されますか? 1. 既存のオブジェクトを複製して変更する

C# 9.0で導入されたwithキーワードは、主にレコード(record)と呼ばれる不変オブジェクトに対して非破壊的な変更を行うために使用されます。withを使用すると、オブジェクトの新しいコピーを作成し、そのコピーの一部のプロパティを変更できます。これにより、不変性を保ちつつオブジェクトの状態を簡単に更新できます。

使用例:

public record Person(string Name, int Age);

var person = new Person("Alice", 30);
var newPerson = person with { Age = 31 };

この例では、newPersonpersonのコピーを作成し、そのAgeプロパティを31に設定します。personオブジェクト自体は変更されず、新しいオブジェクトが生成されます。

withキーワードを使うことで、オブジェクトの不変性を保ちながら効率的に状態の変更を行うことができます。これは特に関数型プログラミングパラダイムに適しており、コードの可読性や保守性にも寄与します。

参考資料・クイズ4

with 式 - 既存のオブジェクトの変更されたコピーである新しいオブジェクトを作成する | Microsoft Learn https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/with-expression

レコード型 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C https://ufcpp.net/study/csharp/datatype/record/#with

私の回答

  1. 2 ○
  2. 4 ✕誤答
  3. 1 ○
  4. 1 ○
    でした。全問正解したかった…

感想

ジェネリクス」が何のことか自分にはピンときていませんでした。「ジェネリック」と同義で、クラス名の後につくTとかTResultとかのことですね。 where T : Enum という形で何回か使ったことがあります。忘れてました。

with式のありがたみを未だによく分かっていないのですが、多分普段からイミュータブルなオブジェクトをその機能を活かせず使ってるからでしょうね。あんま良くないと思います。 string型ですらイミュータブルなのに。あとUnityのVector3構造体とかもそう。 イミュータブルなコレクションや構造体を扱うときに活用したいと思います。

注意

これらの問題および解説はChatGPTのGPT-4 (ChatGPT August 3 Version)にしてもらいました。私も参考資料を確認して間違いがなさそうというのを一応確認しています。が、間違ってるところがあったらどんどん指摘してください。