score:11
First, there is no anonymous type involved.
This string[] arr = { "Agnes", "Allan", "Benny" };
is an array creation expression.
result
is IEnumerable<string>
and in both LINQ statements you are just creating a query.
This is what is going on:
array creation expression
string[] arr = { "Agnes", "Allan", "Benny" };
query arr and returns IEnumerable<string>
var result = arr.Where(a => a.StartsWith("A")).Select(a => a);
assigns results a new query on arr returning IEnumerable<string>
result = arr.Where(a => a.EndsWith("n")).Select(a => a);
As far as, for understanding immutability, think of String
also see this article: Immutable types: understand their benefits and use them
score:3
You have an anonymous type when you do something like:
var anon = new { X = 5, Y = 6 };
There are some pretty simple rules: you can't express the type of an anonymous type (so often you use var
)... there must be a new {
... You must give a name to the properties and a value X = 5
.
What you are doing is creating an array of string[]
using an array initializer. You are even writing it:
string[] arr = ...
And you aren't modifying anything... result
is another variable, referencing an IEnumerable<>
(a new object you are creating) and then referencing another IEnumerable<>
At the end of your code you have 6 objects (a little more, but we will ignore some invisible objects):
- The array referenced by
arr
(and referenced by the twoIEnumerable<>
) - The second
IEnumerable<>
, referenced byresult
, that has a reference toarr
- The first
IEnumerable<>
, not referenced by anyone (the GC will collect it before or later), that has a reference toarr
- 3x
string
, all referenced byarr
. Note thatIEnumerable<>
are "lazy", so they don't contain any reference to anystring
The result
variable is assigned twice, to two different IEnumerable<>
. It is nearly always legal to reassign variables (exception are readonly
fields). it is clearly legal to do:
string foo = "Foo";
foo = "Bar";
score:1
LINQ methods like Where()
and Select()
don't change the underlying array. It creates a new object. The created result
is of type IEnumerable<string>
, LINQ just filters the array so if you will iterate over it later, you will just get values that match Where
and Select
but your arr
object will remain unchanged.
score:2
Another useful concept to understand is the difference between type, instance and variable.
Simplifying, type is like a blueprint, it describes what an instance of the type will look like:
class Car
{
public int Doors {get; set;}
public string EngineType { get; set;}
}
The code above describes type. You can make many instances of this type:
Car truck = new Car { Doors = 2, EngineType = "BigEckingEngine" };
Car pickup = new Car { Doors = 5, Engine Type = "4 cylinder" };
etc... Note how variables truck and pickup house your instances. But variables are just that, they can house any instance of their respective type, so while it does not make much sense you can do this:
Car tmp = truck;
truck = pickup;
pickup = tmp;
The instances themselves has not changed. But the variables now hold different instances.
The instances of this example Car
class above are mutable. So you can do this:
pickup.Doors = 99;
Should the type be immutable, you would not be able to do that, but you are still can do variable assigning as in the example with the tmp
variable freely, regardless of type being mutable or not, because such assignment do not change instances.
As noted, your example does not contain an anonymous type, but even if it did, it does not involve any kind of mutation you are asking about.
score:1
It's worth expanding the other answers to show that a CONCRETE resolution of a LINQ query is not the same as a IEnumerable<T>
and that neither have anything to do with anonymous type immutability.
If you created the following array of anonymous types:
var arr = new[] { new { Name = "Agnes"}, new { Name = "Allan" }, new { Name = "Benny" }};
arr.GetType().Dump();
var result = arr.Where(a => a.Name.StartsWith("A")).Select(a => a)
result = arr.Where(a => a.Name.EndsWith("n")).Select(a => a);
result.Dump();
in my case,
<>f__AnonymousType0`1[System.String][]
and
"Allan"
are respectively outputted, because result type is actually
System.Linq.Enumerable+WhereSelectArrayIterator`2[
<>f__AnonymousType0`1[System.String],
<>f__AnonymousType0`1[System.String]]
In addition, if I try to resolve the IEnumerable and then re-update the result:
var result = arr.Where(a => a.Name.StartsWith("A")).Select(a => a).ToList();
result = arr.Where(a => a.Name.EndsWith("n")).Select(a => a).ToList();
I once again get an output of
"Allan"
However, in this case my result type has been reevaluated to
System.Collections.Generic.List`1[<>f__AnonymousType0`1[System.String]]
since ToList()
is creating a new collection. I can technically add and remove to that collection at will since the collection itself is quite willing to be mutated.
Finally, that does not mean that the underlying anonymous type object is not immutable!
result.First ().Name = "fail";
Will fail, regardless of result being a list with the following error:
Property or indexer 'AnonymousType#1.Name' cannot be assigned to -- it is read only
precisely because it is immutable.
Source: stackoverflow.com
Related Articles
- Why can the anonymous type be changed if it is supposed to be immutable?
- This code returns distinct values. However, what I want is to return a strongly typed collection as opposed to an anonymous type
- c#: Isn't Where(), OrderBy() and Select() from Enumerable Class supposed to take a delegate type, lambda expression or anonymous type as a parameter
- get selected value from combobox with data source is anonymous type
- Return anonymous type results?
- How to create LINQ Expression Tree to select an anonymous type
- How to return anonymous type from c# method that uses LINQ to SQL
- A dictionary where value is an anonymous type in C#
- Setting anonymous type property name
- Cannot assign null to anonymous property of type array
- IEqualityComparer for anonymous type
- Convert anonymous type to class
- Return Anonymous Type from a function
- Could not find an implementation of the query pattern for source type 'System.Data.Entity.DbSet'
- Creating a list of Anonymous Type in VB
- How can I convert anonymous type to strong type in LINQ?
- anonymous type and multiple properties
- Anonymous Type Name Collision
- LINQ select query with Anonymous type and user Defined type
- How can I return an anonymous type from a method?
- Invalid anonymous type member declarator in LINQ
- How to assign a nullable int property in an anonymous type in LINQ with a Union?
- group by using anonymous type in Linq
- Linq, use "variable" inside a anonymous type
- return list with anonymous type in entity framework
- Why does using anonymous type work and using an explicit type not in a GroupBy?
- is it possible to have a conditional field in an anonymous type
- Anonymous Type Appears in both Error
- C# Anonymous Type access from other method
- C# LINQ build expression with anonymous type
- LEM2 algorithm implementation in C#
- How can a ForEach loop in LINQ know about the values in the prior iteration of the loop?
- C# EF Linq Create a list based on another list
- 'List' does not contain a definition for 'Where'
- Linq Get Data Based On Single Column Value
- How to select a list where one property is not in a list of integers?
- Adding an Ienumerable list in ViewModel which will be Enumerated In View
- Linq2sql Find Top Subscribers Question
- Find the number that don't exist in another array
- Entity Framework select by child table last state
- Handle null element in linq
- Do I have to refresh a LINQ object that represents a view/table row after I do a submitchanges operation that may alter it?
- Linq Cast<T> with System.Type
- How do I transfer this logic into a LINQ statement?
- Rotating List(Of T)
- How to force XDocument to output the prolog in uppercase while preserving identation and formatting?
- Retrieve List from listView.ItemsSource
- Using LINQ, get all the objects from a list with a specific column value?
- Linq generic parameter error
- Better Linq GroupBy