Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
There is no difference in principle between TypeScripts say string|number and this Result. You can't do anything with string|number unless you cast first.
Tis is not true. LSP is about substitution not about doing something meaningful. You can substitute Result with its subtypes and the program will be fine. Also note that this behavior is precisely what union types do in languages with more powerful type systems and I never heard anyone consider them a LSP violation.
2) "You're signing yourself up for LSP violations." - pretty sure I am not. LSP is about subtyping not about inheritance. 3) My suggested pattern matching version doesn't handle not passing a value either. However the exception approach does - you can't ignore exception. F# also does handle this case as you cannot ignore a return value
3) I don't like the approach with properties because cases can be ignored, especially in situations where you don't want to retrieve the result. When using ASP.NET Identity I have on more than one occasion shipped code in production where I do something like create user where I don't care about the result and I forget to check if the result is successful. It is quite weird I'd rather get an exception and see a crash.
2) The result object is arguably a misuse of OOP but it is not misuse of subtyping. I am trying to emulate the functional approach here which I quite like but C# lacks the tools to represent it and inheritance is a kind of work-around
1. The 409 code is not supposed to be used like this but I found that it works quite well in practice. We had an app where the code was properly used (to identify invalid relations or situations where the user wanted to delete something that has attached items which should be deleted first). Then we found out it works well for all cases where the user should be presented with the message for the server. I am quite happy with this design and am not looking to change that.
I considered this approach but in reality the continuation is often async. This means that I should have MatchWithAsync which can be awaited and accept async lambdas. I thought that approach too heavy on syntax in this async context. Otherwise it is quite good.
Well, I am only discussing the client here. The server is of course stateless, and the whole point of Blazor is to have stateful client experience (like desktop)
I am thinking of a message bus because the global exception handler doesn't know about the specific forms that need to be reenabled. The goal is not to have try/catch around the call in the form but have a single handler for the application. Even if I use the viewmodel how would the property be set assuming the exception handling logic is not in the viewmodel itself The client tech I am using is ASP.NET Blazor. To be fair I am not sure if it has a concept of global error handler at all.
Maybe but then what? Just wrap every call in try/catch and add the handling in each catch? I'd rather have ifs in this case. It seems to me that the exceptions approach would be good if I find a way to let them bubble up and use a common handler that works in all forms. Maybe a message bus and let the forms subscribe to messages and force them to have Unlock method which enables the controls?
I can't think of a practical case where I do anything but display the error to the user. However I don't want to "stop" work. I want to enable the form so he can try again or click something else. I don't want the app to crash (in the Blazor's case it would display the Reload button)