The Variform Var

A C# riddle. Solved with the help of contextual keywords and implicit conversion operators.

Various Forms

Var can indeed appear in various forms. It is enough to take a look at the example below and see no more and no less then three completely different forms of var sharing the same line of code:

var var = "var";

Var as a keyword, var as a variable of type string, var as a string literal. Variform as only var could be. Or we could still go further? Perhaps insisting that the variable var should be, why not, of type var instead of string ;-)

That var can vary, that we already know. But that it can vary so much that the above variable var becomes an instance of var, that’s a bit harder to imagine. Yet, that’s exactly what this subtle hint in Visual Studio is telling us:

Var var var

The variable var is of type var. Which brings us to our riddle.

The Riddle

Unlike some other riddles on The Humble Programmer whose formulation spanned over several sentences and examples, this one can be easily formulated in a single sentence. Write a C# program that contains the above line of code such that the var variable is of type var, whatever the type var is. As simple as that :-)

As with all the riddles on The Humble Programmer, try to solve it on your own. Don’t rush, give it a try. Think of it. And most of all - don’t give up too early :-)

Before you start, here is a tip that might help you. Combine the ideas from my blog post on contextual keywords and the blog post on the overall context in which contextual keywords appear. By doing so you will already be on the half way to the complete solution ;-)

Wait!

Don’t just read the text through.

Take your time and try to figure out the solution on your own.

It’s not that difficult as it might appear at first ;-)

The Solution

So, let us follow the tip and combine the two ideas that can be found in the previous two blog posts. The first post explains that:

var var = ...

is a perfectly valid declaration of a variable of the name var. Hmm, now I see that we actually already assumed that from the beginning. Sorry for giving you a not so useful tip.

But the second post gives us indeed a useful clue. If there is a type called var somewhere in the program, the compiler will give precedence to that type over the keyword var. So let us declare a class called var and see what happens:

class var { }

class TheVariformVar
{
  public void Method()
  {
    var var = "var";
  }
}

This brings us one step further. The variable var is now of type var! but the code does not compile:

Cannot implicitly convert type 'string' to 'var'

The error message is pretty obvious - “Cannot implicitly convert type ‘string’ to ‘var’”. Here is where the C# implicit conversion operators come to our rescue. If we define an implicit conversion that “teaches” the compiler how to convert string to our newly invented type var, the compiler will apply the conversion and thus, the code will compile. So much for the theory.

Let’s try it out. After adding the implicit conversion operator (a pretty meaningless one, but compilers usually do not insist on a deeper meaning in order to happily accept the code):

class var
{
  public static implicit operator var(string text)
  {
    return null;
  }
}

class TheVariformVar
{
  public void Method()
  {
    var var = "var";
  }
}

the code indeed compiles. Riddle solved :-)

A Dynamic Homework

The purpose of this riddle was to increase our knowledge of contextual keywords and implicit conversion operators. The best way to fortify a freshly gained knowledge is to do a bit of a homework on our own.

So here is an easy homework for you, my eager learners. Extend the below example so that it compiles and that the variable dynamic is of type dynamic as shown on the screenshot:

Dynamic dynamic dynamic

Confusion and Awesomeness

“The homework is trivial” I can hear you saying. “Just take the previous piece of code, replace all occurrences of var with dynamic and that’s it.” Yes, I agree. The solutions are identical and rely on the same C# language features. Still, those of you who did the homework and at the same time have a ReSharper running, probably noticed that the second example confuses ReSharper.

By confuses I mean the following:

Either parameter or return type must be dynamic

ReSharper marks a perfectly valid C# code as invalid proving once again that writing a bullet-proof C# parser/analyzer is an extremely difficult endeavor. I blogged about that in a very detail in the last chapter of my blog post “Await Async as Async”.

Although there is no need to repeat myself here and now, there is one thing I can’t repeat often enough - Roslyn is awesome :-)

The source code used in this blog post is available on GitHub. Download it here.

Wow, you've made it this far :-) The chances are you might like my next blog post as well ;-) Should I let you know when it's out?

Published on March 28, 2018