tags:

views:

725

answers:

13

Background

Currently, if I want to create a new object in C# or Java, I type something similar to the following:

List<int> listOfInts = new List<int>(); //C#
ArrayList<String> data = new ArrayList<String>(); //Java

C# 3.0 sought to improve conciseness by implementing the following compiler trick:

var listofInts = new List<int>();

Question

Since the compiler already knows that I want to create a new object of a certain type (By the fact that I'm instantiating it without assigning it a null reference or assigning a specific method to instantiate it), then why can't I do the following?

    //default constructors with no parameters:
    List<int> listOfInts = new(); //c#
    ArrayList<String> data = new(); //Java

Follow Up Questions:

  1. What are possible pitfalls of this approach. What edge cases could I be missing?
  2. Would there be other ways to shorten instantiation (without using VB6-esque var) and still retain meaning?

NOTE: One of the main benefits I see in a feature like this is clarity. Let say var wasn't limited. To me it is useless, its going to get the assignment from the right, so why bother? New() to me actually shortens it an gives meaning. Its a new() whatever you declared, which to me would be clear and concise.

+28  A: 

C# saves in the other end:

var listOfInts = new List<int>();
Peter Lillevold
This is a .net 3.0+ implementation. is there a 2.0 version that works as well or do you still have to do it like List<int> listOfInts = new List<int>();?
Ioxp
It's not .NET 3.0. It's C# 3.0. You can still use it when targeting .NET 2.0. But no, there's no equivalent in C# 2.0.
Jon Skeet
@Ioxp - You can make 2.0 assemblies with var perfectly fine. var is a C# 3.0 compiler feature. The compiled code is identical to an explicitly typed variable.
Peter Lillevold
small but useful trick in C# 3.0
Vimvq1987
+4  A: 

Your version is less readable, sorry.

Code is meant to be read by humans, only incidentally by machines.

Genericrich
I'm sorry, but that is absolutely false.Code is made to be primarily readable to machines, otherwise there would be no such thing as a syntax error.
John Gietzen
@John - I would disagree. Code is made for humans. Compiled code on the other hand is for machines. There is a reason for why we code in C# and not IL or machine code.
Peter Lillevold
@John Gietzen: Actually, code should be *readable* by humans and *interpetable* by machines. Compilers, etc. don't care about the formatting of code (at least for most languages) but humans certainly do.
Scott Dorman
@John: "Programs must be written for people to read, and only incidentally for machines to execute." - Abelson and Sussman
Genericrich
This discussion reminds me of the phrase "Live each day as if it were your last", and how Homer Simpson responded by sitting on the ground crying "Oh God, I don't want to die!! I'm too young! Why me?"
Daniel Earwicker
+12  A: 

In C# 3 there's already the mirror image for local variables, implicitly typing:

var listOfInts = new List<int>();

This doesn't work for non-local variables though.

In Java, type inference takes into the assignment target into account, so using static imports and cunning libraries such as the Google Java Collections you can write code such as:

List<Integer> integers = newArrayList();

Note that that keeps the variable interface-based while specifying the implementation in the construction side, which is nice.

Jon Skeet
Doesn't var have scope limitations?
rick schott
What do you mean? It's only for local variables - will edit to make that clearer.
Jon Skeet
+2  A: 

C# has:

var listOfInts = new List<int>();

which achieves kind of the same thing.

Douglas Leeder
+2  A: 

In C#, there's

var listOfInts = new List<int>();
Rik
A: 

in C#, theres already something like this namely:

var listOfInts = new List<int>();
mkoryak
+2  A: 

C# 3.0 has a mechanism to reduce the duplication in typing, but it is done by being vague about the type you're declaring, but explicit in the type you are constructing:

e.g.

var listOfInts = new List<int>();
Ray Hayes
+1  A: 

I agree that would be a nice feature. A better example would be where even more typing is required:

Dictionary<string, int> myDictionary = new Dictionary<string, int>();

Life would be easier, albeit only slightly, if that could be instantiated as:

Dictionary<string, int> myDictionary = new();

and:

Dictionary<string, int> myDictionary = { {"a",1}, {"b",2} };
sipwiz
And C# collection initializers help with the last one as well...
Jon Skeet
Yeah but I still have to type "new Dictionary...." and we're talking about optimising laziness here :).
sipwiz
True, but I am really talking about saving time and keystrokes for something I already know about my object.
rick schott
+3  A: 

In general when using object oriented approaches, you will often create more instances of a more specific type than your variable. Also, it is often a good idea to use a less specific type or an interface. In those cases, this would not make sense.

Think of interfaces:

IList<int> = new(); // What instance should the compiler infer?

Also, from a technical point of view, the signature of an operation does not include its return type, so that this kind of assignment would be completely different from the normal case.

Lucero
+4  A: 

In the new Java 7 proposals there's a type inference proposal, which will life easier re. generics declarations.

e.g.

Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

vs

Map<String, List<String>> anagrams = new HashMap<>();

See here for more information.

Brian Agnew
There also was a `final anagrams = new HashMap<String, List<String>>();' proposal somewhere in the closures discussion.
Pete Kirkham
What I like of this proposal is that you can still keep the interface type and implementation type separate while not having to repeat the generic type information.
Joachim Sauer
A: 

In Java this doesn't make too much sense, as you will usually declare variables with the interface type:

List<String> myList = new ArrayList<String>();

It would, however, in most cases make sense to be able to omit the declaration of the generic type without compiler warnings, such as:

List<String> myList = new ArrayList();

But as Java is always very explicit and verbose about everything, this might as well stay the same.

(And why again would anyone code C# or Java without an IDE?)

EDIT:

Oh, there's a proposal for that! Sweet. Thanks, Brian.

Henning
+12  A: 

What edge cases could I be missing?

I briefly discussed this possible C# syntax on my blog in January. See the comments to that post for some reader feedback on the pros and cons of the syntax.

Would there be other ways to shorten instantiation (without using VB6-esque var) and still retain meaning?

Possibly, yes.

"var" in C#, however, is nothing like "variant" in VB6. "var" does not mean the same thing as "object", nor does it introduce dynamic typing or duck typing. It is simply a syntactic sugar for eliminating the redundant stating of the type of the right hand side.

Eric Lippert
A: 

Java has

 List<String> data = newList(); //Java, where newList() is a helper method to create an ArrayList();
 List<String> data = newList("Hello", "World"); // a helper method which takes a T....
 Map<String, List<String>> anagrams = newMap(); // Java, where newMap creates a new  HashMap();
Peter Lawrey