问题
What (if any) is the difference between the results of the following two versions of this VB Linq query?
' assume we have an XElement containing employee details defined somewhere else
Dim ee = From e In someXML.<Employee> _
Select New With {.Surname = e.<Surname>, .Forename = e.<Forename>}
and
Dim ee = From e In someXML.<Employee> _
Select Surname = .Surname = e.<Surname>, .Forename = e.<Forename>
ie what is the point of the New ... With syntax?
I suspect that this has a simple answer, but I can't find it - any links to suitable tutorials or Microsoft documentation would be appreciated.
回答1:
The difference is that the 1st explicitly creates an anonymous type. The 2nd is a query expression, and may use an existing type rather than creating an anonymous type. From the documentation linked by Cameron MacFarland:
Query expressions do not always require the creation of anonymous types. When possible, they use an existing type to hold the column data. This occurs when the query returns either whole records from the data source, or only one field from each record.
回答2:
My understanding is that there is no difference.
New With
is aimed to out-of-query usage like
Dim X = New With { .Surname = "A", .Forename = "B" }
Specifically for Linq queries, you can skip New With
, but it is still useful for other situations. I am not sure, however, since I do not know VB 9 :)
回答3:
There is no functional difference between the two pieces of code you listed. Under the hood both pieces code will use an anonymous type to return the data from the query.
The first piece of code merely makes the use of an anonymous type explicit. The reason this syntax is allowed is that it's possible to return any type from a Select clause. But the type must be used explicitly.
Dim x = From it in SomeCollection Select New Student With { .Name = it.Name }
Joel is incorrect in his statement that the second query may use an existing type. Without an explicit type, a select clause which uses an explicit property name will always return an anonymous type.
回答4:
They're called Anonymous Types.
The main reason for their use is to keep the data from a query in a single object, so the iterators can continue to iterate over a list of objects.
They tend to work as temporary types for storage in the middle of a large or multi-part LINQ query.
回答5:
There is no difference. The compiler will infer the anonymous type.
You most likely want to return the Value of the elements as in e.<Surname>.Value
, which returns a String instead of an XElement.
Your 2nd example could be simplified as
Dim ee = From e In someXML.<Employee> _
Select e.<Surname>.Value, e.<Forename>.Value
because the compiler will also infer the names of the members of the anonymous type.
However, if you have the following class
Class Employee
Private _surname As String
Public Property Surname() As String
Get
Return _surname
End Get
Set(ByVal value As String)
_surname = value
End Set
End Property
Private _forename As String
Public Property Forename() As String
Get
Return _forename
End Get
Set(ByVal value As String)
_forename = value
End Set
End Property
End Class
Then you could change the 1st query to produce an IQueryable(Of Employee)
instead of the anonymous type by using New ... With like so:
Dim ee = From e In someXML.<Employee> _
Select New Employee With {.Surname = e.<Surname>.Value, _
.Forename = e.<Forename>.Value}
回答6:
One difference is that Anonymous types aren't serializable.
来源:https://stackoverflow.com/questions/528610/what-does-the-new-with-syntax-do-in-vb-linq