News for hackers. Stuff that matters.
Re:.NET Framework 4.6.2 by dimgl on Tuesday August 02, 2016 @05:56PM (#12213721)
I can't believe it took this long to show the name of null references. NullReferenceException is actually the first exception I ever encountered when I started learning how to use C#.

That being said, better late than never.

Re:.NET Framework 4.6.2 by jpalomaki on Wednesday August 03, 2016 @01:44AM (#12215870)
+1 for this. The null conditional is also pretty nice thing for the chained method calls. In C# you can write like this:

  int? count = customers?[0]?.Orders?.Count();
https://msdn.microsoft.com/fi-fi/library/dn986595.aspx

Pragmatic features like this are one reason why I love C#. I get the feeling that language designers are actually looking at real world code and thinking what kind of features would be it better.

Re:.NET Framework 4.6.2 by piaste on Wednesday August 03, 2016 @04:52AM (#12216596)
Slight aside: please don't abuse the Elvis operator like that (by using it on every single nullable reference), it could easily grow into a widespread anti-pattern that makes debugging harder.

My rule of thumb is that ?. is OK to use when

1) The reference is expected to occasionally be null in the course of normal operations

2) You legitimately don't care if the reference is unexpectedly null, as you wouldn't or couldn't fix it even if you knew about it

Otherwise it's better to discover and fix the NullReferenceException ASAP.

Re:.NET Framework 4.6.2 by gregmac on Wednesday August 03, 2016 @12:35PM (#12219255)
Generally agreed, and out of curiosity I just looked through some fairly new code I have that's pretty heavy on C# 6, and only found a single instance of two null conditionals being used:

    Assert.That(r.Exception?.InnerException?.Message, Is.EqualTo("Exception result"));
Next closest thing that shows up a few times is coalescing to a default value:

    config?.OutputName ?? DefaultConfig.OutputName
Some other examples that show up a lot:

Invoke Action<> or Func<> that may be null or unassigned (this works for Events as well):

    actionHandler?.Invoke(value);
Extracting a value from a LINQ expression on a list of container objects (this one is actually from a unit test where it's explicitly only expecting one item):

    items.First()?.Data
Easy way to do a Coalesce on a specific property value in a collection:

    items.FirstOrDefault(item => item.Data != null)?.Data
Re:.NET Framework 4.6.2 by piaste on Thursday August 04, 2016 @01:14PM (#12227020)

    items.First()?.Data
I think this one doesn't do anything because .First() will throw on an empty collection.

The rest of your samples look fine to me though.

Re:.NET Framework 4.6.2 by perezdev on Wednesday August 03, 2016 @05:12AM (#12216686)
It's the null propagation operator.
Re:.NET Framework 4.6.2 by breischl on Wednesday August 03, 2016 @11:32AM (#12218667)
Look, if you want to be pedantic it's the null conditional operator[1]. But it is widely called the "Elvis operator"[2].

[1] - https://msdn.microsoft.com/en-us/library/dn986595.aspx

[2] - https://www.google.com/#q=c%23+elvis+operator

Re:.NET Framework 4.6.2 by ygra on Tuesday August 02, 2016 @06:15PM (#12213851)
Is that really such a sorely missed feature? I tend to need just a quick glance at the offending line to isolate potential null references and in more severe cases just check the tool tips of expressions. Or are others writing code that's unusually dereference-heavy?
Re:.NET Framework 4.6.2 by niftich on Tuesday August 02, 2016 @06:20PM (#12213882)
I'd imagine that with the rise of the 'fluent' API style of foo.bar().baz().doThis().doThat(toThis).doAnother(toThat); the number of potential null-references per line has gone up from the days when we were all writing code with mutator methods that returned void.
Re:.NET Framework 4.6.2 by gnaritas on Tuesday August 02, 2016 @06:36PM (#12213971)
The Fluent API styles is to return "this" so setter methods can be chained, that style doesn't produce nulls.
Re:.NET Framework 4.6.2 by niftich on Tuesday August 02, 2016 @06:46PM (#12214025)
Yes, but any of the passed-in arguments can be null if they are de-referenced without checking, or you can muck up your context by doing something weird.

I'm not justifying buggy code, but these days we do handle more objects-per-debug-line-number than we used to.

Re:.NET Framework 4.6.2 by tracker1 on Wednesday August 03, 2016 @03:19AM (#12216227)
Especially in lambda expressions for LINQ methods...
Re:.NET Framework 4.6.2 by ygra on Wednesday August 03, 2016 @03:34AM (#12216298)
But you can already debug inside lambda expressions. E.g. for

     new string[] { "1", null }.Select(s => s.Length).ToList();
VS has no trouble at all telling me the statement that caused the NRE and I can inspect variables local to the lambda as well.
Re:.NET Framework 4.6.2 by pionar on Wednesday August 03, 2016 @11:16AM (#12218541)
But you can't always debug code that's out in the wild with the same exact scenario that caused the NRE.

It's helpful to have the actual thing that's null for post-error troubleshooting.

Re:.NET Framework 4.6.2 by ygra on Wednesday August 03, 2016 @11:45AM (#12218763)
The whole discussion is about a debugger feature, or at least, the runtime groundwork required for said debugger feature. It will not result in the exception message telling you the null reference's name. It enables an attached debugger to query the runtime for additional information to determine that.
Re:.NET Framework 4.6.2 by AndrewDucker on Tuesday August 02, 2016 @06:43PM (#12214005)
It does when it has a bug in it...
Re:.NET Framework 4.6.2 by fuzzy2 on Wednesday August 03, 2016 @02:22AM (#12215987)
> return this

Not necessarily. Take a look at LINQ, for example.

Re:.NET Framework 4.6.2 by gnaritas on Wednesday August 03, 2016 @11:33AM (#12218672)
LINQ is not a fluent programming style, LINQ is standard functional programming with higher order functions. Chaining calls back to back isn't what fluent is, chaining calls to the same object back to back is fluent whereas with LINQ each call returns a whole new object or set of objects; these are entirely different things. The fluent style is an attempt to emulate Smalltalk's cascade operator in languages that lack it by returning "this" from setters enabling a chain of setters to be called on the same object: that's all it is. This style has been idiomatic to Smalltalk since the 70's and doesn't require faking it because there's actually a cascade operator.
Re:.NET Framework 4.6.2 by moogly on Tuesday August 02, 2016 @08:48PM (#12214667)
Common, popular, coding styles with a lot of inlined code instead of temporaries will have this issue:

  public Result MapResult(IntermediateType src)
  {
      return new Result
      {
          Property1 = src.Property1,
          Property2 = src.Indirection.Property,
          [...]
      };
  }
or, in C# 6

  public Result MapResult(IntermediateType src)
      => new Result
      {
          Property1 = src.Property1,
          Property2 = src.Indirection.Property,
          [...]
      };

     
if Indirection is null here (or indeed anything that can throw an NRE within the initializer), the NRE will reference the line starting with return/=>
Re:.NET Framework 4.6.2 by kmc059000 on Tuesday August 02, 2016 @09:39PM (#12214936)
This is usually where I get NREs too and is the most frustrating. When using object initializers, the line number is the same for the entire initializer, so you don't get much help in determining exactly which line the exception was on.

I imagine there is a reason why it's hard, but it seems like it should be easy and incredibly valuable to know which property assignment caused the exception.

Regardless, I agree that this is a major source of NREs

Re:.NET Framework 4.6.2 by ygra on Wednesday August 03, 2016 @02:44AM (#12216086)
Good point, thank you. We're still rather conservative, so except for nameof I haven't yet used any C# 6 features, and the code we write often doesn't look like that, so I tend to forget a few problematic styles sometimes.
Re:.NET Framework 4.6.2 by daigoba66 on Tuesday August 02, 2016 @06:50PM (#12214053)
In optimized code, in object initializers, or even within lambda expressions, the line number is effectively useless. So troubleshooting production exceptions is usually a game of guess-and-check. As a result, many teams are heavy handed with null checks and ArgumentExceptions if only to make debugging easier in crappy code.
Re:.NET Framework 4.6.2 by douche on Tuesday August 02, 2016 @07:37PM (#12214285)
Yup, can confirm. Release builds usually have nearly all useful stack information stripped out, so if you get a NRE, you're kind of left playing pin-the-tail-on-the-donkey guessing at what might have been null, without null-checks and asserts.
Re:.NET Framework 4.6.2 by dimgl on Tuesday August 02, 2016 @06:19PM (#12213875)
Once you're experienced and writing better code, this isn't a crucial feature. It does help when you've got coworkers who write classes with 20,000 lines however (not an exaggeration, I've actually seen this).
Re:.NET Framework 4.6.2 by mattmanser on Tuesday August 02, 2016 @06:47PM (#12214033)
It was constant, especially in older code bases or anything involving SOAP responses with crappy WSDLs.

I'm surprised you've honestly never opened an error call stack and gone "I wish I knew which one it was that is null".

Re:.NET Framework 4.6.2 by ygra on Wednesday August 03, 2016 @12:48AM (#12215654)
These days I actually cannot recall when that happened to me the last time, hence my curiosity. I remember null pointer dereferences in C++ on Android being impossible to debug, but honestly cannot recall the same for C# in VS. Might be that we simply don't write code that's susceptible to that problem (writing libraries ideas of applications makes you kinda defensive sometimes), or maybe that our code is often a bit conservative out of necessity, so no C# 6 features yet (others have pointed out that certain constructs are prone to let you guess on which line it happened).
Re:.NET Framework 4.6.2 by tracker1 on Wednesday August 03, 2016 @03:24AM (#12216247)
It's funny, but with JS I write pretty defensively to prevent null references...

    function frob(foo) {
      return (foo && foo.ary || [])
        .map(...)
    }
Even though I know everything that will call frob exists and has ary, that doesn't mean it won't change or work otherwise... one of the things I like about how shorting works in JS... though the "?" conditional null thing in C# is pretty damned close.
Re:.NET Framework 4.6.2 by lmm on Wednesday August 03, 2016 @05:40AM (#12216768)
That ends up worse than null because the actual error will happen even further away when some value is surprisingly []. You want to fail fast in cases where your state no longer makes sense. (This is why naive use of options can end up worse than null).
Re:.NET Framework 4.6.2 by tracker1 on Friday August 05, 2016 @06:45AM (#12231229)
If the function ALWAYS returns an array, then so be it. If someone's response to my function can't handle an empty array, then their method probably has other issues, and they should check their own data before calling into it.

I'll do other methods that will return an appropriate value, or null. In this way, if you can be defensive in your own code, you aren't the one called when someone hands you garbage.

Just like an HTTP server shouldn't crash because someone sends it data that should return a 4xx response.

Re:.NET Framework 4.6.2 by lmm on Friday August 05, 2016 @08:05AM (#12231588)
> If the function ALWAYS returns an array, then so be it. If someone's response to my function can't handle an empty array, then their method probably has other issues, and they should check their own data before calling into it.

It's best to make it impossible to call your function with the wrong kind of thing, but Javascript doesn't have a type system. Still though, if their code has gotten into a nonsense state, better to throw an exception (or whatever the language-standard way of handling errors is) than silently carry on. Otherwise they can spend up hours debugging their filtering logic wondering why it's started filtering everything out, when in fact the server they were calling into has started sending 1-element responses as not an array which your code then silently changes into an empty array.

> I'll do other methods that will return an appropriate value, or null. In this way, if you can be defensive in your own code, you aren't the one called when someone hands you garbage.

If you propagate garbage you're part of the problem. Defensiveness goes hand-in-hand with fail-fast.

> Just like an HTTP server shouldn't crash because someone sends it data that should return a 4xx response.

Right but if your query was malformed you should get a 4xx, not a 200 with no results. (This is one reason I think it's actually a bad idea to use 404 for when there's no item with that ID - it makes it hard for the client to tell the difference between "I called the API wrong" and "I called the API correctly but there are no results").

Re:.NET Framework 4.6.2 by Someone on Wednesday August 03, 2016 @02:19AM (#12215976)
"in more severe cases just check the tool tips of expressions."

There are no such tool tips when looking at log files. If this problem happens rarely or only in production, that oftentimes is the only thing you have.

Even if there are just two potential null references on the offending line, one of which seems unlikely, knowing for sure that it is the other one will speed up finding the root cause.

Re:.NET Framework 4.6.2 by ygra on Wednesday August 03, 2016 @02:43AM (#12216077)
But you don't have a Visual Studio debugger in log files either. This change is about runtime improvements that would enable a debugger to tell you the offending null reference. This won't change the exception message or anything about the exception itself.
Re:.NET Framework 4.6.2 by Someone on Wednesday August 03, 2016 @11:52AM (#12218806)
For me, anything that produces a stack trace should use that information. IIS can be configured to do that.
Re:.NET Framework 4.6.2 by martinald on Tuesday August 02, 2016 @06:52PM (#12214060)
You could use that argument with any slightly-better debugging feature. It's not groundbreaking but will save a few seconds/minutes each time from darting around. It adds up after a while and I bet after the next release of VS has it it looks backwards not having it.
Re:.NET Framework 4.6.2 by flukus on Tuesday August 02, 2016 @07:32PM (#12214252)
The code your debugging isn't always line for line compatible with the code where/when the exception was thrown.
Re:.NET Framework 4.6.2 by iamcreasy on Tuesday August 02, 2016 @06:04PM (#12213783)
Anybody knows if/when Java will have this feature?
Re:.NET Framework 4.6.2 by benjiweber on Wednesday August 03, 2016 @01:56AM (#12215899)
SAP's JVM implementation has NullPointerExceptions that tell you where the null originated from, which is neat.

See slide 17 of https://oracleus.activeevents.com/2014/connect/fileDownload/...

Re:.NET Framework 4.6.2 by meddlepal on Tuesday August 02, 2016 @11:18PM (#12215329)
I doubt believe it will ever or at least not anytime soon. I don't think the JVM preserves identifier names in the bytecode in a way that it can be accessed easily.

Though I do recall a long time ago reading about some JVM switches that allow that data to be accessed but with performance issues. Can't recall where I read that.

Re:.NET Framework 4.6.2 by iamcreasy on Wednesday August 03, 2016 @02:04AM (#12215922)
> JVM switches that allow that data to be accessed but with performance issues. Can't recall where I read that.

Would love to know how to do that.

Re:.NET Framework 4.6.2 by meddlepal on Wednesday August 03, 2016 @05:33PM (#12221704)
Use the "-g:vars" switch on javac and then use a classfile reader library to inspect the LocalVariableTable.
Re:.NET Framework 4.6.2 by kodfodrasz on Wednesday August 03, 2016 @01:25AM (#12215788)
Sadly (as one developing a lot in Java) i think it won't happen anytime soon, and the community will ideologize it as "it is even better that we don't have it". :(

I hope I will be wrong.

ps: a language where non-nullable references are the thing would be the best.

Re:.NET Framework 4.6.2 by lmm on Wednesday August 03, 2016 @05:41AM (#12216773)
Java has finally got options, so at least it's theoretically possible to start a migration path to non-nullable. It will take decades though.
Re:.NET Framework 4.6.2 by kodfodrasz on Wednesday August 03, 2016 @07:41AM (#12217228)
I tried to use the java Optional<T>, but the API has some points, which make it inconvenient for some usecases. (Some of these are addressed in Java 9)

As I see: unfortunately without algebraic types you cannot solve this properly, even if you address the lacking points in Optional<T>