Turo
Turo

Reputation: 1607

Is there a difference between select new T() and select new T in LINQ

I've been experimenting today with LINQ and DataTable today.

var query = from row1 in table1.AsEnumerable()
            from row2 in table2.AsEnumerable()
            where
            (row1.Field<string>("a") == row2.Field<string>("b"))

            select new Foo
               {
                   Property1 = row1.Field<string>("Hey")
                   Property2 = row2.Field<string>("Ho")
               };

and came to strange conclusion that regardless if I do select new Foo or select new Foo() the query worked exactly the same. I would really like to go into more depth of linq mechanics with delegates etc. to understand this clearly - but for now, for a simple man - is there a difference, and if so, what would this be?

Edit The question has already some similar answers here on SOF, but "object initializer" does not come on top of mind. It is also raised quite specific to LINQ, where 90% of web hints operate on anonymous types(not sure why, I found some good benefit of using concrete types, especially Intellisense). If any materials do specify concrete type implementation example in LINQ I was only able to find new Foo without parentheses . With LINQ construction especially for beginners it might be tricky to find out what is initialized there (object, delegate, predicate etc. - at least it was for me) so hopefully at least some people will find the question and responses useful.

Upvotes: 3

Views: 247

Answers (2)

Frank Bryce
Frank Bryce

Reputation: 8446

These two expressions are exactly the same in C#

new Foo
{
    Property1 = row1.Field<string>("Hey")
    Property2 = row2.Field<string>("Ho")
};

and

new Foo()
{
    Property1 = row1.Field<string>("Hey")
    Property2 = row2.Field<string>("Ho")
};

because Jon said so, and Mr. Lippert tells us why the C# gods chose to make it so in C# 3.0

In your larger example, the select takes an expression of this form, and since the object initializer expression is the same then the larger expression also yields the same result :)

Upvotes: 10

Jakub Lortz
Jakub Lortz

Reputation: 14894

If you use an object initializer and don't pass any parameters to the constructor, the parenthesis can be omitted. Both statements are equivalent.

From C# language specification:

An object creation expression can omit the constructor argument list and enclosing parentheses provided it includes an object initializer or collection initializer. Omitting the constructor argument list and enclosing parentheses is equivalent to specifying an empty argument list.

Upvotes: 6

Related Questions