在没有 System.Collections.Generic.KeyNotFoundException 的情况下对字典键的操作
Operations over dictionary-key without System.Collections.Generic.KeyNotFoundException
我有一个简单的字典调用结果:
Dictionary<String,String> results=new();
results["a"]="a";
results["b"]="b";
results["c"]="c";
为了简化示例,我的字典只包含 3 个字母键 a、b、c。
但有时它不会包含此值之一甚至 none,(它总是会被初始化)。
假设这种情况:
Dictionary<String,String> results=new();
if(anyconditionA) results["a"]="a";
if(anyconditionB)results["b"]="b";
if(anyconditionC)results["c"]="c";
所以每次我想使用这本词典时,我都必须检查键值:
变种测试=结果[“一”]; -> 如果任何条件 A 不为真,则抛出 System.Collections.Generic.KeyNotFoundException。
所以为了解决这个问题,我这样做了:
if(results.ContainsKey("a"){
someOperation(results["a"]);
}
所以如果我有很多值,代码如下所示:
if(results.ContainsKey("a"){someOperation(results["a"]);}
if(results.ContainsKey("b"){... stuff}
if(results.ContainsKey("c"){... stuff}
if(results.ContainsKey("..."){... stuff}
if(results.ContainsKey("d"){someOperation(results["d"]);}
¿是否有一种正确的方法可以在一个语句中执行此操作,我的意思是检查并执行操作(如果存在),或者我必须在每次存在该值时进行测试? (就像在列表中使用 null 运算符一样
结果[a]?.someOperation()
)
谢谢!
如果你发现自己经常这样做并且想简化调用代码,你可以编写一个扩展方法:
public static class DictionaryExt
{
public static bool DoIfExists<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key, Action<TValue> action)
{
if (!self.TryGetValue(key, out var value))
return false;
action(value);
return true;
}
}
那么你可以这样写代码:
results.DoIfExists("a", someOperation);
results.DoIfExists("b", value => Console.WriteLine("Doing stuff with " + value));
results.DoIfExists("c", value =>
{
Console.WriteLine("Doing stuff with " + value);
Console.WriteLine("This uses multiple lines.");
});
我真的不确定这是否值得(我不喜欢过度使用扩展方法),但这是一个见仁见智的问题!
在我看来,上面的第三个例子混淆了代码,最好写成:
if (results.TryGetValue("c", out var value))
{
Console.WriteLine("Doing stuff with " + value);
Console.WriteLine("This uses multiple lines.");
}
但第一个示例 results.DoIfExists("a", someOperation);
可以说比:
要简单一些
if (results.TryGetValue("a", out var value))
someOperation(value);
这是一个边际改进,我个人不会打扰。由你决定!
您从 Matthew Watson 那里得到了“如果键不在字典中,则可能不调用获取值的操作”,但在您的问题末尾,您问的是一个稍微不同的问题
¿Is there a propper way to do this in one statement i mean check and do the operation if exists or i have to test every time that value exists? (like do with null operator in a list something like results[a]?.someOperation() ) Thanks!
如果操作是字典中值的方法,那么当然,您可以使用?.
来防止对不存在的值的空引用:
var dictionary = new Dictionary<int, StringBuilder>();
dictionary.GetValueOrDefault(1)?.AppendLine("hello");
GetValueOrDefault 已实施 as an extension method and is a .net core 2.2+ thing. There are nuget packages that make it available for older versions, or you can write it yourself as an extension possibly adapting it from the netcore source 并将其放入您的应用程序:
public static TValue? GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
return dictionary.GetValueOrDefault(key, default!);
}
public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
if (dictionary == null)
{
throw new ArgumentNullException(nameof(dictionary));
}
TValue? value;
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
}
我有一个简单的字典调用结果:
Dictionary<String,String> results=new();
results["a"]="a";
results["b"]="b";
results["c"]="c";
为了简化示例,我的字典只包含 3 个字母键 a、b、c。 但有时它不会包含此值之一甚至 none,(它总是会被初始化)。 假设这种情况:
Dictionary<String,String> results=new();
if(anyconditionA) results["a"]="a";
if(anyconditionB)results["b"]="b";
if(anyconditionC)results["c"]="c";
所以每次我想使用这本词典时,我都必须检查键值: 变种测试=结果[“一”]; -> 如果任何条件 A 不为真,则抛出 System.Collections.Generic.KeyNotFoundException。 所以为了解决这个问题,我这样做了:
if(results.ContainsKey("a"){
someOperation(results["a"]);
}
所以如果我有很多值,代码如下所示:
if(results.ContainsKey("a"){someOperation(results["a"]);}
if(results.ContainsKey("b"){... stuff}
if(results.ContainsKey("c"){... stuff}
if(results.ContainsKey("..."){... stuff}
if(results.ContainsKey("d"){someOperation(results["d"]);}
¿是否有一种正确的方法可以在一个语句中执行此操作,我的意思是检查并执行操作(如果存在),或者我必须在每次存在该值时进行测试? (就像在列表中使用 null 运算符一样 结果[a]?.someOperation() ) 谢谢!
如果你发现自己经常这样做并且想简化调用代码,你可以编写一个扩展方法:
public static class DictionaryExt
{
public static bool DoIfExists<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key, Action<TValue> action)
{
if (!self.TryGetValue(key, out var value))
return false;
action(value);
return true;
}
}
那么你可以这样写代码:
results.DoIfExists("a", someOperation);
results.DoIfExists("b", value => Console.WriteLine("Doing stuff with " + value));
results.DoIfExists("c", value =>
{
Console.WriteLine("Doing stuff with " + value);
Console.WriteLine("This uses multiple lines.");
});
我真的不确定这是否值得(我不喜欢过度使用扩展方法),但这是一个见仁见智的问题!
在我看来,上面的第三个例子混淆了代码,最好写成:
if (results.TryGetValue("c", out var value))
{
Console.WriteLine("Doing stuff with " + value);
Console.WriteLine("This uses multiple lines.");
}
但第一个示例 results.DoIfExists("a", someOperation);
可以说比:
if (results.TryGetValue("a", out var value))
someOperation(value);
这是一个边际改进,我个人不会打扰。由你决定!
您从 Matthew Watson 那里得到了“如果键不在字典中,则可能不调用获取值的操作”,但在您的问题末尾,您问的是一个稍微不同的问题
¿Is there a propper way to do this in one statement i mean check and do the operation if exists or i have to test every time that value exists? (like do with null operator in a list something like results[a]?.someOperation() ) Thanks!
如果操作是字典中值的方法,那么当然,您可以使用?.
来防止对不存在的值的空引用:
var dictionary = new Dictionary<int, StringBuilder>();
dictionary.GetValueOrDefault(1)?.AppendLine("hello");
GetValueOrDefault 已实施 as an extension method and is a .net core 2.2+ thing. There are nuget packages that make it available for older versions, or you can write it yourself as an extension possibly adapting it from the netcore source 并将其放入您的应用程序:
public static TValue? GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
return dictionary.GetValueOrDefault(key, default!);
}
public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
if (dictionary == null)
{
throw new ArgumentNullException(nameof(dictionary));
}
TValue? value;
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
}