一直困扰我的一件事是完成这个非常简单(对我的工作来说,非常常见)的操作需要多少行代码:
var lTheDict = new Dictionary<string, object>();
// The dictionary gets some stuff put in it elsewhere...
// Do annoying lookup that must be common but is always unwieldy.
object lTheObject;
int lTheValue; // NOTE: Not always an int
if (lTheDict.TryGetValue("TheKey", out lTheObject))
{
lTheValue = (int) lTheObject;
}
Run Code Online (Sandbox Code Playgroud)
我相信一定有更好的方法来做到这一点,也许是空合并或其他东西。我真正希望能够写的是:
int lTheValue ?= (int) lTheDict["TheKey"];
Run Code Online (Sandbox Code Playgroud)
换句话说,如果 TheKey 存在,就给我值,否则就给我“空”int。
几乎不可能刮掉线条。即使我们只是尝试查找和转换并在单行捕获和忽略上捕获异常(我的工作场所代码风格都不允许),我们仍然必须在 try 块之外声明变量,并最终得到类似的东西:
int lTheValue;
try {
lTheValue = (int) lTheDict["TheKey"];
} catch (Exception ex) { }
Run Code Online (Sandbox Code Playgroud)
这又是一个荒谬的开销代码,掩盖了一个非常明显的操作。
即使只是为了能够通过在我们将它用作 outparam 的地方声明它来摆脱 lTheObject 的声明(这是在 .NET 5 中或我听到的),也会删除一行。this 所在的函数本身通常只有 10 行长,看起来我们正在用这个集合做一些重要的事情,因为有一半的代码专门用于获取一个值,但实际上这只是分散注意力。
注意:我知道我可以编写一个模板函数来做到这一点,但即使在函数中它也会让我烦恼,不得不再次编写这些行。一定会有更好的办法!
有没有人找到或者你能想到一种更短的写法?
static class MyExtensions
{
public static T MagicGet<T>(
this Dictionary<string, object> lookup,
string key)
{
return lookup.TryGetValue(key, out var value)) ? (T)value : default(T);
}
}
...
var value = lTheDict.MagicGet<int?>("TheKey");
Run Code Online (Sandbox Code Playgroud)
或者不创建扩展,您可以简单地编写原始查找如下:
int lTheValue = lTheDict.TryGetValue("TheKey", out object lTheObject) ? (int) lTheObject : default(int);
Run Code Online (Sandbox Code Playgroud)