score:8

Accepted answer

though robert mckee's answer is plausible and raises an interesting point, it is not actually the primary issue that we had in mind when writing that section of the specification. the issue we actually had in mind was this:

class c 
{
  private list<int> mylist = new list<int>();
  // only the code in c can add items to the list.
  public ienumerable<int> items 
  {
    get
    {
      return from item in mylist select item;
    }
  }
}

suppose you have a c in hand. should you be able to write this code?

((list<int>)c.items).add(123);

the existence of a query on a list should not grant code which obtains the query the ability to change the list! it should grant that code the right to execute the query and no more.

now imagine that instead of a list<int>, the query is actually wrapping a database call. if the caller can obtain the underlying database from the query then perhaps they can make queries or edits to that database that the author of the query did not intend them to make.

of course, linq is not designed to be a security system, and if it is your only line of defense against code that wants to attack your database, you're probably pretty vulnerable. but all security systems work better when their components use good "defense in depth". not ever leaking the collection that a query is querying is part of a defensive strategy.

for more on this feature, see my article on the subject:

http://blogs.msdn.com/b/ericlippert/archive/2008/05/12/trivial-projections-are-usually-optimized-away.aspx

score:1

possibly because it would break things like:

var data=(from c in customers select c);
if (something)
  data=data.where(somethingelse);

it makes it more difficult to be abstract about the data if the source might be leaked down the chain rather than using the abstract model. you couldn't really use var data if the query might change its type based on the parameters you use in the query itself.


Related Query

More Query from same tag