OneOf 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>
1. 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.
2. 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!