4

Introducing C# 9: Covariant returns

 3 years ago
source link: https://anthonygiretti.com/2020/10/12/introducing-c-9-covariant-returns/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
csharp9-covariant-return.png?fit=749%2C388&ssl=1

Introducing C# 9: Covariant returns

2020-10-12 by anthonygiretti

Introduction

In May 20th 2020, Microsoft introduced C# 9, among the features announced, there is one that has not yet been talked about much: covariant returns. Usually in C# when we inherit from a class, it is possible to override a method if it is declared abstract or virtual but it is not possible to change the return type of this method. C# 9 allows this, In addition to overriding a virtual or abstract method, in C# 9 you can now return a covariant type of the initial type declared in the parent class. For example, you can now return a type that is inherited from the parent class. In this article I will show you how it works with a very simple example and compare with earlier versions of C# 9. This post was produced with input from Dave Brock. Dave recently posted some really interesting C # 9 articles which you can find here: https://daveabrock.com/2020/06/29/c-sharp-9-deep-dive-inits

Before C# 9

Here is a simple example of “covariant returns” before C# 9, you had to return the initial type like this:

public abstract class Product { protected string Name { get; } protected int Id { get; }

protected Product(string name, int id) { Name = name; Id = id; }

public abstract ProductOrder Order(int quantity); }

public class Book : Product { public string ISBN { get; }

public Book(string name, int categoryId, string Isbn) : base(name, categoryId) { ISBN = Isbn; }

public override ProductOrder Order(int quantity) => new BookOrder { Quantity = quantity, Product = this }; }

public class Music : Product { protected Format Format { get; }

public Music(string name, int categoryId, Format format) : base(name, categoryId) { Format = format; }

public override ProductOrder Order(int quantity) => new MusicOrder { Quantity = quantity, Product = this }; }

public class ProductOrder { public int Quantity { get; set; } }

public class BookOrder : ProductOrder { public Book Product { get; set; } }

public class MusicOrder : ProductOrder { public Music Product { get; set; } }

public enum Format { Mp3, Disc }

Then after instanciation and calling the Order method, you had to cast the initial return type to its derived type like this:

public class Program { public static void Main(string[] args) { var book = new Book { Name = "My book", Id = 1, ISBN = "978-3-16-148410-0" };

var music = new Music { Name = "My music", Id = 2, Format = Format.Disc };

BookOrder orderBook = (BookOrder)book.Order(1); MusicOrder orderMusic = (MusicOrder)music.Order(1); } }

As you can see there a cast to perform, and it can avoided with C# 9 🙂

With C# 9

Now let’s take the same example, but now you can explicitely return a covariant like this:

public abstract class Product { protected string Name { get; } protected int Id { get; }

protected Product(string name, int id) { Name = name; Id = id; }

public abstract ProductOrder Order(int quantity); }

public class Book : Product { public string ISBN { get; }

public Book(string name, int categoryId, string Isbn) : base(name, categoryId) { ISBN = Isbn; }

public override BookOrder Order(int quantity) => new BookOrder { Quantity = quantity, Product = this }; }

public class Music : Product { protected Format Format { get; }

public Music(string name, int categoryId, Format format) : base(name, categoryId) { Format = format; }

public override MusicOrder Order(int quantity) => new MusicOrder { Quantity = quantity, Product = this }; }

public class ProductOrder { public int Quantity { get; set; } }

public class BookOrder : ProductOrder { public Book Product { get; set; } }

public class MusicOrder : ProductOrder { public Music Product { get; set; } }

public enum Format { Mp3, Disc }

Its makes the consumption simpler:

public class Program { public static void Main(string[] args) { var book = new Book { Name = "My book", Id = 1, ISBN = "978-3-16-148410-0" };

var music = new Music { Name = "My music", Id = 2, Format = Format.Disc };

BookOrder orderBook = book.Order(1); MusicOrder orderMusic = music.Order(1); } }

Conclusion

It’s definitely not the most famous functionality of C# 9 but it could be pretty useful, your code is being a bit simpler :).

I would like to thanks Dave Brock for his participation as well, it was very fun to get his insights. I strongly encourage you to visit his awesome blog (https://daveabrock.com/) !

Like this:

Loading...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK