c#


Is there any technical reason to use or not to use var in C# when the type is known?


It seems that more and more C# code I read uses the var type identifier:
foreach (var itemChange in ItemChanges)
{
//...
}
instead of explicitly stating the type:
foreach (ItemChange itemChange in ItemChanges)
{
//...
}
even when the type is known.
I am still using the latter explicit version just because I think someone reading it later will more quickly understand which type a variable is than if you use var.
But is there any technical reason to use one or the other?
There is no technical reason. If the type cannot be inferred at compile time then the code will not compile.
You are right in stating there are instances where it may be better to use an explicit type for readabilty, e.g.
var obj = SomeMethod(); // what's the type? you'd have to inspect SomeMethod()
SomeClass obj = SomeMethod(); // the type is obvious
but other instances where using var makes perfect sense, e.g.
var obj = new SomeClass(); // the type is obvious
SomeClass obj = new SomeClass(); // the duplication of type is unnecessary
No, just readability.
In general no technical reason. Readability - in either direction - is the only real factor.
However, one small caveat is that var will infer the static type of the variable. If you want a sub or super class type you'll need to do the casting yourself. In the case of a foreach, as in your example, you can usually get downcasting performed for you "for free" just by declaring your loop variable with the subclass type.
The classic example is iterating over an XML NodeList that you know is a list of XmlElement, but Nodelist is typed as a collection of XmlNodes. Of course you can use a cast or an as to get back the type you want, but that would seem to defeat the purpose of using type inference :-)
Of course, the compiler will let you know about this as soon as you try to use a member of the node that is only available to XmlElement - so it's still not strictly a technical difference.
Another thing that is a little annoying is that if you use a tool like Resharper, it's very aggressive about suggesting you use var in every possible situation. It's particularly annoying when it recommends you change, for example, an int declaration into a var!
However, unless you turn that feature off, you'll get less "noise" from Resharper the more you use var.
The only technical reason I know of is that you can perform implicit casts without var, e.g.
int i = 5;
double a = i; // implicit cast with explicit types
but here I much prefer var as it makes the cast explicit; while I don't care so much about the types I do care when I'm performing a representation changing type conversion:
var a = (double)i; // explicit cast with implicit types
But really the general reason is readability, as you said. The question you need to ask yourself is why you think the exact concrete type is important for readability? Do you always write Linq queries calling out the concrete type, e.g.
from ItemChange itemChange in ItemChanges
// instead of
from itemChange in ItemChanges
Similarly, do you always call out the type arguments to generic methods instead of using type inference, e.g.
ItemChanges.Select<ItemChange, ItemChange>((ItemChange itemChange) => ...);
// instead of
ItemChanges.Select(itemChange => ...);
Or are you happy to let the compiler do some work for you and let it work out the types, at the 'expense' of not having the type information explicitly stated?
If you're happy with type inference in linq and generic methods, then you've already made the decision that you're OK with not having types explicitly spelled out everywhere, and you probably haven't found your code to be any less readable as a result (in fact, you've probably found quite the opposite). So using var is just another step down the same path that you're already on.
var is a C# 3.0 feature only mandatory in anonymous type
Because following code
var v = new { Amount = 108, Message = "Hello" };
dynamically create a new anonymous type, var usage is mandatory. For example, var is particularly useful in Linq where type are often created dynamically.
In any other situations, it's only a matter of taste for final application (it's resolved during compilation). But for code readers, I think 'var' is less informative that type itself.
No. Use var where it improves readability and vice versa.
var is a C# 3.x+ feature, isn't it? without using that, your code is more compatible with other versions too.
And there is lots of interesting questions in SO, when you search "var C#"
There is no technical reason to use var, other than anonymous types, in any given state of the program.
However, using var allows the program to change without you needing to edit it. Given
public int SomeMethod(){}
public List<T> SomeOtherMethod<T>(T parameter);
then
var x = SomeMethod();
var y = SomeOtherMethod(x);
Will work (and y will be List<int>). If you had used
int x = SomeMethod();
List<int> y = SomeOtherMethod(x);
then if SomeMethod() were changed to return long, then you'd have to change the definition of y.
I've seen this kind of thing propagate throughout a program, requiring hundreds of changes. The particular case was changing data access code to return ReadOnlyCollection<T> rather than List<T>. There were so many code changes required, that I changed all explicit mentions of List<T> to var, and the code will never need to change again.
Yes, they are different. var removes the original datatype and one datatype-check, so its more dangerous.
Type-checks
A normal variable definition includes a datatype-check on the initial assignment.
T a = init; // type-checked
a = b; // type-checked
a = c; // type-checked
This is missing when you use var
var a = init; // NOT type-checked
a = b; // type-checked
a = c; // type-checked
These compile-time tests are the glue which holds large programs together. Removing them is foolish.
Accidental changes
A normal variable definition has a fixed type - it cannot be changed accidentally.
TOrig a = init(e); // datatype fixed (as intended)
When you remove the initial datatype, you are allowing the variable's type to be changed accidentally. Any change to the initial expression can change the variable's datatype.
var a = init(e); // datatype changes with init and e
Over time, as the software is edited, the datatype could be accidentally changed. It could already have happened, and you cannot tell.
Example:
public double MaxValue = 1.2;
... meanwhile, in another source file ...
var x = MaxValue - 1;
var y = IsFull(x);
Both x and y's datatypes can be accidentally changing by editing MaxValue. Q. Has this already happened?
Summary
Using var turns the local variable's datatype into a unchecked moving part.
The more moving parts a machine has, the more likely it is to break.
Explicit datatypes prevent bugs.

Related Links

DataGridView Different cell formatting in same column possible?
Animate circle's fill using sine-wave
Overriding methods from Library Project
Reading CSV file in SSIS Script Component task
GroupBy equivalent for Windows Phone
How to save video into database using c#?
Sync Framework - file sync across domains
Selenium WebDriver C# and Omnibug
How to access a Dictionary values within a list by a class object?
System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'file'
SQL Server High Frequency Inserts
Register user only for my country
Best practice for caching values in large project
Can't override a method of a controls
How can i send message to different ip's through microsoft message queue
c# two nested if statements, one else

Categories

HOME
autohotkey
algolia
marie
teradata
packet
popover
latex
liquibase
nagios
spotfire
salesforce-lightning
bitbucket
ebay
css-selectors
genexus
rtc
pyodbc
mongoimport
mamp
suitecrm
drush
infopath
django-rest-auth
hl7-fhir
android-wifi
cherrypy
mattermost
ps
symlink
smart-device
hierarchical-data
typeorm
emr
kundera
ds-5
imdb
scene7
oracle-nosql
webclient
fastadapter
apache-falcon
asp.net-webhooks
dom4j
pymunk
hippocms
device-driver
dotnetnuke-module
gem-fury
compiler-warnings
irr
rexx
grails-2.0
hierarchical-clustering
g77
ng-class
cloudconvert
htop
try-catch-finally
dynatable
bipartite
robotc
fileopendialog
distcc
git-cherry-pick
gdi
angularfire
laterjs
pyshark
jmap
wordpress-plugin
datamodel
matlab-engine
app-data
maven-antrun-plugin
log4cxx
callfire
log-analysis
stderr
skview
qxorm
register-allocation
xpand
winrun4j
image-preloader
slimscroll
nomachine
nokogiri
latex-suite
phone-state-listener
invalidoperationexception
filedialog
sup
github-archive
django-1.4
utm
wdm
jqtransform
hs-err
excellibrary
jquery-attributes
xslt-grouping
appointment
user-preferences

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App