7

In this article, it is written that in C# 8.0 new feature of convariant return type will be included as the community asking for this feature for quite a long time.

Can anybody explain why and when this feature is required with practical example ?

8

Firstly, it is worth noting that the article is very likely wrong. There is currently a long list of features officially earmarked for C# 8.0, but covariant return types is not one of them. That feature is scheduled for X.0, ie it needs to appear in a major release, so might appear for 8.0 (but that's incredibly unlikely), more likely will be in 9.0 or 10.0 etc.

As for what use is the feature, have a read of the original Roslyn issue from three years ago. It has numerous uses around being able to narrow the return type within methods in derived types, eg an implementation of a factory interface could specify that it returns a concrete type, rather than an interface.

For example, using generics, we can do something like:

public interface IFactory<T>
{
    T Create();
}

public class Foo{}

public class FooFactory : IFactory<Foo>
{
    public Foo Create() => null;
}

But if IFactory instead uses further interfaces for its abstractions, rather than generics, similar code isn't currently possible:

public interface IFoo {}

public interface IFactory
{
    IFoo Create();
}

public class Foo : IFoo {}

public class FooFactory : IFactory
{
    public Foo Create() => null; // Compiler complains at Foo; wants IFoo
}

Such code would become legal with covariant return types.

3

Covariant return types means that an method override can specify a more specific return type than the base method. Eg.

class WebRequest {
    virtual WebRequest Create() { ... }
}

class HttpWebRequest : WebRequest {
    override HttpWebRequest Create() { ... }
}

Currently (without covariant return types) the overriden method have to specify the exact same return type, WebRequest, and you will have to manually cast the return value to HttpWebRequest, which is ugly.

  • As a workaround... wouldn't this already work if both classes implemented an interface with an out T generic argument? gist – t3chb0t Apr 5 '18 at 10:44
3

(Apologies beforehand, by C# is a bit rusty)

As mentioned in the other answers the big feature of convariant return types is that you can override virtual functions with functions that return a more specific return type.

For example:

public class Foo
{
    virtual public Foo getCopy(); { //Create a copy of this Foo and return it }
}

The getCopy() method returns a copy of the Foo it is invoked on, so far, so good. Let's add a class that inherits from Foo.

public class Bar : Foo
{
    override public Foo getCopy(); { //Create a copy of this Bar and return it as a Foo }
}

Note that without covariant return types we need to declare that we return a Foo (officially) instead of a Bar (even though we actually return a Bar). This might not be that bad until you write the following code.

//Copying things
Foo myFoo;
Foo myOtherFoo = myFoo.getCopy();

Bar myBar;
Bar myOtherBar = myBar.getCopy(); //Compiler error - getCopy() returns a Foo

Even though you know that myBar is a Bar, and that you (actually) get a Bar from the myBars's getCopy(), you need to cast the return value to get it to compile. Worse, it is a potential source for bugs...

public class Baz : Foo
{
    override public Foo getCopy(); { //Create a copy of this Baz and return it as a Foo }
}

//Copying more things
Foo myFoo;
Foo myOtherFoo = myFoo.getCopy();

Bar myBar;
Bar myOtherBar = myBar.getCopy() as Bar;

Baz myBaz;
Baz myOtherBaz = myBar.getCopy() as Baz; //Whoops

Notice the typo? Without covariant return values you might only notice during runtime (when the program crashes), with them the compiler can tell you at compile time: No, that can't work.

In summary: Covariant Return Values let you write shorter, preciser and safer code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.