LoginSignup
5
10

More than 5 years have passed since last update.

C言語の知識に囚われたC#コードを改善する 第ニ弾

Last updated at Posted at 2018-05-08

関連記事一覧

第一弾
第二弾(本記事)

直したいポイント

配列の呪縛 その3

こんなふうに配列を使っている場合もありました。

string[] keys = new string[]
{
  "zero",
  "one",
  "two",
};
int[] values = new int[] { 0, 1, 2 };

public int Hoge(string key)
{
  var index = keys.IndexOf(key); // for を駆使する場合もある。
  // エラー判定は省略
  return values[index];
}

上のコードをクラス or 構造体を使った場合はこうなります。

class KeyValue
{
   public string Key { get; set; }
   public int Value { get; set; }
}

KeyValue[] KeyValueArray = new KeyValue[]
{
    new KeyValue { Key = "zero", Value = 0 },
    new KeyValue { Key = "one",  Value = 1 },
    new KeyValue { Key = "two",  Value = 2 },
}

public int Hoge(string key)
{
    foreach (var item in KeyValueArray)
    {
        if (item.Key == key)
        {
            return item.Value;
        }
    }
    // エラー処理は省略
}

上記二つのコードは関連のある keys 配列と values 配列を変換や検索に用いる方法です。

前者は keys と values の同じインデックスの値が結びついているのは 単なる暗黙の了解 にすぎず、修正時にインデックスがズレて意図しない結果になる場合もがあります。

後者は結びつきが強化されましたが、以下の点に注意が必要です。

  • Key の値に重複があった場合を考慮する必要がある。
  • 検索結果が配列の末尾付近にあるほど処理の実行が遅くなる。

しかし、実はこういった機能は 標準で用意されているのです!

Dictionary<string, int> dict = new Dictionary<string, int>
{
  ["zero"] = 0,
  ["one"]  = 1,
  ["two"]  = 2,
};

public int Hoge(string key)
{
  // dict[key] もできるが、値がない時は例外になる。
  if (dict.TryGetValue(key, out var value))
  {
    return value;
  }
  // エラー時の処理は省略
}

key と value の関連が明確になり、判定処理も簡単になりました。
そして、Dictionary はハッシュ値を使って要素を検索するため、 要素数が多くなっても高速 です。

ちなみに Dictionary を foreach にかけると、 KeyValuePair<TKey, TValue> という要素が帰ります。

var dict = new Dictionary<string, int>();
foreach (KeyValuePair<string, int> kvp in dict)
{
    // 何か処理
}



他にも項目を挙げようとしましたが、間違って投稿してしまったため、第三段に先送りします。

5
10
4

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
5
10