为什么 C# TryAdd、TryRemove、TryGetValue return 失败时设置空值?

Why do C# TryAdd, TryRemove, TryGetValue return null sets when they fail?

为什么 Dictionary 方法 return 失败时设置为空值?

If the answer is "what do you expect them to return???" I guess I was expecting an empty HashSet that I can run methods like Count or GetEnumerator on. Without getting an exception.

Maybe my question is really, should I catch an exception, make the return value not null and then return it?

我查看了 this question,但当我调用 Add()、Remove() 或 TryGetValue() 时我的字典不为空

是的,这是一个编程作业,但数据结构是我的选择,使用两个 ConcurrentDictionaries 表示一个图。

测试运行时:

DependencyGraph t = new DependencyGraph();
Assert.IsFalse(t.GetDependees("x").GetEnumerator().MoveNext());

我的方法运行:

    public IEnumerable<string> GetDependees(string s)
    {
        HashSet<String> valuesForKey = new HashSet<String>();
        dependeeGraph.TryGetValue(s, out valuesForKey);
        return valuesForKey;
    }

当它在 return 值上命中 .GetEnumerator().MoveNext() 时,我得到 nullReferenceException。

TryGetValue 有一个 out 参数用于 TValue 类型参数。由于 out 参数必须由被调用函数初始化,因此 TryGetValue 必须对每种可能的类型进行通用初始化。唯一这样的值是 default(TValue),对于引用类型是 null,对于值类型是 'zero'。

天啊……

停止忽略 return 值。 return 值告诉您 "there's no data available"。设置 out 参数的唯一原因是因为 C# 要求您这样做——您不应该使用该值。

如果你不关心"no data"和"a set with zero items"的区别,你可以自己写一个扩展方法来简化事情:

public static IEnumerable<string> GetValueOrEmpty(this DependencyGraph dg, string s)
{
  HashSet<string> value;

  if (!dg.TryGetValue(s, out value)) return Enumerable.Empty<string>();

  return value;
}