OneOf in C#
Table of Content:
How do we return several types from a single method using OneOf<T0, …Tn> in C#
Introduction
In every c# dot net project, I have used one of the libraries (OneOf<T0, …Tn>) to return various return types from a single method.
As a backend developer, I have primarily used this package to return the objects, validate errors, and try..catch errors from the service.
OneOf<T0, …Tn> Class Library In C#
In c#, Oneof<T0, …Tn> is a Discriminated Union, Discriminated Unions are a programming convenience that shows that something is one of the multiple types of objects.
Mostly, This library is used to return a variety of object types from the method.
When to use OneOf<T0, …Tn> library
We have a service method to get the user details, we want to return validation error, authentication error, or finally user details if everything is well.
We have a user-defined method/function to get particular data from the user details like name(string), age(number) or salary(real numbers), etc.
Steps to install OneOf<T0, …Tn>
Open the manage NuGet package and search for OneOf and install it.
Or
We can use the following command to install OneOf<> from the package manager console.
Other ways to install can be found here.
After we’ve installed this library, make sure it’s installed properly or not.
Some Important Properties of OneOf<>
There are 2 main properties while using OneOf<>.
- IsT<index>: This is used to determine which response type is returned by the method.
- AsT<index>: This is used to fetch specific response type values returned by the method.
It will be used like IsT0, IsT1, AsT0, and AsT1, here 0 and 1 are indexes of response types.
Let’s see some examples for this, then we will be more clear about this.
Examples
Let’s assume we have a method to return multiple response types and we need to use this method and get different types of values.
Here is a basic console program to get one of 3 different types of string, boolean, and integer as response and access those values and process ahead.
- using System;
- using OneOf;
namespace ConsoleApp { class Program { static void Main(string[] args) { Program p = new Program(); var outcome = p.GetDynamicTypeResponse(3); // put parameter as 1,2 or 3 then we can see the different response type output. if (outcome.IsT0) // check if response is string type using IsT0(for first type) { string stringValue = outcome.AsT0; // access to first response type value using AsT0 Console.WriteLine(stringValue); } else if (outcome.IsT1) // check if response is int type using IsT0(for second type) { int integerValue = outcome.AsT1; // access to second response type value using AsT1 Console.WriteLine(integerValue); } else // otherwise a response is bool or we can also use IsT2(for the third type) { bool booleanValue = outcome.AsT2; // access to third response type value using AsT2 Console.WriteLine(booleanValue); } Console.ReadKey(); } private OneOf<string, int, bool> GetDynamicTypeResponse(int choice = 1) { if (choice == 1) { return "string"; // return string type value } else if (choice == 2) { return 10; // return integer type value } else { return true; // return boolean type value } } } }
Let’s assume another example: we have a service method to get details about a student, and we want to return one of the following:
- paged list of student objects
- list of student objects
- validation error
- try..catch the error
public async Task<OneOf<PagedList<StudentDisplayModel>, List<StudentDisplayModel>, Error>> ListStudents (int skip = 0, int take = 5, string searchText = "") { try { //validation if (validation condition) { // return Error; } //your code if (condition) { return PagedList<object> of StudentDisplayModel } // return List<object> of studentDisplayModel } catch (Exception ex) { // return catch error; } }
In Controller you can access services like this:
[HttpGet("list")] [ProducesResponseType(typeof(PagedList<StudentDisplayModel>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(List<StudentDisplayModel>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ErrorListingItems), StatusCodes.Status400BadRequest)] public async Task<IActionResult> ListStudents(int skip = 0, int take = 5, string searchText = "", CancellationToken cancellationToken = default) { var outcome = await _studentService.ListStudents(skip, take, searchText, cancellationToken); return outcome.IsT0 ? Ok(outcome.AsT0) : outcome.IsT1 ? Ok(outcome.AsT1) : BadRequest(outcome.AsT2); }
Conclusion
So In this way, we can use OneOf<> to return and access multiple response types from a single method in c#.
If you enjoyed this post, then like and share it with your friends and colleagues.
Leave a Reply
Want to join the discussion?Feel free to contribute!