代码之家  ›  专栏  ›  技术社区  ›  Andreas Grech

C:'default'带泛型的关键字

  •  7
  • Andreas Grech  · 技术社区  · 15 年前

    我编写了以下方法从可序列化类(POCO)列表中返回不可序列化类(LINQ类)的列表:

    List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList)
    {
        var tempList = new List<UnSerializableEntity>();
        entityList.ForEach(e =>
        {
            if (e != null)
            {
                tempList.Add(ConvertFromSerializableToUnserializable(e));
             }
         });
         return tempList;
    }
    

    现在,Resharper已经“抱怨”了这句话: if (e != null) ,建议改为:

    if (!Equals(e, default(SerializableEntity))) 
    

    我的问题是 这种变化实际上改善了什么,或者阻止了什么? 我知道这个上下文中的默认关键字与泛型有关,但我不确定它到底代表什么。

    PS。 UnSerializableEntity SerializableEntity 是类泛型。

    2 回复  |  直到 13 年前
        1
  •  13
  •   Tim Cooper    13 年前

    如果 SerializableEntity 是一个值类型,它不能是 null . 因此,你的身体 if 语句将始终执行,因为它正在检查 无效的 . 这个 default 关键字将返回泛型类型的默认值。对于引用类型,默认值为 无效的 . 对于值类型,它是零(或表示该值类型的任何零)。

    如果只希望引用类型作为实体,则应在泛型参数上设置约束。例如:

    List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList)
        where SerializableEntity : class
    
        2
  •  4
  •   Joseph    15 年前

    肯特的回答是准确的,但要更明确地回答你关于雷瑟的问题以及为什么抱怨:

    对于引用类型(类),检查空值就足够了,因为它被认为是引用类型的“默认”值。但是,对于值类型(如结构),“default”永远不会为空。因此,由于序列化实体和不可序列化实体是泛型,因此可以将它们指定为引用或值类型,因此您所做的空检查可能不是您想要的。您想要检查的是确保参数是您真正想要关注的东西。在引用类型的情况下,您不希望关心空对象。在值类型的情况下,您不希望关心“归零”的值。

    例如:假设您指定一个日期时间作为要处理的数据类型。是否确实要添加没有任何值集的日期时间?日期时间的默认值是1/1/0001,而不是空值,因此您需要使用 if (!Equals(e, default(SerializableEntity))) if (e != null)