1

目標: 辞書から値を取得します。上記の値は、キーとして辞書を持っています。

私がやっていること: 値を取得しようとしているキーとまったく同じ値を持つ 2 つ目の辞書を作成しています。使用するTryGetValue

結果: 値が必要ですが、null になります。

コンテキスト: Unity でクラフト機能を作ろうとしています。これは、クラフト材料のクラスがどのように見えるかです (ICombinable は現在まったく同じように見えます):

public class Ingredient : ICombinable
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public Effect Effect { get; set; }
    }

実際には、ユーザーがタイプ ICombinable のオブジェクトを UI (実装されていない) にドラッグし、ボタンを押してそれらを新しいアイテムに結合できるようにしたいと考えています。たとえば、ハーブ 2 本と水 1 杯で回復ポーション (新しいアイテム) が返ってきます。

サーフェスの背後で、ドラッグ/選択されたオブジェクトをDictionary<ICombinable, int>int が あたりの量である に保存しますICombinable

別のクラスでは、すべてのレシピを保持する別の Dictionary を保存しています。

public class Combiner
{
        private Dictionary<Dictionary<ICombinable, int>, ICraftable> _recipebook;

        public Combiner()
        {
            _recipebook = new Dictionary<Dictionary<ICombinable, int>, ICraftable>(); // <Recipe, Item it unlocks>
        }

        public void AddRecipe(Dictionary<ICombinable, int> recipe, ICraftable item) =>  _recipebook.Add(recipe, item);
        
        public ICraftable Craft(Dictionary<ICombinable, int> ingredientsAndAmount) =>
            _recipebook.TryGetValue(ingredientsAndAmount, out var item) == false ? null : item;
        //FirstOrDefault(x => x.Key.RequiredComponents.Equals(givenIngredients)).Value;
    }

_recipebook のキーは、材料とその量で構成される実際のレシピです。ICraftable は、そのレシピに対応するオブジェクト/アイテムです。前に示した例では、ICraftable はヒーリング ポーションであり、2 本の棒とコップ 1 杯の水はそれぞれ、その値のキーである辞書のエントリになります。

そして最後に、Craft メソッドは辞書 (つまり、材料とその量のリスト) を受け取り、指定された辞書に対応する項目を _recipebook でチェックしたいと考えています。成分の組み合わせが有効な場合は項目を返し、それ以外の場合は null を返します。

この機能のテスト方法: プロジェクトを開始したばかりなので、単体テストから始めたいと思いました。セットアップは次のとおりです。

[Test]
    public void combiner_should_return_healing_potion()
    {
        // Use the Assert class to test conditions
        var combiner = new Combiner();
        var item = new Item
        {
            Name = "Healing Potion",
            Unlocked = false
        };

    
        combiner.AddRecipe(new Dictionary<ICombinable, int>
        {
            {new Ingredient {Name = "Herb", Description = "Has healing properties", Effect = Effect.Heal}, 3},
            {new Ingredient {Name = "Water", Description = "Spring water", Effect = default}, 1},
            {new Ingredient {Name = "Sugar", Description = "Sweetens", Effect = default}, 2}
        },
        item);

        var actualItem = combiner.Craft(new Dictionary<ICombinable, int>
        {
            {new Ingredient { Name = "Herb", Description = "Has healing properties", Effect = Effect.Heal} , 3},
            {new Ingredient {Name = "Water", Description = "Spring water", Effect = default}, 1},
            {new Ingredient {Name = "Sugar", Description = "Sweetens", Effect = default}, 2}
        });
        
        Assert.That(actualItem, Is.EqualTo(item));

    }

結果:

combiner_should_return_healing_potion (0.023s)
---
Expected: <Models.Item>
  But was:  null
---

ヒーリングポーションというアイテムとそのレシピとなる辞書を作成中です。これらをレシピブックに追加します。その後、ユーザーの入力を「シミュレート」するための 2 つ目の辞書を作成しています。辞書の内容は、私が Add Recipe() でレシピブックに追加しているものとまったく同じです。TryGetValueこれらの 2 つの辞書が同等であると見なされないのはなぜでしょうか。

機能させるにはどうすればよいですか?

4

2 に答える 2