添加到字典的三元运算符<string, list<uri>>

Ternary operator adding to dictionary<string, list<uri>>

如何使用 MVC C# 中的三元运算符来检查是否为空添加到列表否则创建新列表逻辑更短的字典>?

            if (urlDictionary.ContainsKey(url.Authority))
            {
                urlDictionary[url.Authority].Add(url);
            }
            else
            {
                urlDictionary.Add(url.Authority, new List<Uri> { url });
            }

您只能在需要表达式的地方使用三元运算符。这意味着您可以使用运算符根据布尔条件为变量赋值。

var a = myCondition ? 1 : 0;

您还可以使用运算符将​​值作为方法的参数传递:

DoSomething(myCondition ? 1 : 0);

但是您可以调用基于布尔表达式的方法:

myCondition ? list.Add(myValue) : list.Add(new MyValue());

这将产生编译器错误:

Only assignment, call, increment, decrement, and new object expressions can be used as a statement

此外,您为 Add 方法提供的内容有不同的类型。在运算符的左侧,您添加了一个项目,而在右侧,您添加了一个新列表。

改用简单的 if:

if (!urlDictionary.ContainsKey(url.Authority))
    urlDictionary[url.Authority] = new List<Uri>();

urlDictionary[url.Authority].Add(url);

选项 1

我建议采用这种方法。 TryGetValue 允许您同时检查是否存在 Key 和 return 匹配值.

List<Uri> list = null;
if (!urlDictionary.TryGetValue(url.Authority, out list))
{ 
    list = new List<Uri>();
    urlDictionary[url.Authority] = list;
}
list.Add(url);

ContainsKey 通常不应在这种情况下使用,因为如果密钥确实存在,这将意味着多次(不必要的)哈希查找。

选项 2

如果您愿意使用 ConcurrentDictionary(这会更慢),那么您可以将代码简化为对 AddOrUpdate:

的一次调用
urlDictionary.AddOrUpdate(url.Authority,
    (key) => new List<Uri>() { url },
    (key, oldValue) =>
        {
            oldValue.Add(url);
            return oldValue;
        });

选项 3

可能的第三种方法是完全避免 if 条件并使用 MultiValueDictionary (which allows you to have multiple values for the same key - the same as your existing Dictionary but without you having to explicitly handle the List yourself):

var urlDictionary = new MultiValueDictionary<string, Uri>();
urlDictionary.Add(url.Authority, url);

如果您使用条件运算符,下面是完成它的方法。正如评论中所指出的那样,它没有进行性能优化,但是哈希查找是 ~10ns,所以除非这是在数百万次迭代的紧密循环中,否则它不会产生明显的差异。

urlDictionary[url.Authority] = (urlDictionary.ContainsKey(url.Authority)
                                         ? urlDictionary[url.Authority]
                                         : new List<Uri>())
                                                           .Add(url);

不过,我的建议是使用 Jon Skeet 的旧 MiscUtil 库中的 EditableLookup。这样你就可以隐藏内部的 List<T>,这是一个实现细节,并获得一个与你对多图的期望更一致的接口。

我有类似的场景,并按如下方式实现以减少代码行数

var dictValues = new Dictionary<string, string>();
dictValues.Add("ValueofX", !string.IsNullOrEmpty(valueX) ? valueX : string.Empty);
dictValues.Add("ValueofY", !string.IsNullOrEmpty(valueY) ? valueY : string.Empty);