To var or not to var? -

To var or not to var?

Recently, I had quite an interesting discussion about var keyword in C#. Basically, my interlocutor tried to convince me that using var we drastically reduce code readability, so we should only use that together with anonymous types. He also mentioned performance and that some operations cannot be done using implicit typing.
Well, if you’ve been reading my blog for some time, you’ve probably spotted that I’m a big fan of vars, and I put them every time it’s possible. Below is my justification.


Implicit/Explicit typing makes no difference in C#

First and the foremost, using var instead of explicit type declaration makes no difference in C# at all. It’s not a JavaScript world, where we need to pay attention to the scopes and choose carefully between var, let or explicit type.
C#’s var is statically typed which means that the actual type is determined by the right-side expression during the compilation, not in the runtime. This also means that once we assign something to the var we cannot change its type later in the code:

var number = 2;
number = string.Empty; // not allowed

So, just like with the explicit type declaration, right? I guess, that the confusion might be caused by mistaken treatment both var and dynamic as the same “beings” (which is wrong btw), but that’s just my theory. So, if you’re not sure whether switching to vars will affect your performance, code behavior or something else, the shortest answer is “NO”.


Code readability

To me, there’s no point of saying that vars decrease code readability since it’s very subjective. Personally, I don’t use them just to be a “cool guy”, but it’s because it makes my code way easier to read. And there’s one more thing. Since I don’t use explicit typing, I need to pay more attention to better names for variables, so other developers could understand it as well.
In my opinion, one of the factors affecting the poor readability of the code is indeed bad naming things. It’s very easy to create this kind of code even with explicit type declaration:

int number = NumberManager.Generate();

As you see, the above example is not very extreme (one-letter names) but it’s still hard to determine what it does. What kind of number is returned by Generate method? Is it a sequence number, random number or something else? All names are too general and don’t give you enough information, so you’re forced to click F12 on the method. But once again, keep in mind that the same mess can be easily achieved with vars.

And there’s one more thing when it comes to the code readability. Using vars you cannot be 100% sure what is the actual type if you don’t have an IntelliSense. Fine, that’s true. In this case, reading a code without any explanation could be harder. I cannot deny it.


When do we need to use explicit types?

In the first paragraph, I wrote that we can introduce var in our code with no fear. But here comes the question. Are there situations in which we cannot use them? YES! I came up with four (actually three) examples.


out parameters

Until C # 7, using out parameter required an explicit type declaration before calling the method:

int number;
int.TryParse("2", out number);

The reason is that var needs to be initialized at the time of its declaration, so the following syntax is not allowed:

var number;

But here comes a good news! Since C# 7 we can use the following syntax:

int.TryParse("2", out var number);


Complex if statements

For the same reason, we are forced to get rid of var when it comes to complex if statements:

int result;

if(treshold >= 80)
    result = 10;
else if (treshold >= 60)
    result = 5;
    result = 0;


Lambda expressions

The next example is a little bit more tricky. As mentioned in the first paragraph the actual type of var is determined by the right-side expression. The problems arise when we want to assign a lambda expression:

var func = () => 2;

The first issue is somewhat explained in MSDN:

A lambda expression is an anonymous function that you can use to create delegates or expression tree types.

So in the above case, the compiler couldn’t decide what the actual type should be. Func<int> or Expression<Func<int>>? The only way to do that is to use explicit type declaration:

Func<int> func = () => 2;
Expression<Func<int>> expression = () => 2;

But there’s also one more thing. The lambda expression itself doesn’t have a type. It’s determined by the context (that’s why you can’t create extension methods for them). This basically means that one lambda expression can be used to create several different delegates or expressions. Consider the following code:

var func = () => null;

What’s the result? What type should be put instead of var keyword? It’s impossible to guess since the above lambda expression is assignable to an infinite number of delegates/expression:

Func<string> func1 = () => null;
Func<int?> func2 = () => null;
Func<long?> func3 = () => null;
Func<Guid?> func4 = () => null;
Func<object> func5 = () => null;
Func<MyClass> func6 = () => null;

So, once again when it comes to lambda expression we need explicit type declaration just to pass a clear message to the compiler, what type we expect.



The last example is also related to the fact that the actual type of var keyword is determined by right-sight expression. So, consider the following code:

class A {}
class B : A {}

var a = new B();

In the following example, the type of var is B which makes a perfect sense. But there’s no way to make the a varaible of type A (without explicit casting). This can be achieved easily using explicit type declaration:

A a = new B();


Inspecting ASP.NET GitHub

I was curious which standard was adopted by Microsoft because honestly, I’ve never paid so much attention to that. I inspected three random repositories and chose random classes.

Here’s the code from EF Core:

        public virtual EntityEntry Remove([NotNull] object entity)
            Check.NotNull(entity, nameof(entity));

            var entry = EntryWithoutDetectChanges(entity);

            var initialState = entry.State;
            if (initialState == EntityState.Detached)
                SetEntityState(entry.GetInfrastructure(), EntityState.Unchanged);

            // An Added entity does not yet exist in the database. If it is then marked as deleted there is
            // nothing to delete because it was not yet inserted, so just make sure it doesn't get inserted.
            entry.State =
                initialState == EntityState.Added
                    ? EntityState.Detached
                    : EntityState.Deleted;

            return entry;



        public void MapHub<THub>(string path, Action<HttpSocketOptions> socketOptions) where THub : Hub
            // find auth attributes
            var authorizeAttributes = typeof(THub).GetCustomAttributes<AuthorizeAttribute>(inherit: true);
            var options = new HttpSocketOptions();
            foreach (var attribute in authorizeAttributes)

            _routes.MapSocket(path, options, builder =>


And Kestrel:

        private async Task<Stream> ApplyConnectionAdaptersAsync()
            var connectionAdapters = _context.ConnectionAdapters;
            var stream = new RawStream(_context.Transport.Input, _context.Transport.Output);
            var adapterContext = new ConnectionAdapterContext(_context.ConnectionFeatures, stream);
            _adaptedConnections = new List<IAdaptedConnection>(connectionAdapters.Count);

                for (var i = 0; i < connectionAdapters.Count; i++)
                    var adaptedConnection = await connectionAdapters[i].OnConnectionAsync(adapterContext);
                    adapterContext = new ConnectionAdapterContext(_context.ConnectionFeatures, adaptedConnection.ConnectionStream);
            catch (Exception ex)
                Log.LogError(0, ex, $"Uncaught exception from the {nameof(IConnectionAdapter.OnConnectionAsync)} method of an {nameof(IConnectionAdapter)}.");

                return null;

            return adapterContext.ConnectionStream;


What are your thoughts on this topic? Which approach is better and why? Please share your opinions down in the comments.

You may also like...