我想在C#中创建一个Dictionary查找表.我需要将一个3元组的值解析为一个字符串.我尝试使用数组作为键,但这不起作用,我不知道还能做什么.在这一点上,我正在考虑制作一本词典字典词典,但这看起来可能不是很漂亮,尽管我会在javascript中这样做.
我在List中有一些对象,比方说List<MyClass>,MyClass有几个属性.我想基于MyClass的3个属性创建列表的索引.在这种情况下,2个属性是int,而一个属性是datetime.
基本上我希望能够做到这样的事情:
Dictionary< CompositeKey , MyClass > MyClassListIndex = Dictionary< CompositeKey , MyClass >();
//Populate dictionary with items from the List<MyClass> MyClassList
MyClass aMyClass = Dicitonary[(keyTripletHere)];
Run Code Online (Sandbox Code Playgroud)
我有时会在列表上创建多个字典来索引它所拥有的类的不同属性.我不知道如何最好地处理复合键.我考虑过对三个值进行校验和,但这会产生碰撞的风险.
这是我直到今天才注意到的事情.显然,当执行基于相等的操作时Tuple<T>,很多使用的元组类(Tuple<T1, T2>等)的.NET实现会导致值类型的装箱惩罚.
以下是该类在框架中的实现方式(来自ILSpy的源代码):
public class Tuple<T1, T2> : IStructuralEquatable
{
public T1 Item1 { get; private set; }
public T2 Item2 { get; private set; }
public Tuple(T1 item1, T2 item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public override bool Equals(object obj)
{
return this.Equals(obj, EqualityComparer<object>.Default);
}
public override int GetHashCode()
{
return this.GetHashCode(EqualityComparer<object>.Default);
}
public bool Equals(object obj, IEqualityComparer comparer)
{
if (obj == null)
{
return false;
}
var tuple …Run Code Online (Sandbox Code Playgroud) 我有一个结构可以使用三深嵌套字典很容易地表示,就像这样
private static Dictionary<string, Dictionary<string, Dictionary<string,string>>> PrerenderedTemplates;
Run Code Online (Sandbox Code Playgroud)
结构可能会像这样使用
PrerenderedTemplates[instanceID][templategroup][templatepart]
Run Code Online (Sandbox Code Playgroud)
现在,我意识到这段代码很难阅读,因为通过查看定义语句,你无法分辨出它的用途.我可以真正看到改变它的唯一优势Dictionary<string, PrerenderedTemplate>是可读性.将每个嵌套转换为自己的类(例如class PrerenderedTemplate{} class TemplateGroup{} class TemplatePart{})将为很少(如果有的话)计算优势添加更多代码行.据我所知.
Dictionary在文档/注释中的工作方式更新
所以,受Reza的启发,但无法使用Tuples,我决定创建自己的密钥生成器并实现他的模式:
private Dictionary<string, string> PrerenderedTemplates;
private string GetPrerenderedTemplateKey(string InstanceId, string FeatureId, string OptionId)
{
return new StringBuilder(instanceId)
.Append(FormatTools.LIST_ENTRY_DELIMITER)
.Append(templategroup)
.Append(FormatTools.LIST_ENTRY_DELIMITER)
.Append(templatepart).ToString();
}
Run Code Online (Sandbox Code Playgroud)
FormatTools.LIST_ENTRY_DELIMITERUnicode专用字符在哪里0xe04d.
假设我的字典需要由ItemId和RegionId的组合键入,两者都是int.并且说值侧的类型是"数据".我可以通过以下两种方式做到这一点:
方式1:多级字典,如下所示:
Dictionary<int, Dictionary<int, Data>> myData;
Run Code Online (Sandbox Code Playgroud)
所以查找可以像这样编码:
Data data1 = myData[itemId][regionId];
Run Code Online (Sandbox Code Playgroud)
不错,但缺点是我需要在第一级检查密钥存在,因此代码更安全
Data data1 = null;
if (myData.ContainsKey(itemId)) data1 = myData[itemId][regionId];
Run Code Online (Sandbox Code Playgroud)
方式2:使用多部分密钥.在这种方法中,我将创建一个表示部件的结构,并使用结构作为字典键:
private struct MultiPartKey
{
public int ItemId;
public int RegionId;
}
Dictionary<MultiPartKey, Data> myData;
Run Code Online (Sandbox Code Playgroud)
并且查找将是:
MultiPartKey mpk;
mpk.ItemId = itemId;
mpk.RegionId = regionId;
Data data1 = myData[mpk];
Run Code Online (Sandbox Code Playgroud)
这里可能的缺点是它只有在我的struct完全由简单值类型组成时才有效,因此两个实例的按位比较将是相等的.(对?)
你怎么看?