Amazing LINQ for .Net

  • Thread starter William Stacey [MVP]
  • Start date
C

Christoph Nahr

Yes it's silly, but that wont stop people from doing it. Every feature
that can be abused will be (I'm sure that's some kind of law of
nature).

Okay, but given the choice I'd rather not use a language that avoids
any feature that could *possibly* be abused. You'd end up with a
subset of Java if you followed that policy...
I wouldn't use 'var' for that either. I prefer importing the namespace
with 'using' and letting the editor complete the long type name for
me.

Depends on whether you want the whole namespace imported, how long the
typename itself is, and whether it contains generic type arguments (in
which case you need an individual using statement just for the type).
 
C

Christoph Nahr

what if you write, var x = GetFunkyReturn(); (I assume this should be
legal? since compiler should be able to implicitly tell what x is)

Yes, but you cannot declare GetFunkyReturn to return var -- the method
itself must list an explicit type. Still, this particular example is
bad practice IMO since the declaration does not show the type.

Although, come to think of it, real code would probably say something
like var customer = GetCustomer() and then it would be fairly clear
that customer is of type Customer.
 
F

Frans Bouma [C# MVP]

Christoph said:
Yes, but you cannot declare GetFunkyReturn to return var -- the method
itself must list an explicit type. Still, this particular example is
bad practice IMO since the declaration does not show the type.

Although, come to think of it, real code would probably say something
like var customer = GetCustomer() and then it would be fairly clear
that customer is of type Customer.

But if a method has to return an explicit type, isn't 'var''s usage
pretty limited? I mean, besides the few people who fetch data directly
from the db in a code behind page in asp.net, no-one will be able to
utilize 'var' as you likely have to pass back the fetched results, in
which case it is strongly typed, so WHY would you then use:

var foo = myBlObject.GetEntityList<CustomerEntity>(...);
instead of
List<CustomerEntity> foo =
myBlObject.GetEntityList<CustomerEntity>(...);

as GetCustomers returns a typed list anyway, and the type is known?!

Isn't it so that 'var foo = ...' is only used by the lazy bunch who
don't want to spend 2 seconds longer typing to make the code more
readable?

C# is C#, it's not Miranda, it's not prolog, it's not VB.NET and it's
not Ruby. It's C#. If people want functional programming, or dynamic
typing, use a different language.

FB
--
 
F

Frans Bouma [C# MVP]

William said:
If yo don't know what t is upfront, you can't strong type in where
and select. Actually, I makes a bit of sense. Anders explains this
pretty well in the Channel 9 vid. As for the var thing, I think this
would have been imposible to do without something like it.

No it doesn't make sense. It does make sense in SQL, but not in C#. In
C# you work with typed objects, not with on-the-fly created types. That
is a big change, fundamental even. I mean: after aliasing Customer to c
and Order to o I can use c and o in the select statement.

But that's totally upside down with how the language is setup. (IMHO).

Also, teh compiler can perfectly understand a select upfront and a
from later on, intellisense can't. So placing it at the top is
modifying a language for the toolkit in which it's used. That's a
principle I am against: the language has to have a structure which
makes sense FOR THE LANGUAGE, not for the tool it's used in. Tools
change, languages hardly change (relatively).

FB

--
 
F

Frans Bouma [C# MVP]

Bruce said:
...but you have to realize the intent. The intent was not to embed a
database language into C#. The intent was to make it much easier to
get information _out of_ a database into .NET / C#. I think that it
does that admirably.

For my money, anyone working for me who tries to use this new feature
as a full-scale query language will get a kick in the pants. I have a
database for defining views. These new constructs are just for loading
and sifting through information, not reinventing SQL inside C#

Correct, but that doesn't mean the system of Linq isn't usable for
data-access, on the contrary.

However!, the problem is that it's too focussed on table + raw sql, at
least the examples presented. The REAL goal is to use it for object
oriented way of using your database, which means:
instead of thinking in 'tables' and 'rows' and 'columns' you think in
'set of objects' and defining filters on these objects and ask a piece
of logic to get these objects for you from the total set of objects.

FB

--
 
C

Christoph Nahr

But if a method has to return an explicit type, isn't 'var''s usage
pretty limited?

Yep. AFAIK it's really only needed for inline construction of
anonymous types. The rest is mere convenience.
Isn't it so that 'var foo = ...' is only used by the lazy bunch who
don't want to spend 2 seconds longer typing to make the code more
readable?

See, the thing is that people like me think the var version is _more_
readable, not less so. You seem to think that code always gets more
readable as it gets longer. I think that the most readable code is
the _shortest_ code that still conveys the intended meaning.
C# is C#, it's not Miranda, it's not prolog, it's not VB.NET and it's
not Ruby. It's C#. If people want functional programming, or dynamic
typing, use a different language.

Well, that's just a ridiculous statement. C# started out as a Java
clone with some C features, and its design philosophy was always
similar to Python: if a feature is useful, adopt it! C# is not a
single-minded reseach language that must be kept "pure".

You might as well say "if people want OOP they should use Smalltalk"
as an argument to keep OOP out of all existing procedural languages.
And you could have made the same complaint when generics were
introduced: "If people want generics they should use C++"!

Functional programming is just as valid as the two other paradigms,
procedural and object-oriented programming. It's just another tool in
a toolbox. The fact that FP used to be limited to research languages
is a historical coincidence, not some holy law of design.

Also, C# 3.0 does not have dynamic typing, just inferred typing, which
is merely a variant of static typing, and one that's widely accepted
as an improvement (C++ will add the auto keyword which is similar to
var). There is such a thing as technical progress...
 
W

William Stacey [MVP]

No it doesn't make sense. It does make sense in SQL, but not in C#. In
C# you work with typed objects, not with on-the-fly created types. That
is a big change, fundamental even. I mean: after aliasing Customer to c
and Order to o I can use c and o in the select statement.

But that's totally upside down with how the language is setup. (IMHO).

Also, teh compiler can perfectly understand a select upfront and a
from later on, intellisense can't. So placing it at the top is
modifying a language for the toolkit in which it's used. That's a
principle I am against: the language has to have a structure which
makes sense FOR THE LANGUAGE, not for the tool it's used in. Tools
change, languages hardly change (relatively).

But is does make sense for a couple reasons.
1) It is actually more logical as it flows down from least specific to more
specific.
a) First you define your domain space (what we are operating over) using
From.
b) Then you filter (if needed) with where.
c) Then Select the fields you need from prior results.
2) SQL actually does it backwards. As Anders said, "In SQL, the scope of a
variable flows backwards because a variable is introduced in the From
clause, but is in-scope above the From clause." Using the Linq order, scope
flows down as it should like the rest of the language. Other query
languages (i.e. XQuery) do the same thing.
3) If Select where first and you started typing:
var x = select ...
What would Select show you? You don't know what your selecting from
yet?
 
