我正在使用带有联系人数据的 Exchange Web 服务托管 API。我有以下代码,它是功能性的,但并不理想:
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 给定的键不在字典中。
我怎样才能重构这段代码以减少吸收(同时仍然有效)?
您可以使用 ContainsKey
:
if (dict.ContainsKey(key)) { ... }
或 TryGetValue
:
dict.TryGetValue(key, out value);
更新:根据评论,这里的实际类不是 IDictionary
,而是 PhysicalAddressDictionary
,因此方法是 Contains
和 TryGetValue
,但它们的工作方式相同。
示例用法:
PhysicalAddressEntry entry;
PhysicalAddressKey key = c.PhysicalAddresses[PhysicalAddressKey.Home].Street;
if (c.PhysicalAddresses.TryGetValue(key, out entry))
{
row["HomeStreet"] = entry;
}
更新 2:这是工作代码(由提问者编译)
PhysicalAddressEntry entry;
PhysicalAddressKey key = PhysicalAddressKey.Home;
if (c.PhysicalAddresses.TryGetValue(key, out entry))
{
if (entry.Street != null)
{
row["HomeStreet"] = entry.Street.ToString();
}
}
...根据需要为每个所需的键重复内部条件。每个 PhysicalAddressKey(家庭、工作等)仅执行一次 TryGetValue。
c.PhysicalAddresses
的类型是什么?如果是 Dictionary<TKey,TValue>
,那么您可以使用 ContainsKey
方法。
我使用字典,由于重复性和可能丢失的键,我迅速拼凑了一个小方法:
private static string GetKey(IReadOnlyDictionary<string, string> dictValues, string keyValue)
{
return dictValues.ContainsKey(keyValue) ? dictValues[keyValue] : "";
}
调用它:
var entry = GetKey(dictList,"KeyValue1");
完成工作。
PhysicalAddressDictionary.TryGetValue
public bool TryGetValue (
PhysicalAddressKey key,
out PhysicalAddressEntry physicalAddress
)
这是我今天煮的一些东西。似乎对我有用。基本上,您覆盖基本命名空间中的 Add 方法进行检查,然后调用基本命名空间的 Add 方法以实际添加它。希望这对你有用
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());
}
}
}
不定期副业成功案例分享
TryGetValue
方法似乎是最好的选择,因为我找到了这个页面:goo.gl/7YN6...但我不知道如何使用它。在我上面的代码中,row
是一个“DataRow”对象,所以我不确定您的示例代码是否正确,不过......c.PhysicalAddresses.TryGetValue(c.PhysicalAddresses[PhysicalAddressKey.Home].Street, row["HomeStreet"]);
C# 7.0
)row["HomeStreet"] = c.PhysicalAddresses.TryGetValue(PhysicalAddressKey.Home, out PhysicalAddressEntry entry) ? entry.Street.ToString() : null;