i-school - ランダムなアルファベット文字列を生成する機能
 指定した長さのランダムなアルファベット文字列を生成する機能の実装例です。



AlphabetManager クラス



using System;

public static class AlphabetManager
{
    private static readonly string Alphabets = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /// <summary>
    /// 指定された長さのランダムなアルファベット文字列を生成します。
    /// デフォルトでは文字列の長さは5です。
    /// </summary>
    /// <param name="length">生成するアルファベット文字列の長さ。</param>
    /// <returns>指定された長さのランダムなアルファベット文字列。</returns>
    public static string GetRamdomAlphabet(int length = 5)
    {
        // 乱数生成器のインスタンス
        Random random = new();
        
        // 指定されたアルファベット文字列を指定された回数だけ繰り返し、
        // それぞれからランダムに1文字ずつ選び、新しい文字列を生成する
        string result = "";
        
        for (int i = 0; i < n; i++)
        {
            result += txt[random.Next(txt.Length)]; 
        }
        
        return result;
    }
}


解説


 Random クラスにある Next メソッドを利用して、事前に用意しておいた文字列からランダムな文字1つを抽出し、
それを指定回数繰り返すことでランダムな文字の文字列を生成しています。

 この処理の場合、各文字が Alphabets からランダムに選択されているため、同じ文字が複数回選ばれる可能性があります
例えば、"aaaaa"や"abcde"のような結果も発生する可能性があります。

 ランダムな文字列生成では、重複や特定のパターンが発生する可能性に留意することが重要です。


<リファクタリング>


 LINQ を活用した場合には、以下のようにリファクタリングできます。

using System;
using System.Linq;

public static class AlphabetManager
{
    private static readonly string Alphabets = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

    /// <summary>
    /// 指定された長さのランダムなアルファベット文字列を生成します。
    /// デフォルトでは文字列の長さは5です。
    /// </summary>
    /// <param name="length">生成するアルファベット文字列の長さ。</param>
    /// <returns>指定された長さのランダムなアルファベット文字列。</returns>
    public static string GetRamdomAlphabet(int length = 5)
    {
        // 乱数生成器のインスタンス
        Random random = new();

        return new string(Enumerable.Repeat(Alphabets, length)
            .Select(alphabet => alphabet[random.Next(alphabet.Length)])
            .ToArray());
    }
}



 Enumerable.Repeatで指定した長さの文字列を生成し、それを Select でランダムに選択し、
ToArray で文字配列に変換して、最終的に new string で文字列に戻しています。

        // 上記処理を LINQ で置き換えた場合
        return new string(Enumerable.Repeat(Alphabets, length)
            .Select(alphabet => alphabet[random.Next(alphabet.Length)])
            .ToArray());

 Enumerable.Repeat(Alphabets, length) によって Alphabets が length 回繰り返されることになります。
したがって、Select のラムダ式内の引数である alphabet は Alphabets そのものを指します。この部分で各文字列が random.Next(alphabet.Length) でランダムに選択されています。

 指定された alphabet 文字列からランダムに1つの文字を選択しています。
つまり、alphabet[random.Next(alphabet.Length)] は、alphabet 文字列の中からランダムに1文字を選択しています。
この処理を length 回繰り返しているので、最終的に length 個のランダムな文字列ができ、リファクタリング前と同じ処理になります。


<重複しない文字を指定数選択する>


 例えば、重複しない文字を指定数選択するのであれば、以下のような実装方法があります。


using System.Text;


/// <summary>
/// 指定された長さのランダムなアルファベット文字列を生成します。重複なしバージョン。
/// デフォルトでは文字列の長さは5です。
/// </summary>
/// <param name="length">生成するアルファベット文字列の長さ。</param>
/// <returns>指定された長さのランダムなアルファベット文字列。</returns>
public static string GetRandomUniqueAlphabet(int length = 5)
{
    Random random = new();
    
    // 選択した文字を保持するためのHashSet
    HashSet<char> selectedChars = new HashSet<char>();

    // 文字列の長さがアルファベットの種類数を超える場合は、種類数に合わせる
    length = Math.Min(length, Alphabets.Length);

    // StringBuilderのインスタンスを作成
    StringBuilder resultBuilder = new StringBuilder();

    // 選択された文字が指定の長さに達するまで繰り返す
    while (selectedChars.Count < length)
    {
        // アルファベット文字列からランダムに1文字選ぶ
        char selectedChar = Alphabets[random.Next(Alphabets.Length)];

        // 重複を防ぐため、HashSetに追加できた場合のみ保持する
        if (selectedChars.Add(selectedChar))
        {
            // selectedChar がまだ選択されていない場合は結果に追加する
            resultBuilder.Append(selectedChar);
        }
    }

  // 文字列を作成して戻す
    return resultBuilder.ToString();
}

 この実装では、HashSet を使って選択された文字を保持し、新たに選ばれた文字が既にセットに含まれていない場合のみ追加します。
これにより、ランダムな文字列が指定された長さに達するまで、重複することがありません。
HashSet は重複しない前提で利用できるコレクション機能ですので、こういった場面で便利です。


MicroSoft
HashSet<T> クラス

https://learn.microsoft.com/ja-jp/dotnet/api/syste...



 また Math.Min メソッドを利用し、指定された長さ length がアルファベットの種類数を超えないように確認しています。
もし length が Alphabets.Length よりも大きい場合は、length を Alphabets.Length に制限することで、いずれか小さい方に収まるようにしています。
これにより、アルファベットの種類数を超えるような指定がされた場合でも、不正なインデックスが発生せずに済みます。

 なお、StringBuilder の初期値は string.Empty(長さ 0 の文字列("")) です。
仮に length が 0 の場合、while 文は実行されません。そのため、StringBuilder 型の resultBuilder 変数の値は "" です。
よって ToString メソッドの結果も長さ 0 の文字列("") になります。万が一の場合にも null エラーにはなりません

MicroSoft
StringBuilder コンストラクター

https://learn.microsoft.com/ja-jp/dotnet/api/syste...


<リファクタリング>


 LINQ を活用した場合には、以下のようにリファクタリングできます。


/// <summary>
/// 指定された長さのランダムなアルファベット文字列を生成します。重複なしバージョン。
/// デフォルトでは文字列の長さは5です。
/// </summary>
/// <param name="length">生成するアルファベット文字列の長さ。</param>
/// <returns>指定された長さのランダムなアルファベット文字列。</returns>
public static string GetRandomUniqueAlphabet(int length = 5)
{
    Random random = new();
        
  length = Math.Min(length, Alphabets.Length);

    // LINQを使用して重複なしのランダムな char[] 配列を生成(この時点では文字列(string)ではない)
    char[] result = Enumerable.Range(0, length)
                   .Select(_ => Alphabets[random.Next(Alphabets.Length)])
                     .Distinct()
                     .ToArray();

    // char 配列から新しい文字列(string)を作成して戻す
    return new string(result);

 このリファクタリングでは、Enumerable.Rangeを使用して引数で指定した数値のシーケンスを生成し、
Select メソッドを利用して各数値に対してアルファベットからランダムな文字を選択します。
そして、Distinctメソッドを使用して結果に重複がないようにします。

 最後に、結果を char 配列に変換して、その char 配列から新しい文字列(string)を作成します。



 この処理を応用すれば、数字や記号を含めたランダムな文字列も生成可能です。