一般搜索 3 个单独的字典以获取值
Generically search 3 separate dictionaries for value
我有一个正在开发的在线游戏,我正在尝试以这种确切的方式解决如何使用通用搜索功能从 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.
}
它应该使用 "objId" 在 3 个词典中的任何一个中搜索现有的 key/value 对。一旦找到,它应该将找到的值分配给参数"obj"。我尝试过使用 LINQ,但我 运行 遇到了分配问题,例如,从字段 _currentlyVisisbleNpcs 到 "obj" 参数的 Npc 值分配。
角色、物品和 Npc 继承自 WorldObject。
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,因此您可以return每个与 WorldObject 的潜在匹配,然后转换为更具体的 TObject 类型。
此外,return 直接使用类型,而不是使用输出,这更具可读性和可用性,除非您绝对需要布尔成功值,这应该从 TObject 是否为 null 来推断.
下面的测试代码return是字符类型的匹配项。
_currentVisibleCharacters = new Dictionary<UInt32, Character>();
_currentVisibleCharacters.Add(0, new Character());
var match = GetVisibleObject<Character>(0);
Console.WriteLine(match);
Console.WriteLine(match.GetType());
嗯,我试图通过介绍我自己的东西来简化它 class。
你可以把这个方法作为一个方向,因为我不知道你的class结构是怎样的:
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 个字典,因为您可以创建一个字典(只要键是唯一的)。您可以创建一个父字典 class 并设置 N 个子字典的值。这一点会涵盖L的SOLID原则(LSP(Liskov substitution principle))
如果你想有一个单独的字典,那么用Union把它们组合起来,然后按键搜索。
我假设你需要检查类型,这样你就不会从错误的字典中得到东西。
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;
}
我有一个正在开发的在线游戏,我正在尝试以这种确切的方式解决如何使用通用搜索功能从 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.
}
它应该使用 "objId" 在 3 个词典中的任何一个中搜索现有的 key/value 对。一旦找到,它应该将找到的值分配给参数"obj"。我尝试过使用 LINQ,但我 运行 遇到了分配问题,例如,从字段 _currentlyVisisbleNpcs 到 "obj" 参数的 Npc 值分配。
角色、物品和 Npc 继承自 WorldObject。
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,因此您可以return每个与 WorldObject 的潜在匹配,然后转换为更具体的 TObject 类型。
此外,return 直接使用类型,而不是使用输出,这更具可读性和可用性,除非您绝对需要布尔成功值,这应该从 TObject 是否为 null 来推断.
下面的测试代码return是字符类型的匹配项。
_currentVisibleCharacters = new Dictionary<UInt32, Character>();
_currentVisibleCharacters.Add(0, new Character());
var match = GetVisibleObject<Character>(0);
Console.WriteLine(match);
Console.WriteLine(match.GetType());
嗯,我试图通过介绍我自己的东西来简化它 class。
你可以把这个方法作为一个方向,因为我不知道你的class结构是怎样的:
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 个字典,因为您可以创建一个字典(只要键是唯一的)。您可以创建一个父字典 class 并设置 N 个子字典的值。这一点会涵盖L的SOLID原则(LSP(Liskov substitution principle))
如果你想有一个单独的字典,那么用Union把它们组合起来,然后按键搜索。
我假设你需要检查类型,这样你就不会从错误的字典中得到东西。
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;
}