Water Cooler v2 Water Cooler v2 - 1 year ago 39
C# Question

Can a covariant type parameter be in an input position in the constructor?

In this answer, Michael suggests that the generic type parameter be made co-variant in order to allow the creation of an empty node.

I get that the generic type parameter is in all output positions since all the properties of the

and its sub-types are read-only (

But it does have the type parameter in an input position in the constructor.

I thought that that code wouldn't work in C# so I tried it out and, to my surprise, it worked just fine.

// See this: http://stackoverflow.com/questions/36753579/algebraic-data-types-in-kotlin
// Short url: http://stackoverflow.com/a/36753782/303685
interface ITree<out T> { }

class Tree<T>: ITree<T> { }

sealed class Node<T> : Tree<T>
private readonly T _left;
private readonly T _right;

public Node(T left, T right)
_left = left;
_right = right;

public T Left { get { return _left; } }
public T Right { get { return _right; } }

class Program
static void CovarianceTest1()
ITree<object> tree = new Node<string>("Hello", "World!");

I realize now that in doing this exercise, I learnt something new about variance.

So, my first question is:

Are co-variant type parameters allowed in input positions in constructors? In what other places are type parameters allowed to disregard their variance qualifiers?

Another thing I learnt about variance is that the variant generic type parameter may not even appear in the variant interface declaration as seen in the example below.

interface ITree<out T> { }

You'll see that the
ITree<out T>
interface does not have
in either input or output positions. This also came as a shock to me.

My second question is:

And the other question I have is, what is the C# equivalent of the
type in Kotlin? The answer says that
is the most sub-type that cannot further be derived. It is the exact opposite of
(or the most base type in other languages).

To emulate that code in C#, it didn't make sense to have this:

class Empty : Tree<null> { }

Because that's just illegal C# code and
also doesn't seem analogous to

So, I had to fake a dummy like so to imitate the
class declaration.

sealed class Dummy { }

sealed class Empty : Tree<Dummy>
private static Empty _empty = null;
private static object syncLock = new object();
private Empty() { }
public Empty Instance
if (_empty == null)
lock (syncLock)
if (_empty == null)
_empty = new Empty();

return _empty;

My third and final question is:

Therefore, my final question is, is there a place that contains an exhaustive list of all the types available in Kotlin along with their descriptions? Because even though the Basic Types page lists most of the common ones, it seems not to be an exhaustive list. The types not listed there are all sprinkled over the documentation. Like in the instance above, they just appear with a mention on a page here or there.

Answer Source

All types that are shipped with Kotlin are described in its API reference, in particular the kotlin package: