C# 3.0 new language features

S

S Chapman

In C# 3.0 there will be radical additions:

(#) "select, from, where" keywords allowing to query from SQL, XML,
collections, and more (Language integrated query (LINQ)) - >>Can
appreciate
(#) Object initialization : Customer c = new Customer();
c.Name="James"; becomes Customer c = new Customer { Name="James" }; -(*!!*) Lambda expressions : listOfFoo.Where(delegate(Foo x) { return
x.size>10;}) becomes listOfFoo.Where(x => x.size>10);
(*!!*) Local variable type inference: var x = "hello"; is
interchangeable with string x = "hello";
(*!!*) Anonymous types : var x = new { Name = "James" }
(*!!*) Extension methods (adding methods to classes by including the
this keyword in the first parameter)
(*) C# 3.0 was unveiled at the PDC 2005, and a Preview, with
specifications is available From the MSDN Page (MSDN).

To me it looks like C# is including features (*!!*) that will enable
people to write unreable code. I cannot appreciate why these changes
are necessary. Can anybody convince me otherwise please?
 
N

Nicholas Paldino [.NET/C# MVP]

S Chapman,

See inline (I've rearranged the items a little):
(#) Object initialization : Customer c = new Customer();
c.Name="James"; becomes Customer c = new Customer { Name="James" }; -

Same here.
(*!!*) Lambda expressions : listOfFoo.Where(delegate(Foo x) { return
x.size>10;}) becomes listOfFoo.Where(x => x.size>10);

Well, it's just shorthand. Personally, I like it, as typing some of the
other stuff is unwieldy. You don't HAVE to use it.
(*!!*) Local variable type inference: var x = "hello"; is
interchangeable with string x = "hello";

I agree that in this instance, it is unexcusable to use it. I would
slap someone who used var in a place where the type was known. However, in
the case where you don't know the return type (when you do a query and it
returns a projection (new anonymous type), you need some way of indicating
that there is something there you are working with, you just don't know
what).
(*!!*) Anonymous types : var x = new { Name = "James" }

This is essential for projections (for example, when you have a table in
SQL Server with three columns, and you select just two of them, that's a
projection). You need a way of easily creating new types.
(*!!*) Extension methods (adding methods to classes by including the
this keyword in the first parameter)

I'm a little wary about this myself. In my opinion, MS could have done
a better job with this, since they kind of dilute the definition of a type
now.
(#) "select, from, where" keywords allowing to query from SQL, XML,
collections, and more (Language integrated query (LINQ)) - >>Can
appreciate

While not all of the features are perfect (extension methods), or have
the potential to be used in the wrong way (var), if you look at the above
query language enhancements, you begin to see that they are all necessary
for enabling the above.

I remember when I saw this a long time ago, when the language
enhancements were presented, and then you see the query enhancements. You
have this "a-ha" moment that hits you like a ton of bricks when you figure
out how it is all interconnected.
 
J

Jon Skeet [C# MVP]

Nicholas Paldino said:
I'm a little wary about this myself. In my opinion, MS could have done
a better job with this, since they kind of dilute the definition of a type
now.

I think extension methods will be fine (and indeed very useful) if MS
improves the syntax for including them. The current (well, last time I
looked) way of doing it was horrible in terms of it not being obvious
what was going on.
 
F

Frans Bouma [C# MVP]

Nicholas said:
S Chapman,

See inline (I've rearranged the items a little):


Same here.

I don't like it but it might be that it looks a bit messy (IMHO)
Well, it's just shorthand. Personally, I like it, as typing some
of the other stuff is unwieldy. You don't HAVE to use it.

I welcome these lambda expressions as writing the delegates is indeed
troubling a lot of people.
This is essential for projections (for example, when you have a
table in SQL Server with three columns, and you select just two of
them, that's a projection). You need a way of easily creating new
types.

though every time you should realize that writing a typed class for
this is essentially better than using var for this. As 'var' makes it
easy (no class to write) it might be people will fall into this trap
and have a hard time reading the code they wrote (or others wrote)
simply because it's var all over the place.
I'm a little wary about this myself. In my opinion, MS could
have done a better job with this, since they kind of dilute the
definition of a type now.

See them as processing methods for a type you can't alter. Like find
methods on a collection type which doesn't have a find method. For this
purpose they're excellent. I first had the assumption they were
actually injecting code into the class so you could add an override to
a method which wasn't overriden in the class, but IMHO that's not
possible. In a way this is unfortunate as it would have made adding
code for validation etc. easier without having to write the code inside
the class, or perhaps in a farfetched scenario: AOP.

FB

--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
 
B

Barry Kelly

I agree that in this instance, it is unexcusable to use it. I would
slap someone who used var in a place where the type was known.

I personally find it annoying to repeat myself particularly where types
with generic arguments are required. I don't find things like:

---8<---
Dictionary<string,Pair<string,int>> x = new
Dictionary<string,Pair<string,int>>(StringComparer.Ordinal);
--->8---

better than

---8<---
I'm a little wary about this myself. In my opinion, MS could have done
a better job with this, since they kind of dilute the definition of a type
now.

True, but at least they permit a form of extending an interface without
breaking it everywhere - something like the once-suggested "default
implementation" in an interface. I think they could be a little
"undiscoverable" from simply eyeballing the code, though - they are a
feature that requires good tool support and strong conventions.

-- Barry
 
N

Nicholas Paldino [.NET/C# MVP]

Barry,

See inline:
I personally find it annoying to repeat myself particularly where types
with generic arguments are required. I don't find things like:

---8<---
Dictionary<string,Pair<string,int>> x = new
Dictionary<string,Pair<string,int>>(StringComparer.Ordinal);
--->8---

better than

---8<---
var x = new Dictionary<string,Pair<string,int>>(StringComparer.Ordinal);
--->8---

I don't agree with this. You can use the using statement, like so:

// Let's assume Sp is short for String-Pair
using SpDictionary = System.Collections.Generic.Dictionary<string,
System.Collections.Generic.Pair<string,int>>;

And then:

SpDictionary x = new SpDictionary(StringComparer.Ordinal);
True, but at least they permit a form of extending an interface without
breaking it everywhere - something like the once-suggested "default
implementation" in an interface. I think they could be a little
"undiscoverable" from simply eyeballing the code, though - they are a
feature that requires good tool support and strong conventions.

I don't have a problem with them extending the interface, it's the way
that it is called makes it so ambiguous. If they had a different
convention, I would like it much more.
 
M

MSDN

var x = "hello"

Are we going back to vb 4.- ?
It looks like we are starting to circle around the code-globe
what happened to type safety... launched into dark matter.

SA
 
J

Jon Skeet [C# MVP]

MSDN said:
var x = "hello"

Are we going back to vb 4.- ?
It looks like we are starting to circle around the code-globe
what happened to type safety... launched into dark matter.

Type safety is still very much intact. "var" just means that the type
of the variable is inferred from the compile-time type of the RHS of
the assignment.

I'm not saying I like it, but it doesn't remove type safety at all.
 
B

Barry Kelly

Nicholas Paldino said:
I don't agree with this. You can use the using statement, like so:

// Let's assume Sp is short for String-Pair
using SpDictionary = System.Collections.Generic.Dictionary<string,
System.Collections.Generic.Pair<string,int>>;

And then:

SpDictionary x = new SpDictionary(StringComparer.Ordinal);

The trouble with this is it leads to lots of local names for the same
type, which may get out of sync with one another (maybe a different name
is used in a different location). I also think it's less readable,
because you can no longer see the actual type of x - you have to hunt
for the using declaration.

-- Barry
 
M

Mattias Sjögren

To me it looks like C# is including features (*!!*) that will enable
people to write unreable code.

You've been able to write completely unreadable code in C# since
version 1, so that's nothing new. I prefer to look at how and when the
new features are useful, not how they can be abused (which most
features can be).


Mattias
 
J

james.curran

var x = "hello"
Do not confuse "'var" with Object. "var" is just a compiler trick, to
have it deduce, at compile-time what the type is:


object x = 1234; // boxed
Console.WriteLine(x.GetType().Name); // prints "Object"
x = "ABCD"; // OK.

var y = 1234; // not boxed
Console.WriteLine(y.GetType().Name); // prints "Int32"
y="ABCD"; // compile-time syntx error.
 
O

Ole Nielsby

Barry Kelly said:
I personally find it annoying to repeat myself particularly where types
with generic arguments are required. I don't find things like:

---8<---
Dictionary<string,Pair<string,int>> x = new
Dictionary<string,Pair<string,int>>(StringComparer.Ordinal);
--->8---

better than

---8<---
var x = new Dictionary<string,Pair<string,int>>(StringComparer.Ordinal);
--->8---

Some sense in that, but IMO they placed the type inference in
the wrong place.

Why not allow:

Dictionary<string,Pair<string,int>> x = new(StringComparer.Ordinal);

or

Dictionary<string,Pair<string,int>> x = new
babe(StringComparer.Ordinal);

or whatever keyword seems appropriate.

This would keep with the style of typed declarations, yet relieve the
programmer of some finger- and eyestrain.
 
N

Nicholas Paldino [.NET/C# MVP]

Ole,

The var is needed because of anonymous types, which are needed for
projections, which are needed for the query operations.

If you make an anonymous type, then you need var.

I agree though, they should allow that syntax in the language (where you
can just have new, and not the type name, but have it in the declaration).
 
M

MSDN

James,

Thank you for the enlightenment.

SA


Do not confuse "'var" with Object. "var" is just a compiler trick, to
have it deduce, at compile-time what the type is:


object x = 1234; // boxed
Console.WriteLine(x.GetType().Name); // prints "Object"
x = "ABCD"; // OK.

var y = 1234; // not boxed
Console.WriteLine(y.GetType().Name); // prints "Int32"
y="ABCD"; // compile-time syntx error.
 
M

MSDN

Jon,

Thank you the lesson.

SA


Jon Skeet said:
Type safety is still very much intact. "var" just means that the type
of the variable is inferred from the compile-time type of the RHS of
the assignment.

I'm not saying I like it, but it doesn't remove type safety at all.
 
J

Jon Davis

Nicholas Paldino said:
I agree that in this instance, it is unexcusable to use it. I would
slap someone who used var in a place where the type was known. However,
in the case where you don't know the return type (when you do a query and
it returns a projection (new anonymous type), you need some way of
indicating that there is something there you are working with, you just
don't know what).

This has me very troubled. There is already a solution for this in C# 1.0.
It's called boxing (System.Object and reflection). I thought we dismissed
the variant (which is essentially how I read "var") to go to hell? But if
"var" here is strongly typed at compile-time, I don't mind that so much
because it would be "seen" in its true type during reflection, rather than
as a boxed object.

Still, this "solution" is just for the sake of laziness. This was introduced
for the sake of LINQ / C-Omega to do database lookups without doing a manual
look-up on the field type. I don't think it to be appropriate for a
programmer to not be required to know exactly what field type is being
brought back.


Jon
 
B

Barry Kelly

Ole Nielsby said:
Some sense in that, but IMO they placed the type inference in
the wrong place.

Why not allow:

Dictionary<string,Pair<string,int>> x = new(StringComparer.Ordinal);

This would keep with the style of typed declarations, yet relieve the
programmer of some finger- and eyestrain.

Just to add: as I'm sure you know, the type of expression trees is
usually annotated from the bottom up, for good reasons. C++ has set a
wonderful example in what happens to a language when it is designed with
no concerns for implementation difficulties.

This 'var' is something I've added to my own (functional) languages: an
immutable placeholder for an expression so it can in turn be reused,
turning an expression tree into a dag. It works well, and I'm delighted
to see it in C#.

-- Barry
 
B

Barry Kelly

Jon Davis said:
Still, this "solution" is just for the sake of laziness. This was introduced
for the sake of LINQ / C-Omega to do database lookups without doing a manual
look-up on the field type. I don't think it to be appropriate for a
programmer to not be required to know exactly what field type is being
brought back.

In many ways, I find that the arguments against 'var' strongly
reminiscent of the arguments in favour of hungarian notation. The
semantic meaning of the code should be visible by reading it.

Fields and properties may be declared screenfuls and even files away
from where they are used, yet these days one expects that people will
know what they represent even though they don't have an alphabet soup
attached any more labeling their types. 'var' does exactly the same
thing for local variables. It makes perfect sense to me.

-- Barry
 

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