0

两个代码片段都有效,但是,我想知道哪个更好(如果有的话)。有真正的区别吗?我所指的代码部分在 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; }
}
4

1 回答 1

1

第一个片段将返回一个查询,该查询将在枚举时创建枚举中每个对象的副本products,并遍历这些副本。(警告:如果输入对象的类型是派生自Product而不是实际上Product本身,那么您会将这些对象“切片”为 的实例Product。)

第二个片段将返回一个查询,该查询将在枚举时迭代原始序列中的对象,并且在语义上实际上与做没有什么不同return products;(假设它products不为空,即——两种变体在枚举时都会抛出异常ifproducts为 null,但会抛出不同的异常类型)。

“tl;dr”版本是:第一种方法按顺序复制对象,第二种方法不复制。

当您需要制作序列的深层副本时使用第一个,以便修改结果序列中的对象不会修改原始序列中的对象。如果您确实希望修改影响原始序列,请使用第二种方法,或者您不会修改两个序列中的任何一个。


旁白:如果您确实需要复制,请考虑在Product类 ( public virtual Product Clone()) 上创建一个虚拟方法,以便 (a) 封装克隆逻辑,以及 (b) 如果您派生Product,您可以覆盖Clone()以返回正确类型的副本。

于 2013-01-02T23:33:28.247 回答