我编写了以下方法,从Serializable类(POCO)列表中返回一个Unserializable类(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
是类泛型。
答案 0 :(得分:13)
如果SerializableEntity
是值类型,则永远不会是null
。因此,if
语句的正文将始终执行,因为它正在检查null
。 default
关键字将返回泛型类型的默认值。对于参考类型,默认值为null
。对于值类型,它为零(或该值类型的零代表)。
如果您只想将引用类型作为实体,则应该对通用参数设置约束。例如:
List<UnSerializableEntity> ToListOfUnserializables(List<SerializableEntity> entityList)
where SerializableEntity : class
答案 1 :(得分:4)
肯特的回答是准确的,但要更明确地回答你关于Resharper的问题及其抱怨的原因:
对于引用类型(类),检查null就足够了,因为它被认为是引用类型的“默认”值。但是,对于值类型(例如结构),“default”将永远不为null。因此,由于您的SerializableEntity和UnSerializableEntity是泛型,您可以将它们指定为引用或值类型,因此null检查您的操作可能不是您想要的。你想要检查的是确保参数是你真正想要关注的东西。对于引用类型,您不希望自己关注null对象。对于值类型,您不希望自己关注“归零”值。
例如:假设您将DateTime指定为您正在处理的数据类型。你真的想要添加没有设置任何值的DateTimes吗? DateTime的默认值是1/1/0001,而不是null,因此您需要使用if (!Equals(e, default(SerializableEntity)))
而不是if (e != null)