通常搜索3个单独的词典以获得价值

时间:2015-01-31 02:45:15

标签: c# dictionary

我有一个正在进行的在线游戏,我正试图以这种方式解决我如何能够使用通用的3个不同词典获得单个结果搜索功能。

这适用于玩家的视线,但不会在循环中使用。

    protected Dictionary<UInt32, Character> _currentVisibleCharacters;
    protected Dictionary<UInt32, Item> _currentVisibleMapItems;
    protected Dictionary<UInt32, Npc> _currentVisibleNpcs;

    public Boolean GetVisibleObject<TObject>(UInt32 objId, out TObject obj) 
        where TObject : WorldObject
    {
          //I need to be able to search all 3 dictionaries with this function.
    }

它应该使用&#34; objId&#34;在3个词典中的任何一个中搜索现有的键/值对。一旦找到,它应该将找到的值赋给参数&#34; obj&#34;。我已经尝试过使用LINQ,但是我遇到了一些问题,例如,从字段_currentlyVisisbleNpcs中分配Npc值到&#34; obj&#34;参数。

Character,Item和Npc继承自WorldObject。

3 个答案:

答案 0 :(得分:1)

我假设你需要检查类型,这样你才能从错误的词典中得到一些东西。

    public Boolean GetVisibleObject<T>(UInt32 objId, out T obj) 
        where T : WorldObject
    {
          //I need to be able to search all 3 dictionaries with this function.
          //It should use "objId" to search for an existing key in either of the 3.

        obj = null;

        if (typeof(T) == typeof(Character))
        {
            if (_currentVisibleCharacters.ContainsKey(objId))
            {
                obj = _currentVisibleCharacters[objId] as T;
                return true;
            }
        }
        else if (typeof(T) == typeof(Item))
        {
            if (_currentVisibleMapItems.ContainsKey(objId))
            {
                obj = _currentVisibleMapItems[objId] as T;
                return true;
            }
        }
        else if (typeof(T) == typeof(Npc))
        {
            if (_currentVisibleNpcs.ContainsKey(objId))
            {
                obj = _currentVisibleNpcs[objId] as T;
                return true;
            }
        }           

        return false;

    }

答案 1 :(得分:0)

public TObject GetVisibleObject<TObject>(UInt32 objId) 
    where TObject : WorldObject, new()
{
     WorldObject match = null;

     match = _currentVisibleCharacters[objId];

     if (match == null)
        match = _currentVisibleMapItems[objId];

    if (match == null)
        match = _currentVisibleNpcs[objId];


    return (TObject)match;
}

由于存储在字典中的所有值都继承自WorldObject,因此您可以将每个可能的匹配返回给WorldObject,然后转换为更具体的TObject类型。

此外,不是使用out,而是直接返回类型,除非你绝对需要布尔成功值,否则它将更具可读性和可用性,而不应该根据TObject是否为空来推断它。

以下测试代码返回Character类型的匹配项。

_currentVisibleCharacters = new Dictionary<UInt32, Character>();
_currentVisibleCharacters.Add(0, new Character());
var match = GetVisibleObject<Character>(0);
Console.WriteLine(match);
Console.WriteLine(match.GetType());

答案 2 :(得分:0)

我试图通过引入自己的课程来简化它。

你可以采用这种方法作为方向,因为我不确切知道你的班级结构如何:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Character
    {
        public string Name { get; set; }
    }

    class Micky : Character
    {

    }

    class Minnie : Character
    {

    }

    class Program
    {
        static void Main(string[] args)
        {
            var mickeys = new Dictionary<Guid, Character>();
            var searchKey = Guid.NewGuid  ();
            mickeys.Add(searchKey, new Micky { Name = "Micky A"});
            mickeys.Add(Guid.NewGuid(), new Micky { Name = "Micky B" });

            var minnies = new Dictionary<Guid, Character>();
            minnies.Add(Guid.NewGuid(), new Minnie { Name = "Minnie A" });
            minnies.Add(Guid.NewGuid(), new Minnie { Name = "Minnie B" });


            var searchedItem = mickeys.Union(minnies).Where(k => k.Key == searchKey).FirstOrDefault();
            Console.WriteLine(searchedItem.Value.Name);

        }
    }
}

要考虑的要点:

  1. 您不需要创建3个字典,因为您可以创建一个字典(只要密钥是唯一的)。您可以创建一个父类字典并设置N个子项的值。这一点将涵盖L的SOLID原则(LSP(Liskov替代原则))

  2. 如果您想要一个单独的字典,请使用Union将它们组合起来,然后按键搜索。