Suggestion for C# language: Modification to the "new" keyword - Allow type inference in C# to use th

  • Thread starter Thread starter Nicholas Paldino [.NET/C# MVP]
  • Start date Start date
N

Nicholas Paldino [.NET/C# MVP]

If any of you have the time or inclination, I'd love
feedback/ratings/support (and while I loathe to say it, dissent) to a
recommendation I am making for the C# language:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=388649

Basically, it extends type inference to work with the left-hand side of
an assignment, instead of the right. What I mean by that is if you use the
right hand side, you have to use the "var" keyword, like so:

var o = new object();

What I am proposing is something like this:

object o = new();

There is a lot more to it, but that's the jist of it. For the complete
details follow the link above.

There is also post on my blog about it at (first is permalink):

http://www.caspershouse.com/post.aspx?id=53b672b9-3b76-4027-802f-7a0d5ffeb7cd
http://www.caspershouse.com/post/Called-out.aspx

But it's not much more than a brief synopsis (like here) and a link to
the feedback site.

Thanks in advance.
 
What I am proposing is something like this:

object o = new();

Heh, I'm with you. See my response to the thread "Bitmpa.Save & GZipStream -
error" started on 2008-12-13.
 
Jeff,

Thanks for the support. If you like it, vote for it at the Microsoft
Connect site. I've spoken with people internally about it, but that can be
a little bit of a black hole. At least this documents it (and the
support/dissent) in some way.
 
I prefer

var j = new ComplexJob();

Because

SimpleJob j = new();

would create a SimpleJob, but I want a complex job. Using "var" gives you
the short-hand you need (except it's 4 characters longer). I am undecided
about your request. It neither excites me nor fills me with dread. It's
just kind of...


"meh" :-)
 
Nicholas Paldino said:
If any of you have the time or inclination, I'd love
feedback/ratings/support (and while I loathe to say it, dissent) to a
recommendation I am making for the C# language:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=388649

Basically, it extends type inference to work with the left-hand side of
an assignment, instead of the right. What I mean by that is if you use
the right hand side, you have to use the "var" keyword, like so:

var o = new object();

What I am proposing is something like this:

object o = new();

There is a lot more to it, but that's the jist of it. For the complete
details follow the link above.

There is also post on my blog about it at (first is permalink):

http://www.caspershouse.com/post.aspx?id=53b672b9-3b76-4027-802f-7a0d5ffeb7cd
http://www.caspershouse.com/post/Called-out.aspx

But it's not much more than a brief synopsis (like here) and a link to
the feedback site.

Sorry it doesn't get my vote.

The RHS is no longer independant of the LHS and that is just mathematically
wrong. The other way round (as in the case of var) its fine.

I'm also unclear on what actual problem is being solved by it.
 
Peter,

If you look at the full proposal at the Microsoft Connect site, you will
see that it doesn't preclude you from using "var" if you want. It simply is
an alternative with some extra benefits (there are uses outside of the areas
that "var" is limited to now) that "var" doesn't give you when you want to
use it for the purpose of being concise (as opposed to using it for an
anonymous type).

In regards to your second point, the same issue exists with "var" as it
does with my proposal, you have no way of using polymorphism with either
construct (I assume that ComplexJob derives from SimpleJob, or some other
shared base). "var" will give you a type of ComplexJob, my proposal will
give you a type of SimpleJob.
 
Thanks for the support. If you like it, vote for it at the Microsoft
Connect site. I've spoken with people internally about it, but that can
be a little bit of a black hole. At least this documents it (and the
support/dissent) in some way.

Voted. Plus I think you should change your blog post:

-------------
To that end, I recommend the following. Whereas before type-inference used
data from the right hand side in conjunction with the var keyword:

var o = new object();

I suggest we should be able to do something like this:

var o = new();
 
Jeff,

Doh! Thanks. I edited that thing so many times I lost track.

- Nick
 
Anthony,

The same issue exists with "var", so while it might not be
mathematically correct, it is allowable in the language.

When using "var", the left-hand side of the declaration is completely
dependent on the right, it's the same issue, just reversed. Before "var",
there was no dependency on either side.

As for what problem it solves, it doesn't necessarily solve a problem
(it's a recommendation/suggestion). I personally don't like the use of
"var" for the purpose of being concise (as I believe it obfuscates the
code), but that's a personal observation (and I believe it is a problem, but
wouldn't argue the point, as I know it's pointless).

It's a suggestion along the lines of "var" (when considering "var" on
it's own, and not in conjunction with anonymous types) or auto-implemented
properties (although this has the side effect of having an impact on the
structure of the compiled code, in that it auto-generates the backing
fields).
 
Sorry it doesn't get my vote.

The RHS is no longer independant of the LHS and that is just
mathematically wrong. The other way round (as in the case of var) its
fine.

I'm also unclear on what actual problem is being solved by it.

The problem is "unnecessary wordiness."

Why oh why must you write MyClass TWICE:

MyClass c = new MyClass();

when you could just do

MyClass c = new();

Nothing in the proposal STOPS you from using the full syntax, and you would
HAVE to use it if you wanted to assign a derived class:

MyClass c = new MyNewClassDerivedFromMyClass();

but it serves as a less-cluttered shorthand. There aren't many cases where I
think VB.NET has an advantage over C#, but this syntax is one of them,
because there you can already do this:

Dim c As New MyClass();

and you've got a constructed instance without writing MyClass twice. You can
go the long way as well, especially for derivatives:

Dim c As MyClass = New MyNewClassDerivedFromMyClass()
 
Jeff said:
There aren't many cases
where I think VB.NET has an advantage over C#, but this syntax is one
of them, because there you can already do this:

Dim c As New MyClass();

Isn't that the VB equivalent of

var c = new MyClass();

which is already supported by C#?


--
Rudy Velthuis http://rvelthuis.de

"If Tyranny and Oppression come to this land, it will be in
the guise of fighting a foreign enemy."
-- James Madison
 
Isn't that the VB equivalent of

var c = new MyClass();

which is already supported by C#?

Ah, I see the opposition now. I guess it comes down to the fact that I hate
"var" and think it's ugly, makes code harder to read, and will be highly
abused, whereas I think "object o = new()" looks very nice.
 
Well... for one, this is annoying...

var query = new Query();
Results results = query.Execute();

Customer cust = null;
if ( results.Count > 0 ) {
cust = results[0];
}

Chunks of inconsistency like that make me instinctively avoid the use of
var. In VB at least all of the type names are to the right of the variable
name.

PS: Please don't suggest FirstOrDefault() because that's not the point. :)
 
Jeff Johnson said:
The problem is "unnecessary wordiness."

Why oh why must you write MyClass TWICE:

MyClass c = new MyClass();

when you could just do

MyClass c = new();

This would be an OK idea if "= new()" were a single operator. The problem
with this proposal, as I see it, is that "new" is a general-purpose
operator that can be used in other ways. What you are proposing requires
an ugly and intrusive change to the expression parser. Right now, the
parser sees this:
LHS = RHS;
It is then able to evaluate the RHS using normal expression parsing, then
evaluate the LHS using the lvalue parsing, and connect them together with
an assignment

Your change would require special-casing to say
IF this is an assignment statement
AND the left hand side declares a new variable of type X
AND the right side consists only of a "new operator"
THEN assume that the "new" operator should create a type X".

That's very intrusive, and I'd be surprised if there were any single spot
within the compiler to insert this.
 
I was just kind of thinking out loud. I've given it some thought since and
I think it is a good solution to something that has always annoyed me about
C#.


SomeLongClassName c = new SomeLongClassName();

Introducing "var" made this more bearable

var c = new SomeLongClassName();

but this isn't so clear when you are retrieving a result from a method

var c = SomeOtherObject.SomeOtherMethod();

which is why I use an explicit name in such circumstances. I think your
proposal is a much better solution in all cases (not that I have read the
link).


SomeLongClassName c = new();

Gives me the benefits and none of the disadvantages.
 
Nicholas Paldino said:
Anthony,

The same issue exists with "var", so while it might not be
mathematically correct, it is allowable in the language.

When using "var", the left-hand side of the declaration is completely
dependent on the right, it's the same issue, just reversed. Before "var",
there was no dependency on either side.

The issue with var is different. We mathematically expect that with an
equation like this:-

x = a + b

that x is impacted by the result of the RHS. We do not expect x to
participate in anyway in the expression on the RHS. C# 3 allows x to be
influenced not only by the value result of a specific invocation of an
expression but its type is influenced by the expressions type as well.
However the flow is in the same direction, RHS influences LHS but LHS has
no part to play in the RHS.

As for what problem it solves, it doesn't necessarily solve a problem
(it's a recommendation/suggestion). I personally don't like the use of
"var" for the purpose of being concise (as I believe it obfuscates the
code), but that's a personal observation (and I believe it is a problem,
but wouldn't argue the point, as I know it's pointless).

I do agree and I'm sure we've had a long thread here before on how liberally
var should be used. IMO var should primarily used for where the type of the
RHS is an anonymous type. Idomatically its reasonable to use it as a result
of a LINQ expression (even one where the type is known). The only other
place I would use a var is in simple new operations:-

var x = new Thing();

You seem to be proposing that we also be able to do this:-

Thing x = new();

I don't see any improvement with this syntax. In fact it feels wrong
because the flow of imformation is weird in fact so far to me its unique.
Can you think of any other statement or expression where info flows from the
RHS into LHS before the operation on the LHS can complete?
 
Jeff Johnson said:
Ah, I see the opposition now. I guess it comes down to the fact that I
hate "var" and think it's ugly, makes code harder to read, and will be
highly abused, whereas I think "object o = new()" looks very nice.

Seriously you find this:-

MyClass c = new();

Easier to read than

var x = new MyClass();

?
 
Jeff said:
Ah, I see the opposition now. I guess it comes down to the fact that
I hate "var" and think it's ugly

I often use Delphi, so I'm used to it. "Dim", OTOH, is plain ugly, IMO.
<g>
 
Anthony,

I can't think of a situation where info flows from the RHS into LHS
before the operation on the LHS can complete.

However, using your analogy, it could be said that there are situations
where the LHS participates in the equation independently from the RHS. When
you use polymorphism:

IComparable<DateTime> dtComparable = new DateTime(2008, 12, 15);

In this case, the LHS is contributing to what the range of values
assigned to dtComparable can be (in this case, it expands the range to be
anything implementing IComparable<DateTime> not just DateTime, as suggested
by the RHS) independent of the RHS. Note that this was always the case
(until "var" was introduced).

The introduction of "var" was radically different, in that the barrier
which kept each side from influencing the other (since you had to define the
range of types on both sides) was broken down.

The new proposal takes advantage of this fact that those barriers were
broken down.

Because of that previous segregation, I tend to look at this not in
terms of an equation, but in terms of sets (which have no "sides"). With
any declaration and assignment statement (like above) you have a set of
types allowed on the LHS and RHS. If there is an intersection between the
sets, then the assignment is valid. Things like my proposal, "var", even
polymorphism just change the range of the set. In that sense, as long as
there is an intersection of sets, it doesn't matter what side either is on.
 
Seriously you find this:-

MyClass c = new();

Easier to read than

var x = new MyClass();

?

100% seriously. Here's why: the new (no pun intended) method is consistent.
If I want to declare a variable of BaseClass and set it to a derived class,
I can't use var:

var x = new BaseClass();

I get a BaseClass, so I must change the syntax to

BaseClass x = new DerivedClass();

So now the code is mixed, like this:

var x = new BaseClass();
var y = new Whatever();
BaseClass z = new DerivedClass();

but with the other method, it's consistent:

BaseClass x = new();
Whatever y = new();
BaseClass z = new DerivedClass();

You ALWAYS declare the class on the LHS.
 
Back
Top