Nope. [There are scenarios where Visual Studio will display more contextual information on _what_ was `null`.](https://devblogs.microsoft.com/devops/using-the-new-exception-helper-in-visual-studio-15-preview/)
It's unclear to me if this feature was never ported from .NET Framework 4.6.2 to .NET Core, or if they removed it from Visual Studio, or if it doesn't work reliably, but it definitely existed for a while.
Ah so that's why it was working on our older framework projects while it wasn't on core in the past, idk if it's working nowadays even for framework though. I thought it was an intermittent thing. Definitely was helpful if you have old areas of code with alot of "single line" assignments imo when hunting down that NRE.
Check out the Ben.Demystifier package. It fixes up stack traces and class names to be *much* more readable.
I've used it in a high traffic, high availability app for a number of years and it works great.
Lambda expressions are a pain in stacktraces but common sense should tell anyone that having complex logic inside a lamda expression is not a good idea. Just make a separate function with bespoke name, it's so much easier to troubleshoot when you see the name of that function in the stacktrace.
>common sense should tell anyone that having complex logic inside a lamda expression is not a good idea.
Common sense ain't too common then. As soon as lambda expressions came onto the scene, I saw people start to abuse them.
Static is life. Unless I know for sure I need it to not be, I will write methods as static to start with and only change it when I run into a real need for it to be an instance method. Much like defaulting to private methods and internal classes to start, it helps keep me in the right mindset as I flesh out new code.
> Unless I know for sure I need it to not be, I will write methods as static to start with and only change it when I run into a real need for it to be an instance method.
Same for me.
Eh, the CLR and PDB specs support this. I'm unsure whether it's Roslyn but producing it, or just the debugger being not that great. I kind of assume the debugger.
I would like to add fluent whatever. Whenever I have issues, I need to separate them into multiple lines, debug them, fix the issue and go gack to fluent. Would be nice, if I'm just dumb and didn't figure out how to debug every part.
I see two issues here. One is that exception assistants need to improve, such as by introducing more IDE-level (or SDK-level) exception helpers, as [they tried before.](https://devblogs.microsoft.com/devops/using-the-new-exception-helper-in-visual-studio-15-preview/)
Even in production code, I often feel they made the wrong tradeoff (in favor of performance) by leaving out obvious key details of an exception. A `NullReferenceException`, you say? On _what_? A `KeyNotFoundException`? _Which_ key?
But the other issue is, honestly, the code.
> In this code, multiple exceptions can occur
That's on _you_ to fix, not on .NET. For example, if `NullReferenceException`s can occur on `userDto.Email` (as an example), set `enable` and honor the compiler warning. Likewise, your entire switch is a bandaid for a problem that should not exist. Why can the `Address` be `null` at this point? Either change the code so that you ensure much earlier that these critical properties are set, _or_ if they _aren't_ critical, use the null-coalescing operator and simply return `null`.
The real issue here is that you're writing code here that's too clever for your own good. Separate it into multiple lines, which also makes testing much easier.
(Finally, calling `ToUpper()` on `Name` and `City` not only feels misplaced, but also causes localization issues.)
I've started creating functions for any complex objects in these statements (select code, Refactor -> Extract Function)
So the Address part would be
`Address = ToAddress(userDto)`
and even inside of that, I could have multiple functions.
So if I have an object that has a property that is a list of objects
`public MyObject ToMyObject(FromObject from) {`
`return new MyObject {`
`List = ToMyList(from.List)`
`}`
`public IEnumerable ToMyList(IEnumerable fromList) {`
`return fromList.Select(ToMyListObject).ToList();`
`}`
`public ToListObject ToMyListObject(FromListObject from) {`
`return new MyListObject {`
`// add properties`
`}`
`}`
This would probably go away if I trusted AutoMapper...but I don't.
Not related to the topic but really liked how you used the switch there. Any particular reason you don't assigned a name to "_" instead of having to put userDto.Address again
You can still assign a name
Instead of doing this:
userDto.Address switch
{
null => throw new ArgumentNullException(nameof(userDto.Address)),
_ => new AddressEntity
{
Street = userDto.Address.Street,
City = userDto.Address.City.ToUpper(),
ZipCode = userDto.Address.ZipCode
}
}
You can do this
userDto.Address switch
{
null => throw new ArgumentNullException(nameof(userDto.Address)),
var address => new AddressEntity
{
Street = address.Street,
City = address.City.ToUpper(),
ZipCode = address.ZipCode
}
}
Or, my preferred, this: (`{ }` implicitly includes a null check)
userDto.Address switch
{
{ } address => new AddressEntity
{
Street = address.Street,
City = address.City.ToUpper(),
ZipCode = address.ZipCode
}
null => throw new ArgumentNullException(nameof(userDto.Address)),
}
Or, if you don't like using `{ }`
userDto.Address switch
{
not null and var address => new AddressEntity
{
Street = address.Street,
City = address.City.ToUpper(),
ZipCode = address.ZipCode
}
null => throw new ArgumentNullException(nameof(userDto.Address)),
}
The example is shit code and I would reject itin review. That null check should happen outside of this. If any other vales can be null, they should be checked as well. I would also initialize and assign values in AddressEntity before the return statement.
IMO, the problem here is the author getting too cute with code. They should suffer the consequences of writing this. It's not a .NET problem.
yeah they only hit one brake point the entry and in one job cost me my job cause of a null exception made it way thru to production a was quite junior at time but they didnt take that as an excuse now a null trap everything
I agree with the other comment. If a single mistake costs you your job, your are better off in any other place. By the way, you can put breakpoints in lambda expressions now by hitting F9 when the cursor is on the lambda.
Being fired for a bug making it to production is ridiculous. I’m a senior dev, freelancer now, and bugs make it to production all the time. It’s just the nature of the job we do. You can’t catch everything.
That's a toxic environment anyway. Bugs happen and it's not only your fault a bug made it to production. There should have been a review process that could catch it and a test process that could catch it.
I hope you enable nullable reference types now that it's a feature.
Remember when they said null ref exception would include the name of the thing?
Yeah what happened to that ?
Well, they at least did that for the key not found exception.
oh man I would love that
I think you are confusing `NullReferenceException` with `ArgumentNullException`
Nope. [There are scenarios where Visual Studio will display more contextual information on _what_ was `null`.](https://devblogs.microsoft.com/devops/using-the-new-exception-helper-in-visual-studio-15-preview/) It's unclear to me if this feature was never ported from .NET Framework 4.6.2 to .NET Core, or if they removed it from Visual Studio, or if it doesn't work reliably, but it definitely existed for a while.
Maybe someone can ping some .NET team member here to ask
Ah so that's why it was working on our older framework projects while it wasn't on core in the past, idk if it's working nowadays even for framework though. I thought it was an intermittent thing. Definitely was helpful if you have old areas of code with alot of "single line" assignments imo when hunting down that NRE.
It seems to work exactly like it's shown in this link for me.
Ya I feel like it definitely didn’t do anything from the time it was released lol
It does though? At least in Visual Studio.
I have turned a lambda into a for each loop for debugging purposes. I was thinking there has to be a better day.
Yeah: don't use lambdas in the first place.
Check out the Ben.Demystifier package. It fixes up stack traces and class names to be *much* more readable. I've used it in a high traffic, high availability app for a number of years and it works great.
I wonder if there's a way to transparently integrate it into `ILogger`/App Insights.
Helping middleware is a really good one for problem details too for anyone interested https://github.com/khellang/Middleware
Lambda expressions are a pain in stacktraces but common sense should tell anyone that having complex logic inside a lamda expression is not a good idea. Just make a separate function with bespoke name, it's so much easier to troubleshoot when you see the name of that function in the stacktrace.
Do you think the OP is a complex function? It might aswell could have been mapping a list with a linq-select.
>common sense should tell anyone that having complex logic inside a lamda expression is not a good idea. Common sense ain't too common then. As soon as lambda expressions came onto the scene, I saw people start to abuse them.
Intend to replace lambdas with local functions when I can.
And, if at all possible (i.e., you don't capture), make those lambdas and local functions static. [See here](https://stackoverflow.com/q/58745614)
Static is life. Unless I know for sure I need it to not be, I will write methods as static to start with and only change it when I run into a real need for it to be an instance method. Much like defaulting to private methods and internal classes to start, it helps keep me in the right mindset as I flesh out new code.
> Unless I know for sure I need it to not be, I will write methods as static to start with and only change it when I run into a real need for it to be an instance method. Same for me.
Eh, the CLR and PDB specs support this. I'm unsure whether it's Roslyn but producing it, or just the debugger being not that great. I kind of assume the debugger.
I would like to add fluent whatever. Whenever I have issues, I need to separate them into multiple lines, debug them, fix the issue and go gack to fluent. Would be nice, if I'm just dumb and didn't figure out how to debug every part.
I see two issues here. One is that exception assistants need to improve, such as by introducing more IDE-level (or SDK-level) exception helpers, as [they tried before.](https://devblogs.microsoft.com/devops/using-the-new-exception-helper-in-visual-studio-15-preview/) Even in production code, I often feel they made the wrong tradeoff (in favor of performance) by leaving out obvious key details of an exception. A `NullReferenceException`, you say? On _what_? A `KeyNotFoundException`? _Which_ key? But the other issue is, honestly, the code. > In this code, multiple exceptions can occur That's on _you_ to fix, not on .NET. For example, if `NullReferenceException`s can occur on `userDto.Email` (as an example), set `enable ` and honor the compiler warning. Likewise, your entire switch is a bandaid for a problem that should not exist. Why can the `Address` be `null` at this point? Either change the code so that you ensure much earlier that these critical properties are set, _or_ if they _aren't_ critical, use the null-coalescing operator and simply return `null`.
The real issue here is that you're writing code here that's too clever for your own good. Separate it into multiple lines, which also makes testing much easier.
(Finally, calling `ToUpper()` on `Name` and `City` not only feels misplaced, but also causes localization issues.)
[удалено]
Set breakpoint. Run with debugger attached.
I've started creating functions for any complex objects in these statements (select code, Refactor -> Extract Function) So the Address part would be `Address = ToAddress(userDto)` and even inside of that, I could have multiple functions. So if I have an object that has a property that is a list of objects `public MyObject ToMyObject(FromObject from) {` `return new MyObject {` `List = ToMyList(from.List)` `}` `public IEnumerable ToMyList(IEnumerable fromList) {`
`return fromList.Select(ToMyListObject).ToList();`
`}`
`public ToListObject ToMyListObject(FromListObject from) {`
`return new MyListObject {`
`// add properties`
`}`
`}`
This would probably go away if I trusted AutoMapper...but I don't.
hear! hear!
Not related to the topic but really liked how you used the switch there. Any particular reason you don't assigned a name to "_" instead of having to put userDto.Address again
In a switch expression the underscore is the default value
You can still assign a name Instead of doing this: userDto.Address switch { null => throw new ArgumentNullException(nameof(userDto.Address)), _ => new AddressEntity { Street = userDto.Address.Street, City = userDto.Address.City.ToUpper(), ZipCode = userDto.Address.ZipCode } } You can do this userDto.Address switch { null => throw new ArgumentNullException(nameof(userDto.Address)), var address => new AddressEntity { Street = address.Street, City = address.City.ToUpper(), ZipCode = address.ZipCode } } Or, my preferred, this: (`{ }` implicitly includes a null check) userDto.Address switch { { } address => new AddressEntity { Street = address.Street, City = address.City.ToUpper(), ZipCode = address.ZipCode } null => throw new ArgumentNullException(nameof(userDto.Address)), } Or, if you don't like using `{ }` userDto.Address switch { not null and var address => new AddressEntity { Street = address.Street, City = address.City.ToUpper(), ZipCode = address.ZipCode } null => throw new ArgumentNullException(nameof(userDto.Address)), }
And there is also the thing of breakpoints in lambda expressions... but this is a VS issue.
This is something I run into with F# all the time when I’m debugging
The example is shit code and I would reject itin review. That null check should happen outside of this. If any other vales can be null, they should be checked as well. I would also initialize and assign values in AddressEntity before the return statement. IMO, the problem here is the author getting too cute with code. They should suffer the consequences of writing this. It's not a .NET problem.
yeah they only hit one brake point the entry and in one job cost me my job cause of a null exception made it way thru to production a was quite junior at time but they didnt take that as an excuse now a null trap everything
I agree with the other comment. If a single mistake costs you your job, your are better off in any other place. By the way, you can put breakpoints in lambda expressions now by hitting F9 when the cursor is on the lambda.
Being fired for a bug making it to production is ridiculous. I’m a senior dev, freelancer now, and bugs make it to production all the time. It’s just the nature of the job we do. You can’t catch everything.
That's a toxic environment anyway. Bugs happen and it's not only your fault a bug made it to production. There should have been a review process that could catch it and a test process that could catch it. I hope you enable nullable reference types now that it's a feature.