关于exchangewebservices:如何检测C#中是否存在此字典密钥?

How can I detect if this dictionary key exists in C#?

我正在使用Exchange Web服务管理API和联系人数据。我有以下代码,这是功能性的,但不理想:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
foreach (Contact c in contactList)
{
    string openItemUrl ="https://" + service.Url.Host +"/owa/" + c.WebClientReadFormQueryString;

    row = table.NewRow();
    row["FileAs"] = c.FileAs;
    row["GivenName"] = c.GivenName;
    row["Surname"] = c.Surname;
    row["CompanyName"] = c.CompanyName;
    row["Link"] = openItemUrl;

    //home address
    try { row["HomeStreet"] = c.PhysicalAddresses[PhysicalAddressKey.Home].Street.ToString(); }
    catch (Exception e) { }
    try { row["HomeCity"] = c.PhysicalAddresses[PhysicalAddressKey.Home].City.ToString(); }
    catch (Exception e) { }
    try { row["HomeState"] = c.PhysicalAddresses[PhysicalAddressKey.Home].State.ToString(); }
    catch (Exception e) { }
    try { row["HomeZip"] = c.PhysicalAddresses[PhysicalAddressKey.Home].PostalCode.ToString(); }
    catch (Exception e) { }
    try { row["HomeCountry"] = c.PhysicalAddresses[PhysicalAddressKey.Home].CountryOrRegion.ToString(); }
    catch (Exception e) { }

    //and so on for all kinds of other contact-related fields...
}

正如我所说,这个代码是有效的。如果可能的话,现在我想让它少吸一点。

我找不到任何方法允许我在尝试访问字典之前检查字典中是否存在该键,如果我尝试(使用.ToString())读取该键,但它不存在,则会引发异常:

500
The given key was not present in the dictionary.

我如何重构这段代码以减少代码的使用量(同时仍能正常工作)?


您可以使用ContainsKey

1
if (dict.ContainsKey(key)) { ... }

TryGetValue

1
dict.TryGetValue(key, out value);

更新:根据注释,这里的实际类不是IDictionary,而是PhysicalAddressDictionary,所以方法是ContainsTryGetValue,但它们的工作方式相同。

示例用法:

1
2
3
4
5
6
PhysicalAddressEntry entry;
PhysicalAddressKey key = c.PhysicalAddresses[PhysicalAddressKey.Home].Street;
if (c.PhysicalAddresses.TryGetValue(key, out entry))
{
    row["HomeStreet"] = entry;
}

更新2:这是工作代码(由提问者编译)

1
2
3
4
5
6
7
8
9
PhysicalAddressEntry entry;
PhysicalAddressKey key = PhysicalAddressKey.Home;
if (c.PhysicalAddresses.TryGetValue(key, out entry))
{
    if (entry.Street != null)
    {
        row["HomeStreet"] = entry.Street.ToString();
    }
}

…根据需要对每个键重复内部条件。TryGetValue仅在每个PhysicalAddressKey(家庭、工作等)中执行一次。


c.PhysicalAddresses的类型是什么?如果是Dictionary,那么可以使用ContainsKey方法。


物理地址字典.TryGetValue

1
2
3
4
 public bool TryGetValue (
    PhysicalAddressKey key,
    out PhysicalAddressEntry physicalAddress
     )

我使用字典,由于重复性和可能丢失的键,我很快就修补了一个小方法:

1
2
3
4
 private static string GetKey(IReadOnlyDictionary<string, string> dictValues, string keyValue)
 {
     return dictValues.ContainsKey(keyValue) ? dictValues[keyValue] :"";
 }

称之为:

1
var entry = GetKey(dictList,"KeyValue1");

完成任务。


这是我今天做的一点东西。似乎对我有用。基本上,您要重写基命名空间中的add方法来进行检查,然后调用基的add方法来实际添加它。希望这对你有用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.Collections;

namespace Main
{
    internal partial class Dictionary<TKey, TValue> : System.Collections.Generic.Dictionary<TKey, TValue>
    {
        internal new virtual void Add(TKey key, TValue value)
        {  
            if (!base.ContainsKey(key))
            {
                base.Add(key, value);
            }
        }
    }

    internal partial class List<T> : System.Collections.Generic.List<T>
    {
        internal new virtual void Add(T item)
        {
            if (!base.Contains(item))
            {
                base.Add(item);
            }
        }
    }

    public class Program
    {
        public static void Main()
        {
            Dictionary<int, string> dic = new Dictionary<int, string>();
            dic.Add(1,"b");
            dic.Add(1,"a");
            dic.Add(2,"c");
            dic.Add(1,"b");
            dic.Add(1,"a");
            dic.Add(2,"c");

            string val ="";
            dic.TryGetValue(1, out val);

            Console.WriteLine(val);
            Console.WriteLine(dic.Count.ToString());


            List<string> lst = new List<string>();
            lst.Add("b");
            lst.Add("a");
            lst.Add("c");
            lst.Add("b");
            lst.Add("a");
            lst.Add("c");

            Console.WriteLine(lst[2]);
            Console.WriteLine(lst.Count.ToString());
        }
    }
}