假设我有一个具有stringProp1,stringProp2的对象。我希望将stringProp1,stringProp2的每个组合存储在Dictionary中。最初我将密钥存储为key = stringProp1 + stringProp2,但实际上这可能会导致错误,具体取决于2个值。是创建自定义字典类的最佳解决方案,还是使用内置.NET类的更好方法?
答案 0 :(得分:3)
在.NET 4中,您可以使用System.Tuple
作为密钥。
var dict = new Dictionary<Tuple<string,string>, int>();
dict.Add(Tuple.Create("foo","bar"), 1);
答案 1 :(得分:1)
为什么不直接使用包含2个字符串的结构?这将是最简单的。
答案 2 :(得分:1)
只要密钥包含比较器正确比较/散列的必要信息,您使用哪种数据结构并不重要。
您甚至可以将对象用作字典中的键,并使用适当的EqualityComparer
实现在您喜欢的任何字段上进行比较。这个使用序数比较比较两个字符串属性:
class MyObject
{
public string StringProp1 { get; set; }
public string StringProp2 { get; set; }
public MyObject(string prop1, string prop2)
{
StringProp1 = prop1;
StringProp2 = prop2;
}
}
class MyObjectComparerS1S2 : EqualityComparer<MyObject>
{
//Change this if you need e.g. case insensitivity or
//culture-specific comparisons
static StringComparer comparer = StringComparer.Ordinal;
public override bool Equals(MyObject x, MyObject y)
{
return
comparer.Equals(x.StringProp1, y.StringProp1) &&
comparer.Equals(x.StringProp2, y.StringProp2);
}
public override int GetHashCode(MyObject obj)
{
//Uncomment this if running in a checked context
//Copycat of Jon Skeet's string hash combining
//unchecked
//{
return
(527 + comparer.GetHashCode(obj.StringProp1)) * 31 +
comparer.GetHashCode(obj.StringProp2);
//}
}
public static readonly MyObjectComparerS1S2 Instance =
new MyObjectComparerS1S2();
}
static void Main(string[] args)
{
Dictionary<MyObject, MyObject> dict =
new Dictionary<MyObject, MyObject>(MyObjectComparerS1S2.Instance);
MyObject obj = new MyObject("apple", "plum");
dict.Add(obj, obj);
MyObject search = new MyObject("apple", "plum");
MyObject result = dict[search];
Console.WriteLine("{0}:{1}", result.StringProp1, result.StringProp2);
}
您可以通过创建虚拟对象,填充字符串键并使用虚拟对象作为查找键来搜索对象。
如果您不喜欢这个想法,或者它不可行,只需按@Vlad说并在结构或类中提取键。在这种情况下,修改比较器以从EqualityComparer<MyKeyStructOrClass>
派生。
请注意,我已使用Jon Skeet's method来组合字符串哈希。它可能比XOR method found on MSDN更好。如果您觉得钢筋不足,请随意使用另一个哈希实现处理字符串 - Hsieh,Murmur,Bob Jenkin's或您信任的任何内容。这是{{3实际上也有一些C#代码。
答案 3 :(得分:1)
根据您填写字典的方式以及使用它执行的操作,可以使用匿名类型作为键。例如,如果您有一个班级Person
:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
如果你有一个这样的序列,IEnumerable<Person>
,并想创建一个将名字映射到年龄的字典,你可以写:
var personDictionary = people.ToDictionary(p => new { p.FirstName, p.LastName });
这会为您提供一个字典,其中包含名字和姓氏作为键,并将整个Person
存储为值。您可以稍后使用以下方式查找密钥:
personDictionary.TryGetValue(new { FirstName = "John", LastName = "Smith" },
out person);
如果您尝试在不同的类甚至方法之间传递字典,这对您没有多大帮助,它变得难以管理,但是为了在单个方法中进行一些快速数据处理,它可以很好地工作。事实上,使用匿名类作为GroupBy
扩展方法或group by
查询理解语法的关键是很常见的。
答案 4 :(得分:0)
如果有一个字符在任何一个字符串中都没有出现,你可以在那里放一个分隔符。
例如
stringProp1 + "|" + stringProp2
如果没有,那么我建议{/ 1}},如
Dictionary<string, Dictionary<string, MyValueType>>
答案 5 :(得分:0)
您可以使用MD5算法为每个字符串生成一个值,然后将这两个值相加。结果就是关键 .NET在System.Security.Cryptography命名空间中提供类MD5CryptoServiceProvider。该类包含用于计算哈希值的ComputeHash方法。