2

When I program in Java, I make all nullability explicit; that is, an instance of Foo is assumed to be non-null, and if I want it to be null, I use a @Nullable annotation (or better, Optional<Foo>). But C# doesn't natively support annotations, and Nullable<> is only for value types.

But what if I did something like this?

struct Value<T> where T : class {
  T value;
}

And then use Value<Foo>? as the type for a field. What impact would this have on performance/memory, and is there something that makes this a very bad idea?

  • 2
    C# does have something quite like annotations - it's called attributes - and, if you are using JetBrains ReSharper by any chance, see this and this – Filip Milovanović Nov 5 '17 at 9:30
  • You might also consider investigating Code Contracts for C#, which let you represent non-nullability. – Eric Lippert Nov 6 '17 at 21:37
  • If you want to know what the impact on performance is, try it both ways and measure the results. Then you will know. – Eric Lippert Nov 6 '17 at 21:37
  • If this is the approach you want to take, I recommend making use of Jon Skeet's MiscUtil.NonNullable<T>, available at jonskeet.uk/csharp/miscutil . I would encourage you to read the source code (including the comments) within NonNullable.cs; it handles numerous scenarios that you may not have considered. – Brian Nov 7 '17 at 14:06
9

References are already passed by value in .net. And since value can be null, you’re not gaining much. You can’t even force a nice constructor to guarantee that value is non-null since structs require a public nullary constructor.

You’re doing work to gain nothing but confusion.

  • I think that's a little bit unfair. Using such a NonNullable is making a declaration of intent that draws attention at compile-time (rather than at runtime), making it a bit more effective than an assertion. It's trivial to work around, but such work-arounds tend to be deliberate. Avoiding use of the public constructor of the struct can be enforced by both a preprocessor and by a coding convention. That said, I don't think it's usually worth the trade-offs; I favor coding contracts over this, and even that's not probably only worth it for completely new code-bases. – Brian Nov 7 '17 at 14:11
  • @Brian - I disagree. Preprocessors and coding conventions are fragile. More likely, someone new to the project will go about their day assuming that the value can never be null, causing bugs. Or your serialization breaks because of the stupid wrapper. – Telastyn Nov 7 '17 at 15:59
  • And in that scenario (assuming you use Jon skeet's implementation of non-nullable), you'll hit a run-time exception, which is the same behavior you'd experience when using a non-nullable. So the error scenario is the same. As for serialization: You're right that non-nullables make serialization more complicated. – Brian Nov 8 '17 at 14:27
1

There are few C# Option/Maybe implementations : here, here or here

There is also a proposal to make non-nullable references in C#, in which case there will be need for some kind of Nullable/Option type for reference types.

So your idea is perfectly sound and supported by many people. Its just your implementation is not that great. You don't need to wrap a reference in structure and then use Nullable. Just make the structure behave like Nullable. Which is what all other implementations are doing.

As for performance, I wouldn't worry too much. Better performance is often achieved using better structures and algorithms and not micro-optimizing your types. And any performance hit will be out-weighted by improved stability and readability of your code, due to explicit handling of null states.

0

Looks like you're reinventing wheels there - why can't you simply use T? as the nullable value type? I imagine under the covers exactly what you are suggesting is happening already. As the nullability is explicitly defined in the type definition using the ?, then you have what you want already.

As for types that are already nullable, I'd say making a nullable generic type that can itself contain a null to be a particularly bad idea just because it will confuse people, add lots of extra code and provide no benefit.

If you really must have an annotation, use a naming convention.

  • I can't use T? because T is a reference type; it's an abstract class with subclasses. – Nick Tobey Nov 5 '17 at 0:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.