我有一个正在进行的在线游戏,我正试图以这种方式解决我如何能够使用通用的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。
答案 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);
}
}
}
要考虑的要点:
您不需要创建3个字典,因为您可以创建一个字典(只要密钥是唯一的)。您可以创建一个父类字典并设置N个子项的值。这一点将涵盖L的SOLID原则(LSP(Liskov替代原则))
如果您想要一个单独的字典,请使用Union将它们组合起来,然后按键搜索。