Anonymous
Anonymous

Reputation: 1979

object initializer

Both snippets of code work, however, I'm wondering which one is a better(if any). Is there a real difference? The part of the code I'm referring to is in the LINQ. Any insight would be appreciated.

select new Product {...

First Snippet:

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; }
} 

Second Snippet:

 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; }
}

Upvotes: 0

Views: 110

Answers (1)

cdhowie
cdhowie

Reputation: 169008

The first snippet will return a query that will, when enumerated, create a copy of each object in the products enumerable, and iterate over those copies. (Caveat: If the input objects are of a type derived from Product and not actually Product itself, then you will "slice" those objects into instances of Product.)

The second snippet will return a query that will, when enumerated, iterate over the objects in the original sequence, and really isn't semantically different from doing return products; (assuming that products is not null, that is -- both variations would throw an exception when enumerated if products was null, but would throw a different exception type).

The "tl;dr" version is: the first approach copies the objects in the sequence, the second one does not.

Use the first when you need to make a deep copy of a sequence so that modifying the objects in the resulting sequence do not modify the objects in the original sequence. Use the second approach if you do, in fact, want modifications to affect the original sequence, or you will not be modifying either of the two sequences.


Aside: If you do need to take copies, consider creating a virtual method on the Product class (public virtual Product Clone()) so that (a) the cloning logic is encapsulated, and (b) if you derive Product, you can override Clone() to return a properly-typed copy.

Upvotes: 1

Related Questions