

C#のdictionaryとListについて質問させてください。

（そもそも、C#の仕様的に可能か不可能か分かりませんが、）「Dictionaryが格納されたList」というものを作ろうとしています。コード的には下記のような内容です。

[code]

    inputRecord2D = new List<Dictionary<string, float>>();
    
[/code]

使用目的としては、UnityにおいてInputManagerからの入力を過去一定フレーム分格納して、格闘ゲームなどでいう「コマンド入力」を識別できる機能を搭載することです。

そして、上記のコードから値を取り出そうと…

[code]

    Debug.Log(inputRecord2D[0, "Horizontal"]);
    
[/code]

…というコードを試し書いてみたのですがエラーになります。

私としては「inputRecord2Dの0番に格納されているHorizontalというKeyの値（Value）を出力してほしい」という目的で記述したのですがエラーが発生してしまいます。エラーの内容は「error
CS1501: No overload for method 'this' takes 2 arguments」です。

そこで、お伺いしたいのですが、そもそもListの内部にDictionaryを入れ子にすることは可能なのか、もしくはやるべきではないのか？
はたまた正しい値の取り出し方があるのか？ お教えいただきたいです。

以下にペーストして検証できるコードを記載します。

[code]

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class CommandController : MonoBehaviour
    {
        public Rigidbody rigidbody;
    
        public List<Dictionary<string, float>> inputRecord2D; // すべての入力項目と入力内容をフレーム毎に格納。
        public Dictionary<string, float> inputRecord1D; // すべての入力項目と入力内容を格納。
        public int maxFrame = 10;// 最大格納フレーム数。inputRecord2Dの最大要素数。60だと過去60フレームの入力を格納することになります。
    
        void Start()
        {
            rigidbody = GetComponent<Rigidbody>();
    
            inputRecord2D = new List<Dictionary<string, float>>()
            {
                inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D, inputRecord1D
            };
            inputRecord1D = new Dictionary<string, float>()
            {
                // 本来は水平軸以外の入力も格納します。
                {"Horizontal", 0f},
            };
        }
    
        void Update()
        {
            inputRecord1D["Horizontal"] = Input.GetAxis("Horizontal");
    
            if (inputRecord2D.Count == maxFrame)
            {
                // inputRecord2Dの要素数がmaxFrameの値に達した場合は、古い要素に一つ隣の新しい要素を上書きします。
                for (int i = 0; i < inputRecord2D.Count - 1; i++)
                {
                    inputRecord2D[i] = inputRecord2D[i + 1];
                }
            }
    
            inputRecord2D[inputRecord2D.Count - 1] = inputRecord1D;
    
            Debug.Log(inputRecord2D[0, "Horizontal"]);
        }
    }
    
[/code]


CC BY-SA 4.0
2020-06-19T05:06:31.023
67805
2020-06-20T02:43:23.683
2020-06-19T05:08:07.643
3060
40733
question
c# unity3d
「Dictionary型のList」というものを作ることはできるのでしょうか？


コメントの内容で解決したということで回答として書きます。

まずタイトルの **「Dictionary型のList」というものを作る**
については、コード上の定義・初期化・操作の部分が正常にビルド出来て実行時にエラー・例外が発生していないので、問題無く作れている(可能である)ということでしょう。

そしてエラーになった`Debug.Log(inputRecord2D[0, "Horizontal"]);`と、そのエラー`error CS1501: No
overload for method 'this' takes 2 arguments`ですが、日本語の記事はこちら。  
[コンパイラ エラー CS1501](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-
reference/compiler-messages/cs1501)

> 引数 '<数値>' を指定するメソッド '<メソッド>' のオーバーロードはありません  
>  クラスのメソッドの呼び出しを試みましたが、このメソッドの定義には、指定された数の引数を指定できません。

これを適用すると「`this`というメソッドには2つの引数を指定する形式の処理は存在しない」ということですが、直接的にはどういう状況かは判り難いですね。

そこで少し見る点を変えると、値の指定方法として配列にアクセスしようとしているけれども添え字がカンマで2つ並んでいるようなのが怪しい訳です。

実態として正しいか分かりませんが、Dictionary型を入れ子にしたListというのを2次元配列だと考えれば、Listの添え字とDictionaryのKeyはそれぞれ独立した次元の添え字と見做せるので、1つの`[
]`の中に`,`(カンマ)で並べるのではなく、`[Listの添え字][DictionaryのKey]`として`Debug.Log(inputRecord2D[0]["Horizontal"]);`というように指定すれば良いでしょう。


CC BY-SA 4.0
2020-06-20T02:43:23.683
67821
2020-06-20T02:43:23.683
26370
67805
answer