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: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: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.
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: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";
Source: stackoverflow.com
Related Query
- Why can the anonymous type be changed if it is supposed to be immutable?
- why can I only access the properties of an anonymous type when I add .toList to the end of my linq query
- How I can pass the LINQ result anonymous type to another method?
- Why not reveal the type and identity of the source to the client?
- Can someone tell me why this simple bit of c# code won't work, involves recursively calling method from within itself to get the root category ID
- c# can I type the code I want to execute in LINQ expressions
- Why can the type of the parameter for InsertOnSubmit not be inferred from the usage?
- Why can I not use the same poco in code first in EF4.1 to project my data?
- How can I filter a dictionary using LINQ and return it to a dictionary from the same type
- Could not find an implementation of the query pattern for source type 'System.Data.Entity.DbSet'
- How can I convert anonymous type to strong type in LINQ?
- This code returns distinct values. However, what I want is to return a strongly typed collection as opposed to an anonymous type
- How can I return an anonymous type from a method?
- Why does using anonymous type work and using an explicit type not in a GroupBy?
- Can Scala collection's seq/par/view/force be seen as a violation of the uniform return type principle?
- Why can't the compiler infer the type for this select call?
- Type inference failed in the call to 'Join' when using anonymous type
- What is the return type for a anonymous linq query select? What is the best way to send this data back?
- LINQ anonymous type not giving the list I need
- Why can't I pass an anonymous type as a parameter to a function?
- How can I write the following code more elegantly using LINQ query syntax?
- The given value of type String from the data source cannot be converted to type int of the specified target column
- Can I use an anonymous type for this Linq grouping?
- The property 'a' is not a navigation property of entity type 'b'. Why not?
- How to send the Anonymous type object to a method
- How to specify the type of an anonymous type while using a generic type
- Why does my text box not recognise the value has changed when I submit?
- Why does IEnumerable.Where method allow a predicate that can change the data?
- Convert anonymous type to array or arraylist. Can it be done
- Could not find an implementation of the query pattern for source type
More Query from same tag
- Iterate over list of iterators linq
- Query for unique id with XDocument
- Linq - Get items from the list based on "weight" and "order"
- C# Linq Query - Extracting multiple groups from a collection (nested groups?)
- How to use logical "and" operator in linq
- Using Extension methods versus lambda expression in c#
- linq Command not getting the answer for DB
- Bind LINQ Query results to Repeater
- Group the results by calender week and get the average
- ASP.NET how to get the currently logged in users name and ID from a SQL database
- Is a Person an aggregate root?
- LINQ GroupBy for multiple Column
- How do you tell at run time if an IEnumerable<T> is deferred?
- What is the benefit of using IQueryable and LINQ queries?
- How can I return a BadRequest on Azure Mobile Services TableController GET template method?
- Need Help Filtering A LINQ Query Using An Entity Framework Navigation Property
- What am I doing wrong in this SQL to LINQ conversion?
- OrderBy exception "At least one object must implement IComparable"
- How to have eager loading in linq join statement?
- Deep loading data with EF6 and LINQ
- TinyInt datatype in SQL Server does not save 0 integer when using LINQ (C#)
- Group inside group linq
- linq projection element count
- Linq Query multiples tables join with array of varying table names
- Search by string field name
- Left outer join in Linq To Entities (The entity or complex type cannot be constructed in a LINQ to Entities query.)
- C# Parse XML with repeated pattern of nodes
- How can I use LINQ to summarize this data--number of relationships grouped by the count of those relationships
- linq to sql, why to use it in MVC instead of traditional queries?
- Parameters in Enumerable.Where