Skip to main content
Site Icon Mysterious Pixel

'var', ELDoc and Omnisharp

Originally published here.


A couple of weeks ago in the office we were having a conversation about the pros and cons of using 'var' in C#. If you're not aware of it, 'var' is the C# equivalent of 'auto' in C++11; it tells the compiler work out the type of a variable declaration for you, based on the type of its initialising value. So for example:

List<GameObject> someList = new List<GameObject>();

can be replaced with:

var someList = new List<GameObject>();

The compiler can automatically work out that someList should be a list of GameObjects based on the initial assignment. Moreover because it does so at compile-time, there's no runtime overhead, unlike with 'real' dynamic typing. Over time this can save a fair amount of typing, and reduces silly typo-based compiler errors.

It's also a useful tool when refactoring. Consider the following:

foreach(SomeType loopVar in ImportantList) {...}

This can be replaced with with:

foreach(var loopVar in ImportantList) {...}

Now, if you change the type of ImportantList, the loop will 'just work' (as long as the loop body still contains valid code, obviously).

The concern in our office was regarding code readability. The more you use 'var', the harder it can be to work out what's going on. For example:

var inventory = GetInventory(); 
var slot = inventory.GetSlot(); 
foreach(var item in slot.GetItems()) { ... }

If you're new to this code it's hard to know what slot or item is without jumping to another file. Although I'm personally happy with the tradeoff, the concern is a valid one and I wanted to try and develop a tool to address the issues.

Thankfully a dash of Emacs, a bit of ELDoc and a giant pinch of OmniSharp provided a pretty comprehensive solution. ELDoc shows information about the symbol at point in the echo area. It didn't take long to get OmniSharp and ELDoc working together, and the result is very handy even if you don't use var.

Some examples:

example1

Here we can clearly see the type that has been assigned to myTween in the echo area, even though we've declared it with var.

example2

And here we can see the complete function signature and return type of Go.to, which makes understanding the code around the call easier, especially in the presence of heavily overloaded methods.

And that's it! ELDoc support is in my OmniSharp fork on github, and it will hopefully get pulled across to main soon. I hope someone finds it useful.