J

Jon Skeet [C# MVP]

Christoph Nahr said:
But this quote is hardly true for int (also three letters) or string
or double (six instead of three letters, all lowercase... please!).

Trouble is, once you get into the habit, I could see it becoming the
default way of doing things - even when there's no benefit whatsoever.
Yes, but sometimes you may wish to avoid importing big namespaces
wholesale just for a single type.

For any particular reason?
Besides, the type name might use
generic type parameters in which case you'd need an individual using
statement just for that type.

Indeed - but personally I'd rather see a semantically meaningful name
used throughout the code anyway.
I'll defy you all and use them with wild abandon on any types longer
than ten characters! :p

:)
 
B

Bruce Wood

But if a method has to return an explicit type, isn't 'var''s usage pretty limited?

Yes, and Anders was explicit about that: var declarations for anonymous
types (usually resulting from projections) is limited to local
variables only. You have to _do_ something with that type--transform it
into something else--before you can return it from a method, or pass to
a method, or assign it to a field, unless you want to make it into an
Object and use Reflection on it later. (Yuck.)
 
C

Christoph Nahr

Trouble is, once you get into the habit, I could see it becoming the
default way of doing things - even when there's no benefit whatsoever.

Okay, but at some point you have to trust developers to make the right
decision. People could also abuse goto, or exceptions, or any other
construct in C# 1.0 and 2.0.
For any particular reason?

There might be a conflict between type names in different namespaces.
Remember, that's why namespaces were introduced in the first place. :)
Indeed - but personally I'd rather see a semantically meaningful name
used throughout the code anyway.

If it's used repeatedly in a class/file I'd agree but for one-time use
the var method is simpler.
 
J

