【问题标题】:Return null when dictionary with non-nullable values doesn't has a match当具有不可为空值的字典不匹配时返回 null
【发布时间】:2020-08-01 18:51:53
【问题描述】:

我有一个整数类型的字典。当我使用 Nullable<int> 类型的属性之一填充我的类时,我想使用基于给定产品 ID 的字典中的值填充此属性。

当给定的产品 id 没有对应的值时,如何获得可为空的类型?

public class OrderLine
{
    public int? AvailableQuantity { get; set; }
}

var selectedProductId = Guid.NewGuid();
var products = new Dictionary<Guid, int>
{
    { Guid.NewGuid(), 1 },
    { Guid.NewGuid(), 2 },
    { Guid.NewGuid(), 3 },
};

var result = new OrderLine
{
    Id = Guid.NewGuid(),
    ProductId = selectedProductId,
    AvailableQuantity = products.GetValueOrDefault(selectedProductId, default)
};

上面的方法返回0而不是null

当我尝试时编译器无法编译

AvailableQuantity = products.GetValueOrDefault(selectedProductId, default(int?))

方法 'TValue 的类型参数 System.Collections.Generic.CollectionExtensions.GetValueOrDefault(这个 IReadOnlyDictionary, TKey, TValue)' 无法推断 从用法上。尝试明确指定类型参数。

我无法更改字典的类型。字典是一种广泛使用的方法的返回类型。这是我们需要处理产品 id 不能在该字典中的情况的第一种情况。

我想避免枚举字典以将其类型更改为可空

【问题讨论】:

    标签: c# dictionary collections


    【解决方案1】:

    您可以编写一个使用 TryGetValue 的 C# 扩展

    例如

    public static class DictionaryExtensions
    {
        public static TValue? GetValueOrNull<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key)
            where TValue : struct
        {
            if (dict.TryGetValue(key, out TValue value))
            {
                return value;
            }
    
            return null;
        }
    }
    

    用法:

    products.GetValueOrNull(selectedProductId);
    

    PS:此扩展也适用于 int 以外的其他类型,例如decimalbool 等结构体类型

    【讨论】:

    • 不错的通用版本 ;)
    • 这与 System.Collection 命名空间中已有的 GetValueOrDefault 方法不同吗?
    • @Morten_564834 我也这么认为,但在这种情况下GetValueOrDefault 将返回类型int 和值0,而不是请求的null。这里输入的是new Dictionary&lt;Guid, int&gt; 而不是new Dictionary&lt;Guid, int?&gt;
    • @Julian 是的,谢谢,我还需要一个可为空的参数 new Dictionary GetValueOrDefault 没有。
    【解决方案2】:

    如果你只这样做一次 - 使用三元运算符

    Quantity = products.TryGetValue(productId, out var qty) ? qty : default(int?)
    

    如果您要在多个地方执行此操作,请将上面的代码包装到扩展方法中

    【讨论】:

      【解决方案3】:

      你得到默认值 0,因为它是int 的默认值(不可为空)。

      要获取null 的默认值,将字典中的值类型更改为int?(可为空):

      var products = new Dictionary<Guid, int?>
      {
          { Guid.NewGuid(), 1 },
          { Guid.NewGuid(), 2 },
          { Guid.NewGuid(), 3 },
      };
      

      【讨论】:

      • 抱歉,我无法更改字典的类型
      【解决方案4】:

      请尝试

      var products = new Dictionary<Guid, int?>
      {
      { Guid.NewGuid(), 1 },
      { Guid.NewGuid(), 2 },
      { Guid.NewGuid(), 3 },
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        • 2021-08-06
        • 2016-12-11
        • 2019-10-04
        • 1970-01-01
        • 2021-07-08
        相关资源
        最近更新 更多