然而,两段代码都有效,我想知道哪一个更好(如果有的话)。有真正的区别吗?我所指的代码部分是在LINQ中。任何见解都将不胜感激。
select new Product {...
第一个片段:
public static IEnumerable<Product> GetProducts(IEnumerable<Product> products)
{
var query = from p in products
select new Product
{
Category = p.Category,
Id = p.Id,
CategoryId = p.CategoryId,
Name = p.Name
};
return query;
}
class Product
{
public int Id { get; set; }
public String Name { get; set; }
public Category Category { get; set; }
public int CategoryId { get; set; }
}
class Category
{
public int Id { get; set; }
public String CategoryName { get; set; }
}
第二个片段:
public static IEnumerable<Product> GetProducts(IEnumerable<Product> products)
{
var query = from p in products
select p;
return query;
}
class Product
{
public int Id { get; set; }
public String Name { get; set; }
public Category Category { get; set; }
public int CategoryId { get; set; }
}
class Category
{
public int Id { get; set; }
public String CategoryName { get; set; }
}
答案 0 :(得分:1)
第一个代码段将返回一个查询,在枚举时,将创建products
枚举中每个对象的副本,并迭代这些副本。 (警告:如果输入对象的类型派生自Product
而实际上不是Product
本身,那么您将把这些对象“切片”为Product
的实例。)
第二个片段将返回一个查询,当枚举时,它将遍历原始序列中的对象,并且在语义上与执行return products;
完全不同(假设products
不为null ,即 - 如果products
为null,则枚举时两个变量都会抛出异常,但会抛出不同的异常类型。)
“tl; dr”版本是:第一种方法复制序列中的对象,第二种方法不复制。
当您需要对序列进行深层复制时,请使用第一个,以便修改结果序列中的对象不会修改原始序列中的对象。事实上,如果您想要修改以影响原始序列,请使用第二种方法,或您将不会修改这两个序列中的任何一个。
除此之外:如果确实需要复制,请考虑在Product
类(public virtual Product Clone()
)上创建虚拟方法,以便(a)克隆克隆逻辑,以及(b)如果您派生Product
,您可以覆盖Clone()
以返回正确类型的副本。