NULL 合并字典查找

Der*_*ren 3 c# collections

一直困扰我的一件事是完成这个非常简单(对我的工作来说,非常常见)的操作需要多少行代码:

  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 行长,看起来我们正在用这个集合做一些重要的事情,因为有一半的代码专门用于获取一个值,但实际上这只是分散注意力。

注意:我知道我可以编写一个模板函数来做到这一点,但即使在函数中它也会让我烦恼,不得不再次编写这些行。一定会有更好的办法!

有没有人找到或者你能想到一种更短的写法?

Mar*_*ell 5

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)