使用Add()
方法添加字典时,是否可以在编译时检查字典在方法范围内的键唯一性?
示例:有许多支付解决方案提供商(PayPal,PayEx等)在您查询事务时提供某种状态结果,假设为整数。由于每个PSP处理不同的状态,我们都有固定数量的系统状态(例如Pending,Aborted,Committed等),这些状态映射到每个PSP的各种状态代码。
public static class ResponseMapping
{
private static readonly Dictionary<int, PaymentResult> ResultMap;
static ResponseMapping()
{
ResultMap = new Dictionary<int, PaymentResult>();
ResultMap.Add(1, PaymentResult.LogonError);
ResultMap.Add(2, PaymentResult.Pending);
ResultMap.Add(9, PaymentResult.Ok);
// OH DEAR, THIS WILL BLOW UP
ResultMap.Add(1, PaymentResult.Something);
}
public static PaymentResult FindAppropriateResponse(int resultCode)
{
if (ResultMap.ContainsKey(resultCode))
{
return ResultMap[resultCode];
}
return PaymentResult.UnknownResult;
}
}
一个简单的快捷方式是使用[]
索引表示法来添加每个地图,但使用Add()
,您可以避免覆盖您并不意味着的内容。
不幸的是,这种方式在运行时爆炸了。有没有一种技术可以让它在编译时爆炸?
答案 0 :(得分:4)
我认为你不能在编译时检查密钥是否存在。相反,您可以使用Dictionary.ContainsKey
方法,例如:
int key = 1; //your key
if(!ResultMap.ContainsKey(key))
{
ResultMap.Add(key, PaymentResult.Something);
}
答案 1 :(得分:1)
您可以使用ContainsKey
:
if(!ResultMap.ContainsKey(1))
{
ResultMap.Add(1, PaymentResult.Something);
}
或TryGetValue
:
obj item;
if(!ResultMap.TryGetValue(1, out item))
ResultMap.Add(1, PaymentResult.Something);
答案 2 :(得分:1)
如果你真的需要一个字典对象,我认为你不能在编译时这样做,并且可以通过单元测试来伪装它。但如果您只是想要查看,请使用开关。
public static PaymentResult FindAppropriateResponse(int resultCode)
{
switch(resultCode)
{
case 1:
return PaymentResult.LogonError;
case 2:
return PaymentResult.Pending;
case 3:
return PaymentResult.Ok;
default:
return PaymentResult.UnknownResult;
case 1: // Does blow up at compile time
return PaymentResult.Something;
}
}
答案 3 :(得分:0)
您可以定义一个使用的方法而不是Add。 它将添加值(如果不存在)或替换它(如果存在)。
private void Add(Dictionary<int, PaymentResult> PaymentResults, int index, PaymentResult pResult)
{
if(PaymentResults.ContainsKey(index))
{
PaymentResults[index] = pResult;
}
else
{
PaymentResults.Add(index, pResult);
}
}
并使用它
this.Add(ResultMap, 1, PaymentResult.LogonError);
答案 4 :(得分:0)
这是相关但不完全相关的。我遇到的问题是我不确定是否存在密钥,所以我创建了一个简单的方法。
private void AddKey(string key, string value)
{
if (!Dictionary.ContainsKey(key))
Dictionary.Add(key, value);
}
刚刚调用AddKey(键,值);
也许这会对你有所帮助。
答案 5 :(得分:0)
或延伸
public static class Extensions
{
public static bool Push<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
try
{
if (dictionary.ContainsKey(key))
{
dictionary[key] = value;
}
else
{
dictionary.Add(key, value);
}
return true;
}
catch (Exception ex)
{
return false;
}
}
public static TValue Pull<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
try
{
return dictionary.ContainsKey(key) ? dictionary[key] : default(TValue);
}
catch (Exception ex)
{
return default(TValue);
}
}
}
然后你可以做
ResultMap = new Dictionary<int, PaymentResult>();
ResultMap.Push(1, PaymentResult.LogonError); //1 -> PaymentResult.LogonError
ResultMap.Push(1, PaymentResult.Something); //1 -> PaymentResult.Something