BrandGhost

Easy Type Conversion With C# Implicit Operators - Code Available!

In this video, we walk through an example of how you can make use of implicit operators in C# dotnet. The use case will be creating an object that can hold either one of two types, but never both, and that this object can easily be converted between the two types in question. Want the source for this video? Check it out here: https://github.com/ncosentino/NexusLabs.Framework/blob/master/NexusLabs.Framework/TriedEx.cs For more videos on programming with detailed examples, check this out: https:...
View Transcript
today we're going to look at implicit operators and C sharp and I'm going to walk through an example of where I was using implicit operators to try and create something like a multi-type class so usually when we're talking about implicit operators there's a lot of people that are pretty hesitant to use things like implicit operators in c-sharp and I'm one of them I actually haven't ever had a use for them and then recently I was trying to play around with them a little bit because I was curious and I came up with a pattern that I was actually pretty happy with so I'm going to walk you through my pattern using implicit operators and then I'm going to show you how I'm using that in some of my other code so to start let's actually have a look at the syntax that we need to use for implicit operators so for the example that I'm going to walk through today the implicit operator syntax you can see right here is going to have public static implicit operator and then actually what we're doing with implicit operators is type conversion so what we see highlighted here where it says tried X and then a generic type here is actually going to be the type that we're casting to implicitly so to give you some context I mentioned that I was trying to create something like a multi-type and what I meant by that is a single class that could actually hold one of two types of objects so there's already nuget packages that exist that do some of this magic for you that kind of give you this opportunity to have something like a one of type of class and this way like as the name suggests you're able to have one of one of the types that this class supports for a lot of what I do I like to play around so I can learn for myself so this class that we're looking at that can have multiple types you can actually see them right here what we're going to be doing is having a class that can take in a generic non-null value or it can take in an exception and if you're looking at the naming convention that I'm using you might be catching on here that what I'm trying to create is something like a return type that can either be the value of the function that I wanted to calculate or an exception if something bad happened so the implicit operators that I wanted to work with were converting from the type that I want my object to be able to hold converting from an exception that I want my object to be able to hold we'll look at an example that actually shows the use case for both of these implicit operators if you imagine a function with tried X and the generic T parameter here what we're able to do is actually return something that is just the value t or return the exception what's really cool about this is we can just return either the type t or an exception without having to write out the code to go create a new instance of this object it will just implicitly convert it does in fact actually create a new instance and you can see right here in both these operators that it is in fact calling the Constructor the other implicit operators that this supports actually work the exact opposite way so given one of these tried X generic T type types we're actually able to take the type T value directly off of it or take the exception directly off of this so if you think about the person calling the function they can actually get the exception or get the type T directly off of this return type together all of these kind of create something that feels a little bit like when you make nullable types and you're able to check to see if it has a value or actually take the value off of it let's just quickly have a look through the rest of the class and then we'll go to look at an example of how this is used so this class just has two Constructors and really we're just able to pass in either the value that we're interested in or an error and again keep the use case in mind that this is going to be used as a return type for functions when we want to be able to return an exception or return the actual value from the function in either case we're only setting one of either the error or the value for this object the remainder of this class aside from the implicit operators is primarily just being able to pull the actual value off of this and if we look at the implementation for this property if we actually have an error then we throw an exception and say you're not supposed to be grabbing the value directly off of this because this did experience an error and therefore there is no value this particular implementation that I made does not support nulls directly for this object so if You Were Somehow able to construct one of these with a null value I do have a bit of a sanity check here that says that we shouldn't be able to do this but otherwise we're going to return the value these are just implementation details for how I wanted to make this class it's not really important for the implicit operator part I'm just demonstrating what I was putting together the other two properties just to quickly mention are the exception that we can pull off of this object in case there is an exception and then a quick Boolean parameter that just says whether or not there was an error so if there was no error right it's set to null here what we're able to do is just have a quick check to see if this result was successful so before I jumped into the code that I'm actually using in some of my applications I just wanted to show you a quick little class that I made that actually wrapped some of this functionality it makes calling it a little bit nicer this pattern that we see on the screen here from lines 88 to 102 is essentially something that I found myself writing a lot all over my code personally I know a lot of people will say don't use like these Pokemon handlers right you gotta catch all the exceptions but I actually find myself writing code where I want to be able to catch exceptions and log the information that's happening and generally what I might do is then throw the exception or handle it some other way but generally I have something like logging and because I do that I wanted to create this pattern to make it a little bit more generic if we think about the implicit operators that we were just talking about we can notice that on line 88 we have the return type that is tried x with a generic T parameter and what we're going to be doing is calling some function and the idea as the name suggests is we're going to get the result of that function or the error that occurs if you look at line 94 and 95 we can see that we're actually just getting the result of the Callback and returning it and this is the success path so if this all works and there's no exception thrown great we just returned the result which is if we look at the Callback it's just of type t the implicit operator is actually allowing us just to return result which is of type T and you'll notice that type T is not the return type here so the implicit operator allows us to do this nicely the last part just the catch with this error callback and like I said I might use this a lot of the time just for being able to log this catch block you'll notice actually Returns the exception so if you look at line 95 and line 100 these are returning two different types and again the implicit operators kind of give us this cool functionality where we can return a tried XT as the type of the function but the individual returns that we're doing are one of the result type or an exception so hopefully that explains the implicit operator part so far you might not like this type of pattern and you may not want to use something like this in your code but for me I found a lot of the time I was trying to avoid basically just throwing exceptions and parsers but I still wanted to have a bit more information about why my parsing failed so instead of just returning a true or false value I actually wanted to have something like an exception and because my parsers are often dealing with information that I'm not really controlling I also wanted the ability to say if something bad happened and I do want to catch an exception that actually occurred I can go ahead and log that but still make sure that my parser can return the exception and not totally just blow up a lot of the time I am just trying to parse is a best effort so let's walk through an example where I'm actually using this tried X Type here recall that I mentioned I'm often using it for things like parsing and in this case I'm also using it for things like converting I'm attempting to make a conversion here there's going to be some cases where I actually can't control the input properly and as a result I want to do a best effort but I still want to have information about what went wrong when it went wrong you'll notice here that I have a asynchronous task that is going to return a tried x with a double so in this case in the happy path I'm just going to be returning a number but in the failure case I'm going to return an exception this particular method is trying to convert a number between two different units so for example if you wanted to convert grams to kilograms pounds to ounces milliliters to liters that kind of stuff that's what this method is trying to do the first part of this function you'll notice that I'm just trying to go to a repository look up a particular unit and then if the result of that lookup is that I did not find something I'm actually just going to return an invalid operation and actually provide the information about what went wrong you might say well why aren't you throwing an exception here and my reason for that is that throwing exceptions is really slow for me I wanted to see if I could stop throwing exceptions everywhere but instead try to return them if I could get a performance boost and organize my code in a way that was a little bit different than usual but still felt nice for me to use the second part of this function is doing something very similar I'm just trying to look up the destination unit that we're trying to convert to and again if that fails I'm able to return this invalid operation exception and you'll notice that by returning these two exceptions on line 218 and 208 tried X is actually the return type so we're using implicit operators to get that nice Syntax for free the other way that we would normally do this is really just say return and then wrap this invalid operation exception in an object but I like this syntax because it just makes it look nice and clean in my opinion if we go to line 222 you'll notice that we actually have a very similar pattern occurring it's just that we're calling another function called try convert async that actually is going to give us a result that is of type tried double in this particular case I have a slight variation of my tried X class that doesn't return an exception but instead it will just give us a true or false along with the type that that function can return you'll notice that on line 228 I'm actually able to say with this exclamation mark not conversion result which is actually the same as saying if the conversion result is not successful right but if you recall I had implicit operators that could do some conversion for us in this particular case the slight variation I can implicitly convert my result type to a true or a false depending on the success for the tried X example that we looked at instead of converting to a true or a false I can convert to the exception automatically and I had another success property in addition to that so if we look at the last little bit of code in here in my opinion this is pretty cool because you can see quite close together that we can either return an exception or we can return the result of the conversion line 230 and line 234 are different types but the implicit operator allows us to convert to the returning type that we see up here on line 197 and as I create this video this method is actually a good candidate for that safely class that I was showing a little bit earlier that allows us to actually wrap all of this in a try catch with a callback for logging again the takeaway here isn't necessarily that I'm just trying to show that I'm getting rid of bubbling up exceptions by being able to return them as a type I just wanted to show you what the syntax looks like when you're using implicit operators to be able to do this type of return to a single type even though you're returning two potentially different types it's totally okay if you disagree with the entire concept that I'm doing for try catch and returning the exceptions I get it not everyone's going to like that but I wanted to try playing around with that and in my use case I've actually found it to be really helpful and it's all doable because I was able to use these implicit operators so to summarize what we were able to look at was a class that using a couple of implicit operators we could actually convert between two different types of this class would wrap we looked at some Syntax for functions over the return type was this class that we looked at that could hold one of two different types and then we could see see that the different returns within the function we never actually had to go manually new up a new instance of this return type but instead we could return directly one of the two types that this other class could contain we briefly looked at the implicit operators that work the other way and the one example there was I had a return type that could implicitly convert to a true or false depending on the result of that function if it completed successfully or not so I wanted to share that example with you because personally I haven't really found any reason to use implicit operators but when I went exploring to go play around with this I thought this was a pretty cool use case I am using it in my code and I found for me at least it's helped clean some things up with a little bit of cool syntax I'd be curious to hear from you in the comments if you found any use cases for implicit operators because I'd like to go explore that too and maybe learn a little bit more for myself thanks so much for watching I hope you found some of this informative and we'll see you next next time

Frequently Asked Questions

What are implicit operators in C# and why should I use them?

Implicit operators in C# allow for automatic type conversion between types without needing to explicitly call a conversion method. I found them useful for creating a multi-type class that can hold either a value or an exception, simplifying my code and making it cleaner.

Can you give an example of how implicit operators are used in your code?

Sure! In my example, I created a class that can hold either a generic value or an exception. By defining implicit operators, I can return either the value or the exception directly without having to instantiate a new object each time, which makes the syntax much cleaner.

Are there any downsides to using implicit operators?

While implicit operators can simplify code, they can also lead to confusion if overused or used inappropriately. It's important to ensure that the conversions are intuitive and that they don't hide potential issues, like unexpected exceptions. I personally had hesitations about using them, but found a good use case that worked well for my needs.

These FAQs were generated by AI from the video transcript.
An error has occurred. This application may no longer respond until reloaded. Reload