Related
I would like to ask a theoretical question. If I have, for example, the following C# code in Page_load:
cars = new carsModel.carsEntities();
var mftQuery = from mft in cars.Manufacturers
where mft.StockHeaders.Any(sh=> sh.StockCount>0)
orderby mft.CompanyName
select new {mft.CompanyID, mft.CompanyName};
// ...
Questions:
This code uses the var keyword. What is the benefit of this construct?
What is the key difference between the implementation of var in Javascript and C#?
JavaScript is a dynamically typed language, while c# is (usually) a statically typed language. As a result, comparisons like this will always be problematic. But:
JavaScript's var keyword is somewhat similar to C#'s dynamic keyword. Both create a variable whose type will not be known until runtime, and whose misuse will not be discovered until runtime. This is the way JavaScript always is, but this behavior is brand new to C# 4.
dynamic foo = new DateTime();
foo.bar(); //compiles fine but blows up at runtime.
JavaScript has nothing to match C#'s var, since JavaScript is a dynamically typed language, and C#'s var, despite popular misconception, creates a variable whose type is known at compile time. C#'s var serves two purposes: to declare variables whose type is a pain to write out, and to create variables that are of an anonymous type, and therefore have no type that can be written out by the developer.
For an example of the first:
var conn = new System.Data.SqlClient.SqlConnection("....");
Anonymous type projections from Linq-to-Sql or Entity Framework are a good example of the second:
var results = context.People.Where(p => p.Name == "Adam")
.Select(p => new { p.Name, p.Address });
Here results is of type IQueryable<SomeTypeTheCompilerCreatedOnTheFly>. No matter how much you might like to write out the actual type of results, instead of just writing var, there's no way to since you have no knowledge of the type that the compiler is creating under the covers for your anonymous type—hence the terminology: this type is anonymous
In both cases the type is known at compile time, and in both cases, subsequently saying either
conn = new DateTime();
or
results = new DateTime();
would result in a compiler error, since you're setting conn and results to a type that's not compatible with what they were declared as.
a) C#'s var lets you avoid writing an explicit type upon variable declaration. This makes your code more compact, also sometimes the type of the expression on the right side of the declaration is complicated and in the same time you are not interested what the actual type is.
b) Javascript's var is like C#'s dynamic. It lets you declare a variable but you can change its type.
var i = 1;
i = "foo"; // legal in Javascript, illegal in C#
The only thing they have in common is that they are used to declare local variables.
The C# equivalent of JS var is dynamic. But since most C# users prefer static typing it is usually only used in interop scenarios of some kind(with COM or a dynamically typed language).
C# var still uses static typing, but with an inferred type. Since JS only supports dynamic typing, there is no equivalent.
In this context explicit static typing isn't possible, since new {mft.CompanyID, mft.CompanyName} creates an anonymous type, so implicit static typing with var is used.
var in C# is dynamic at design time but staticly typed at compile time. You will see that if you do:
var mftQuery = from mft in cars.Manufacturers
where mft.StockHeaders.Any(sh=> sh.StockCount>0)
orderby mft.CompanyName
select new {mft.CompanyID, mft.CompanyName};
and then:
mftQuery = "Hello world!";
It will not compile and complain about missmatching types even though you didn't specify any type.
This is a useful productivity enhancement because you can easily change return types to similar types without breaking anything and it is easier to write. A stupid example:
foreach(var animal in GetCats()){
Console.WriteLine(animal.Owner);
}
could be changed to:
foreach(var animal in GetDogs()){
Console.WriteLine(animal.Owner);
}
And to answer your question 1, the benefit of using var keyword in the presented code is at may be difficult to come up with the resulting type for the LINQ query and can be easily affected by the change to the query. In fact, its introduction to C# coincide with the premiere of LINQ.
Reassuming, it is to make the life of programmer easier and also to remove the redundancy of Type t = new Type().
One of the common programming best practices is "define variables as close to where they are used as possible".
I use structs frequently to create code thats almost self documenting in places. However, C# forces me to define the struct outside the method. This breaks the aforementioned best practice - its basically creating an unwanted global variable type for the entire class.
Is it possible to define a local struct inside a method, just like a local variable, and if not, could you give me a window into the reasons the C# designers decided to prevent this?
Use Case
I'm converting part of a spreadsheet into C# code. I'd like to use local structs within the method to store temporary information in an organized manner, without having to resort to hundreds of separate variables that are global in scope.
Update 2016-August: C# 7.0 may have this feature!
As of 2016-Aug, apparently, this will be a feature in C# 7.0.
So the C# compiler team agreed - wow!
Update 2020-July: Now supported by C# and C++
C++ has always fully supported this. And it's fantastic.
C# 7.0 now has value tuples for a lightweight data structure with named fields. See answer from Ghost4Man.
I believe it's not permitted to define named types within a method. As to why, I'll have to speculate. If a type is not going to be used outside, then its existence probably cannot be justified.
You can however define anonymous type variables within a method. It will somewhat resembles structures. A compromise.
public void SomeMethod ()
{
var anonymousTypeVar = new { x = 5, y = 10 };
}
It is a little late but this is my solution for lists - using anonymous vars as the structs inside of methods:
var list = new[] { new { sn = "a1", sd = "b1" } }.ToList(); // declaring structure
list.Clear(); // clearing dummy element
list.Add(new { sn="a", sd="b"}); // adding real element
foreach (var leaf in list) if (leaf.sn == "a") break; // using it
Anonymous elements (sn and sd) are somehow read only.
Since C# 7.0, you can use value tuples if you want a lightweight data structure with named fields. They can be used not only locally inside methods, but also in parameters, returns, properties, fields, etc. You can use local functions to somewhat emulate struct methods.
var book = (id: 65, pageCount: 535); // Initialization A
(int id, int pageCount) book2 = (44, 100); // Initialization B
Console.WriteLine($"Book {book.id} has {book.pageCount} pages.");
(int id, int pageCount) = book; // Deconstruction into variables
Console.WriteLine($"Book {id} has {pageCount} pages.");
Here book is of type System.ValueTuple<int, int> (a generic struct).
You could do something like this using anonymous types. MSDN examples below:
var v = new { Amount = 108, Message = "Hello" };
or
var productQuery =
from prod in products
select new { prod.Color, prod.Price };
foreach (var v in productQuery)
{
Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
Nowadays, you could also use a named tuple: https://learn.microsoft.com/en-us/dotnet/csharp/tuples
No, this is not possible. If you are using .net 4.0, you could use Tuple<T1, ..., Tn> to replicate such a thing.
I don't see the reason why you would need such a struct - just use variables with speaking names and this shouldn't be any problem at all. In combination with explicit declaration using the class names there is very little space for ambiguity.
You can define an anonymous type within your method and use it. The anonymous type will be readonly, so it gets you the immutability that is desired of structs. It will not explicitly be a struct, but it will be fully defined and contained within your method.
var myLocalType = new
{
SomeValue = "Foo",
SomeId = 14
};
it's not a struct, but mayme a var can help you out here?
var person = new {Name= "John", City = "London"};
it's strong typed so it will be compile time checked
You can create a dynamic type in c# 4.0 to accomplish this task, but its not exactly what you are looking for.
However I believe that the maximum of defining variables as close to where they are used is meant to mean where a variable is introduced into program flow not where the type is declared. I believe that most types have some ability to be reused creating in method types limits you ability to create reusable blocks of code that operates on common data.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Use of var keyword in C#
I don't really understand why you would the var keyword in C#
This code:
var s = "my string";
is the same as:
string s = "my string";
Why would you want to let the compiler determine the best type to use. Surely you should know what type to use. After all you are writing the code?
Isn't it clearer/cleaner to write the second piece code?
See Use of var keyword in C#
Its very, very subjective!
Personally, I use "var" when I think its obvious what the type is, and I want to remove "noise" from the source code.
It doesn't make much sense to me to use it there either. For some I can see more of a point just to save typing:
var cache = new Dictionary<int, Page>();
But even then I'd be tempted not to, as intellisense saves most of the typing anyway. For Linq, though, I pretty much always use it - you can determine the type, but this might change if you change the statement so it's a bit of a hassle.
StringBuilder output = new StringBuilder();
becomes
var output = new StringBuilder();
Or anonymous types, ala LINQ:
List<MyClass> items = GetItems();
var itemsILike = items.Select(i => new { Cheeky = i.Monkey, Bum = i.Looker });
I used to use it more often, but now I try to avoid it for stuff like:
var items = GetItems();
For this example, though, it can still be useful if you're trying to work against code from another solution that you know is going to be refactored, but you still have to write code against.
You use it because var is shorter than string and if you have an expression (especially a generic one) where the type is lengthy and unnecessary to type. The reality is that there's virtually no downside to using var as VS will pop up the type on mouseover of a variable name.
To save typing and remove unnecessary codes, but use it only when it is obvious what type you are declaring
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What’s the point of the var keyword?
What is the var type and should it be used in c#? When should it be used?
Can you specify the var type for the parameters to a method?
var is not a type. It is a convinient short hand notation that saves you a lot of typing. The following two declarations are equivalent:
Dictionary<string,List<int>> dic = new Dictionary<string,List<int>>();
and
var dic = new Dictionary<string,List<int>>();
As you can see, this saves typing and are easier to read. And if you descide to change the data type, you only have to change the right hand part.
But where I really like it most is in foreach loops:
foreach ( var item in someList )
Here item automatically takes the correct type, depending on the type of someList and it enables you to change the type of someList without haveing to change the declaration of item.
In short: var is GREAT and should be used.
EDIT: No, you can not specify var as a parameter to a function. The closest you can get to that is generics, I guess. And I also completely forgot to mention anonymous types. With those you have to use var.
It is part of the language, so yes, it should be used. It is not a type, however, but signifies a placeholder for the actual type determined by the compiler.
When should you use it? This has been asked before, many times:
Use of var keyword in C#
https://stackoverflow.com/questions/633474/c-do-you-use-var
var is not a type, it's an instruction to the compiler to let it figure out the correct type to use.
This means there is no difference at all to the output of the following two lines:
var s = "Test";
string s = "Test";
As for when to use it, you'll have to come up with your own rules. There is very few things you can do with var that you cannot do with a specific type name, but there is one thing: anonymous types.
You can do:
var x = new { A = 10 };
but you cannot come up with a strong type for that, since it has no type known at compile-time, instead the compiler will create the type during compilation, and then var will use that type.
That's what var was created to support, that it can also be used without anonymous types is a bonus, but you'll have to make up your own rules for when to use it in those cases.
Personally I only use it when the type is easily read from the source code, so I would use it for:
var dict = new Dictionary<int, string>();
var stream = new FileStream(...);
but not for:
var dict = GetDataStructure();
var stream = OpenFileForReading();
We tend to use it when interacting with all of our home grown libraries.
This is because we often change things as we are developing the libraries and quite often changing the type name or return type won't actually break the things which are using it.
We also tend to use it most of the time with the .NET framework as well.
However, we have put in an outright ban on using it with native types like int, string, bool etc. because it is not always clear what type the variable is in those cases.
Well, as mentioned earlier var is a short notation for a type name of any variable. As for me, I find, that var is overused by many developers and I think var makes code less readable sometimes. But one case where u should use it definitely is anonimous type variables.
Just to add to the other commentary, I suggest using var only when you can infer the type just by reading the code
var x = new Widget(); //ok
var y = Customer.Create(); // ok
var z = DoSomething(); //not ok
Some of the answers introduce Anonymous Types.
The var keyword on MSDN.
Know that var is not a type but a placeholder and can only be used within methods or properties (local variable definition). You can't use it in local member definition (private members of a class), neither can you when defining a method that should return whatever type, as generics, where you can use whatever name, except var (or any other reserved keyword) like so:
public IList<var> GetItems() { // Here the compiler will complain about the context of using `var` keyword within a local variable definition only.
}
public IList<T> GetItems() { // Here, we're talking about generics.
}
So, here are the principal rules to follow using the var keyword:
Local variable definition only;
Use var with anonymous types (Linq query, for instance);
Not to be confused with generic types;
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:
What are possible pitfalls of this approach. What edge cases could I be missing?
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.
C# saves in the other end:
var listOfInts = new List<int>();
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.
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.
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.
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.
Your version is less readable, sorry.
Code is meant to be read by humans, only incidentally by machines.
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} };
C# has:
var listOfInts = new List<int>();
which achieves kind of the same thing.
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>();
In C#, there's
var listOfInts = new List<int>();
in C#, theres already something like this namely:
var listOfInts = new List<int>();
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.
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();
Code is read from left to right (if your language is not right to left).
That means that
var someTypeWithALongName = new TypeWithALongName<TypeParamOne,TypeParamTwo>();
puts important data to the right part (actual method / type constructor that is used to init variable, from which a reader of the code can infer knowledge about actual var type), which is less convenient to eye, compared to when it is located in the left.
What author suggests however is much better for a left to right reading human - we declare a variable of known type (not some unknown var type)
TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
now important data (actual type that variable will have) is to the left, we can scan code on left side and notice actual types, not a fence of var declarations
var x = ....;
var y = ....;
var z = ....;
var xy = ....;
Code Complete book states that readability is the most important, and I find it hard to disagree with that. Saving 5(or less) seconds and using var instead of real type easily makes code review in future harder, can make code unreadable depending on the right part, and can plant unexpected errors that will be very hard to notice. All with the value of.. saving 5 seconds and not writing a declaring type for variable?
It is now a common knowledge that actual code writing is not taking that much time out of whole time consumed for program creation,especially if it is a product program) ( which usually has debugging, system testing, components integration, design, meetings, etc taking MUCH more time that actual code writing)
On other hand when we type
TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
I find it hard not to interpret that line as anything but calling a default constructor for type and creating an instance of the type.
Also in case of wall of initializations we get actual type names on the beginning of the line, so its easy to scan code from top to bottom and we don't have to move eyes to the end of string to know what actually this concrete var initialization does.( And if you think scanning line to end is a free roll task , first of all its not, and with var its not just scanning, its also checking whether there is a bug in the right part of initialization (for example method with different return type is called or some other types of bugs which var allows))
TypeWithALongName<TypeParamOne,TypeParamTwo> someTypeWithALongName = new();
AnotherTypeWithLongNname someAnotherTypeWithLongNname = new();
List<int> idList = new();
Dictionary<int,string> lookupDict = new ();
I am against var use except for cases it was created for (anonymous types , generally coming from LINQ), and if we were to save up some space in a code I would prefer any code reducing strategies were happening on the right side.
I also believe that using var to declare a variable and assigning it to a return value of some method highly complicates code analysis and often introduces hard to catch bugs, that would have been completely avoided if var wasn't possible for such cases, so if only the constructors code could be shortened to a new() or new(ParamType param) and not some other method like
var x = someTypeLocalIstance.ComputeResults()
readability will only win once more.
I think Microsoft made it this way: a) var xy = new MyClass();
instead of this way: b) MyClass xy = new();
because a) is capable to hold anonymous classes and with b) that would not be possible.