Jon Skeet [C# MVP]

Christoph Nahr said:
Okay, but at some point you have to trust developers to make the right
decision. People could also abuse goto, or exceptions, or any other
construct in C# 1.0 and 2.0.

Indeed. And people do abuse features, unfortunately (or often use them
without understanding them).
There might be a conflict between type names in different namespaces.
Remember, that's why namespaces were introduced in the first place. :)

In that case, import the single type, or if you need to refer to both
types in the same class (rare, in my experience) have two different
explicit using directives.
If it's used repeatedly in a class/file I'd agree but for one-time use
the var method is simpler.

Simpler to type, yes. Simpler to read though?
 
R

richard.hein

" Isn't it so that 'var foo = ...' is only used by the lazy bunch who
don't want to spend 2 seconds longer typing to make the code more
readable? "

No, you've unfortunetely completely missed the point. The point of
type inference is so you don't have to know in advance what the type
is. The compiler will figure out what the type is, so it's still
strongly typed, and you get to write the same code to work on that var
no matter what type it is -- for example if you have an extenstion
method called Select() you don't have to know the type of the var you
are calling Select() to use it.

Take a look at more code samples, you'll get the idea.
 
J

Jon Skeet [C# MVP]

" Isn't it so that 'var foo = ...' is only used by the lazy bunch who
don't want to spend 2 seconds longer typing to make the code more
readable? "

No, you've unfortunetely completely missed the point.

I don't think so.
The point of type inference is so you don't have to know in advance
what the type is. The compiler will figure out what the type is, so
it's still strongly typed, and you get to write the same code to work
on that var no matter what type it is -- for example if you have an
extenstion method called Select() you don't have to know the type of
the var you are calling Select() to use it.

But Frans' point is that the code is more readable if the reader can
see immediately what the type is, rather than letting the compiler
infer it.

To give a slightly different example, using "var" is like writing code:

int x = y<<z + a;

The compiler knows the operator precedence, but the code is cleaner if
you write:

int x = y << (z+a);
 
R

Richard Blewett [DevelopMentor]

The fundedmental issue isn't that type inference makes code quicker to type, its that its absolutely vital in the face of anonymous types:

??? foo = new {5, "Hello"};

So what are you going to type in for ??? - thats why type inference is necessary.

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

" Isn't it so that 'var foo = ...' is only used by the lazy bunch who
don't want to spend 2 seconds longer typing to make the code more
readable? "

No, you've unfortunetely completely missed the point.

I don't think so.
The point of type inference is so you don't have to know in advance
what the type is. The compiler will figure out what the type is, so
it's still strongly typed, and you get to write the same code to work
on that var no matter what type it is -- for example if you have an
extenstion method called Select() you don't have to know the type of
the var you are calling Select() to use it.

But Frans' point is that the code is more readable if the reader can
see immediately what the type is, rather than letting the compiler
infer it.

To give a slightly different example, using "var" is like writing code:

int x = y<<z + a;

The compiler knows the operator precedence, but the code is cleaner if
you write:

int x = y << (z+a);

--
Jon Skeet - <[email protected]>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

[microsoft.public.dotnet.languages.csharp]
 
J

Jon Skeet [C# MVP]

Richard Blewett said:
The fundedmental issue isn't that type inference makes code quicker
to type, its that its absolutely vital in the face of anonymous
types:

??? foo = new {5, "Hello"};

What's the anonymous type here, out of interest? I've seen Select
examples, but this is somewhat different. I haven't had a chance to
actually read the spec yet...
So what are you going to type in for ??? - thats why type inference
is necessary.

And I have no problem with that. When you *only* use it for that
purpose, that's reasonable. It's the idea that it's a perfectly
reasonable thing to use for all local variables that I dislike
intensely.
 
C

Christoph Nahr

What's the anonymous type here, out of interest? I've seen Select
examples, but this is somewhat different. I haven't had a chance to
actually read the spec yet...

I don't think you can actually write it like this. The compiler needs
to get the new type's property names from somewhere:

var foo = new { Value = 5, Text = "Hello" };

The anonymous type is then a simple data container with some secret
name, two backer variables, and two get/set properties:

public sealed class SecretClass {
int _value; string _text;

public int Value {
get { return this._value; }
set { this._value = value; }
}

public string Text {
get { return this._text; }
set { this._text = value; }
}
}
 
C

Christoph Nahr

Simpler to type, yes. Simpler to read though?

Absolutely, since you don't even have to look up the using section at
the top of the file to determine the actual type!
 
J

Jon Skeet [C# MVP]

Christoph Nahr said:
Absolutely, since you don't even have to look up the using section at
the top of the file to determine the actual type!

You have to look at the assignment though - and you may well be a long
way from that as well as the using statement.

The difference is that the using statement would show the intent,
rather than just the types involved.
 
R

Richard Blewett [DevelopMentor]

Ahh yes, sorry, I was using the Outlook compiler ;-)

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

What's the anonymous type here, out of interest? I've seen Select
examples, but this is somewhat different. I haven't had a chance to
actually read the spec yet...

I don't think you can actually write it like this. The compiler needs
to get the new type's property names from somewhere:

var foo = new { Value = 5, Text = "Hello" };

The anonymous type is then a simple data container with some secret
name, two backer variables, and two get/set properties:

public sealed class SecretClass {
int _value; string _text;

public int Value {
get { return this._value; }
set { this._value = value; }
}

public string Text {
get { return this._text; }
set { this._text = value; }
}
}
 
F

Frans Bouma [C# MVP]

" Isn't it so that 'var foo = ...' is only used by the lazy bunch who
don't want to spend 2 seconds longer typing to make the code more
readable? "

No, you've unfortunetely completely missed the point. The point of
type inference is so you don't have to know in advance what the type
is. The compiler will figure out what the type is, so it's still
strongly typed, and you get to write the same code to work on that var
no matter what type it is -- for example if you have an extenstion
method called Select() you don't have to know the type of the var you
are calling Select() to use it.

Take a look at more code samples, you'll get the idea.

Richard, I didn't miss the point, I fully understand what the purpose
is and what problem it solves (as every O/R mapper programmer runs into
that problem pretty quickly).

I just want the language to be readable without bells and whistles
provided by a tool, the language by itself should be readable without
these. IMHO, 'var' doesn't provide that clarity, it supports obscurity,
as the type it contains is hidden for you and the aspects of that type
are (mainly) only available to you by using intellisense

FB

--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top