Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字典和键值对_C#_Collections_Dictionary - Fatal编程技术网

C# 字典和键值对

C# 字典和键值对,c#,collections,dictionary,C#,Collections,Dictionary,我对字典有点问题,希望你能帮助我 我有以下声明: class MainCollection<TKey1, TKey2, TValue> : Dictionary<KeyValuePair<TKey1, TKey2>, TValue> class主集合:字典 问题是我无法通过TKey1或TKey2从该词典中获取元素。 是否有方法仅通过TKey1或TKey2而不是TKey1和TKey2获取元素 我编写了以下代码: public TValue GetItemB

我对字典有点问题,希望你能帮助我

我有以下声明:

class MainCollection<TKey1, TKey2, TValue> : Dictionary<KeyValuePair<TKey1, TKey2>, TValue>
class主集合:字典
问题是我无法通过TKey1或TKey2从该词典中获取元素。 是否有方法仅通过TKey1或TKey2而不是TKey1和TKey2获取元素

我编写了以下代码:

 public TValue GetItemByKey1(TKey1 key)
 {
     MainCollection<int, int, string> Coll = new MainCollection<int, int, string>();
     var value = from s in Coll where s.Key.Key == key select s.Value;
 }
public TValue GetItemByKey1(TKey1键)
{
MainCollection Coll=新的MainCollection();
var value=从Coll中的s开始,其中s.Key.Key==键选择s.value;
}
但它已经有两个问题:

  • 编译错误:s.Key.Key==Key=>operator==不能应用于int和TKey1类型
  • 它看起来很丑。即使编译会成功,我也不确定这是获得此类项目的最快方法。我想那本字典应该是更好的
  • 如何解决这些错误?我在这里没有发现任何相关问题。
    提前谢谢

    只需向集合本身添加一个方法:

     public TValue GetItemByKey1(TKey1 key)
     {         
         var value = from s in this.Keys where s.Key.Key == key select this[s];
         return value.SingleOrDefault();
     }
    
    对于
    TKey2
    ,您可以使用类似的方法


    请注意,这些查找将比标准字典键查找慢得多,因为您正在迭代键集合,而不是利用字典将使用的哈希表。

    只需向集合本身添加一个方法即可:

     public TValue GetItemByKey1(TKey1 key)
     {         
         var value = from s in this.Keys where s.Key.Key == key select this[s];
         return value.SingleOrDefault();
     }
    
    对于
    TKey2
    ,您可以使用类似的方法


    请注意,这些查找将比标准字典键查找慢得多,因为您正在迭代键集合,而不是利用字典将使用的哈希表。

    好的,因此您希望能够通过
    TKey1
    TKey2
    进行查找。然后你需要三个字典,每个键一个,然后一个键对

    class Foo<TFirstKey, TSecondKey, TValue> {
        private readonly Dictionary<TFirstKey, List<TValue>> firstDictionary
            = new Dictionary<TFirstKey, List<TValue>>();
        private readonly Dictionary<TSecondKey, List<TValue>> secondDictionary
            = new Dictionary<TSecondKey, List<TValue>>();
        private Dictionary<Tuple<TFirstKey, TSecondKey>, TValue> dictionary
            = new Dictionary<Tuple<TFirstKey, TSecondKey>, TValue>();
    
        public IEnumerable<TValue> GetByFirstKey(TFirstKey firstKey) {
            return this.firstDictionary[firstKey];
        }
    
        public IEnumerable<TValue> GetBySecondKey(TSecondKey secondKey) {
            return this.secondDictionary[secondKey];
        }
    
        public TValue GetByKey(TFirstKey firstKey, TSecondKey secondKey) {
            return this.dictionary[Tuple.Create(firstKey, secondKey)];
        }
    
        public void Add(TFirstKey firstKey, TSecondKey secondKey, TValue value) {
            this.dictionary.Add(Tuple.Create(firstKey, secondKey), value);
            if(this.firstDictionary.Keys.Contains(firstKey)) {
                this.firstDictionary[firstKey].Add(value);
            }
            else {
                this.firstDictionary.Add(firstKey, new List<TValue> { value });
            }
             if(this.secondDictionary.Keys.Contains(secondKey)) {
                this.secondDictionary[secondKey].Add(value);
            }
            else {
                this.secondDictionary.Add(secondKey, new List<TValue> { value });
            }
        }
    }
    
    class-Foo{
    专用只读词典
    =新字典();
    专用只读词典
    =新字典();
    私人字典
    =新字典();
    公共IEnumerable GetByFirstKey(TFirstKey firstKey){
    返回这个.firstDictionary[firstKey];
    }
    公共IEnumerable GetBySecondKey(TSecondKey secondKey){
    返回此.secondDictionary[secondKey];
    }
    公共TValue GetByKey(TFirstKey firstKey,TSecondKey secondKey){
    返回此.dictionary[Tuple.Create(firstKey,secondKey)];
    }
    公共无效添加(TFirstKey firstKey、TSecondKey secondKey、TValue){
    this.dictionary.Add(Tuple.Create(firstKey,secondKey),value);
    if(this.firstDictionary.Keys.Contains(firstKey)){
    this.firstDictionary[firstKey].Add(value);
    }
    否则{
    this.firstDictionary.Add(firstKey,新列表{value});
    }
    if(this.secondDictionary.Keys.Contains(secondKey)){
    this.secondDictionary[secondKey].Add(value);
    }
    否则{
    Add(secondKey,新列表{value});
    }
    }
    }
    
    请注意,只有通过
    (TFirstKey,TSecondKey)
    进行的查找是唯一的,因此您需要
    GetByFirstKey
    GetBySecondKey
    来返回集合

    剩下的细节我就留给你了


    关键是,如果要快速查找任意一个键,需要两个字典(键对的每个坐标对应一个)。通过查询密钥集,可以使用one,但这很慢(搜索密钥是线性的)。

    好的,因此您希望能够通过
    TKey1
    TKey2
    进行查找。然后你需要三个字典,每个键一个,然后一个键对

    class Foo<TFirstKey, TSecondKey, TValue> {
        private readonly Dictionary<TFirstKey, List<TValue>> firstDictionary
            = new Dictionary<TFirstKey, List<TValue>>();
        private readonly Dictionary<TSecondKey, List<TValue>> secondDictionary
            = new Dictionary<TSecondKey, List<TValue>>();
        private Dictionary<Tuple<TFirstKey, TSecondKey>, TValue> dictionary
            = new Dictionary<Tuple<TFirstKey, TSecondKey>, TValue>();
    
        public IEnumerable<TValue> GetByFirstKey(TFirstKey firstKey) {
            return this.firstDictionary[firstKey];
        }
    
        public IEnumerable<TValue> GetBySecondKey(TSecondKey secondKey) {
            return this.secondDictionary[secondKey];
        }
    
        public TValue GetByKey(TFirstKey firstKey, TSecondKey secondKey) {
            return this.dictionary[Tuple.Create(firstKey, secondKey)];
        }
    
        public void Add(TFirstKey firstKey, TSecondKey secondKey, TValue value) {
            this.dictionary.Add(Tuple.Create(firstKey, secondKey), value);
            if(this.firstDictionary.Keys.Contains(firstKey)) {
                this.firstDictionary[firstKey].Add(value);
            }
            else {
                this.firstDictionary.Add(firstKey, new List<TValue> { value });
            }
             if(this.secondDictionary.Keys.Contains(secondKey)) {
                this.secondDictionary[secondKey].Add(value);
            }
            else {
                this.secondDictionary.Add(secondKey, new List<TValue> { value });
            }
        }
    }
    
    class-Foo{
    专用只读词典
    =新字典();
    专用只读词典
    =新字典();
    私人字典
    =新字典();
    公共IEnumerable GetByFirstKey(TFirstKey firstKey){
    返回这个.firstDictionary[firstKey];
    }
    公共IEnumerable GetBySecondKey(TSecondKey secondKey){
    返回此.secondDictionary[secondKey];
    }
    公共TValue GetByKey(TFirstKey firstKey,TSecondKey secondKey){
    返回此.dictionary[Tuple.Create(firstKey,secondKey)];
    }
    公共无效添加(TFirstKey firstKey、TSecondKey secondKey、TValue){
    this.dictionary.Add(Tuple.Create(firstKey,secondKey),value);
    if(this.firstDictionary.Keys.Contains(firstKey)){
    this.firstDictionary[firstKey].Add(value);
    }
    否则{
    this.firstDictionary.Add(firstKey,新列表{value});
    }
    if(this.secondDictionary.Keys.Contains(secondKey)){
    this.secondDictionary[secondKey].Add(value);
    }
    否则{
    Add(secondKey,新列表{value});
    }
    }
    }
    
    请注意,只有通过
    (TFirstKey,TSecondKey)
    进行的查找是唯一的,因此您需要
    GetByFirstKey
    GetBySecondKey
    来返回集合

    剩下的细节我就留给你了


    关键是,如果要快速查找任意一个键,需要两个字典(键对的每个坐标对应一个)。通过查询密钥集,可以使用one,但这很慢(搜索密钥是线性的)。

    我建议不要使用
    KeyValuePair
    ,因为KVP是一个结构,并且作为字典中的密钥表示对象将存在一段时间。我建议改为使用
    元组。好处是Tuple是一种引用类型,您可以自由地传递,而无需复制。此外,Tuple是一个只读对象,就像KVPair一样。我会这样写:

        class Program
        {
            static void Main(string[] args)
            {
                MainCollection<int, string, DateTime> collection = new MainCollection<int, string, DateTime>();
    
                collection.Add(Tuple<int, string>.Create(1, "Bob"), new DateTime(1992, 12, 1));
                collection.Add(Tuple<int, string>.Create(2, "James"), new DateTime(1945, 9, 1));
                collection.Add(Tuple<int, string>.Create(3, "Julie"), new DateTime(1976, 7, 15));
    
                DateTime date;
    
                date = collection.GetValue(1);
                Console.WriteLine("Bob birthdate: {0}", date);
    
                date = collection.GetValue("Julie");
                Console.WriteLine("#3 birthdate: {0}", date);
    
                Console.ReadLine();
            }
        }
    
        public class MainCollection<TKey1, TKey2, TValue>
        {
            Tuple<TKey1, TKey2> key;
            Dictionary<Tuple<TKey1, TKey2>, TValue> mainCollection = new Dictionary<Tuple<TKey1, TKey2>, TValue>();
    
            public void Add(Tuple<TKey1, TKey2> Key, TValue Value)
            {
                mainCollection.Add(Key, Value);
            }
    
            public TValue GetValue(TKey1 Key)
            {
                return mainCollection.Where(k => k.Key.Item1.Equals(Key))
                                     .Select(v => v.Value)
                                     .FirstOrDefault();
            }
    
            public TValue GetValue(TKey2 Key)
            {
                return mainCollection.Where(k => k.Key.Item2.Equals(Key))
                                     .Select(v => v.Value)
                                     .FirstOrDefault();
            }
    
        }
    
        public class Tuple<T1, T2>
        {
            readonly T1 item1;
            readonly T2 item2;
    
            Tuple(T1 item1, T2 item2)
            {
                this.item1 = item1;
                this.item2 = item2;
            }
    
            public static Tuple<T1, T2> Create(T1 Item1, T2 Item2)
            {
                return new Tuple<T1, T2>(Item1, Item2);
            }
    
            public T1 Item1
            { get { return item1; } }
    
            public T2 Item2
            { get { return item2; } }
        }
    }
    

    我建议不要使用
    KeyValuePair
    ,因为KVP是一个结构,并且作为字典中的键表示该对象将存在一段时间。我建议改为使用
    元组。好处