The keywords "notnull" and "nullable" for class types #9114
Unanswered
Dsyboot
asked this question in
Language Ideas
Replies: 1 comment 13 replies
-
The default value of any reference type is With NRTs, the errant code would already warn/error. |
Beta Was this translation helpful? Give feedback.
13 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Problems with classes with null
Well, let's say we have a numeric data type class
and for some reason, we don't want to allow null in it, in some way, mimic the primitive types behavior of course.
So what options do we currently have?
Structs:
Oh yes, structs, quite light, fast and non-nullable.
But, there is a problem, these are stored sometimes in Stack or the Heap,
this has problems when the internal data that we are going
to create is many bytes, since when passing through references
these structures, it can be quite slow to take all the data of their and make a new copy to use.
But, structs force you to initialize all variables you have declared in them
(similar to making variables read-only). Another problem is that in structs it is not allowed
to inherit from them in other structs or classes, which is a limitation if you need to allow inheritances.
Keyword notnull (edited because it works as warning)
Wow, so, in C# exists something called "notnull", I guess this is what I want! That's amazing, so I guess I don't need to do anything else. Right?
Mmm let's try something like this?
Maybe which generics?
Well, let's try removing "class"
Okay, seems like this would work, so, let's instance MyClass!
Oh surprise... "notnull" doesn't do what you'd think, personally, I thought it could prohibit the entry of null for classes or Nullables, but no, what it really does is in theory show a warning about the data types with null for the generic types. Very disappointing actually, because that keyword haves to much potential alone.
And, you know what is funny about this keyword?
What it really does is give you a warning, not actually prohibit the assignment of null (I used to think this keyword was useless? But, thanks to the comments I was able to realize that I didn't have #nullable active, which is weird since I've never turned it off, but in the end it just gives a warning that it's not expected, but doesn't block its use. Thanks @HaloFour to mention the problem of why it didn't show warnings.
Classes:
Well, it seems like that we are back to classes, but here is the problem, these can be null.
I know it doesn't seem like a big deal, it's just validating in each constructor, method, or property to avoid null.
But... That's the problem!, having to validate everywhere to get rid of null. In my case I'm making a class called BigDecimal,
but I realized that problem, that I have too much methods, constructors and properties, I don't have the patience to be
validating null in each one of them, that's why I looked for solutions to avoid my class from having a null instance.
Well, I discovered that the only viable option is to make a struct, but there is the problem, this BigDecimal class haves data
that tends to have many bytes because it uses two BigIntegers, plus I am forced to initialize all declared variables
(which is not a problem, since my constructors take care of it). Worse I also have static variables that are initialized with a
static constructor (THANKS for inventing this, it's really useful for initializing certain data for general use in classes),
something that does not exist in structs, and it's reasonable why.
An example class and the proposed solution
You know... Is very interesting than C# doesn't have something to allow programmers to have classes without null,
because C# alone has too many classes for anything you can imagine, and it's amazing, since you can find almost
everything in the language itself. Although I also imagine that some classes do not exist to let programmers to make reality
their own ideas, which is a very good thing to be honest, since only in this language I keep programming every day and night.
Well, now in the solution. A solution to this problem would be to add the keyword "nullable", because the keyword "notnull" already exists but works weird.... (or it doesn't work?), now I will explain to you why:
Okay!, now when we create an instance of this class, we do it as usual:
Now, we try to give an null input
Did you see the problem? Sometimes an exception will appear, but, you know, this is easy to fix:
Now this is valid:
Ah, as we have seen, it is very easy to fix here, since there are only two cases in a constructor where it can be null.
But, this can have problems later, as one can add methods, more constructors, properties, even operator overloading.
So let's talk about the proposed keyword: "nullable" and an improvement to the existing keyword: "notnull"
How to use?
In theory it's super simple to use, if you want a class than cannot be null, just use:
This imitates the behavior of the structs, because these cannot be null, but at the same time, having all the advantages of a class, such as static constructors, inheritance, polymorphism, and more.
But, if you want your class to be null, you have two options:
I imagine you're thinking, why use nullable if you could just avoid it? Well... The answer is when we make inheritances.
Inheritance
Suppose we inherit from a class that has the keyword "notnull", by common sense you might think that it could continue being notnull, or lose that property. But, because it's inheritance, we need to keep al the property's of the base class
Okay!, let's test what happens if why try to use null in both classes
As you can see, the compiler will just not allow this, because notnull will like as an property!
Okay! Now, what happens if we need to make a class nullable again? (This can be useful if you want to handle null for some operations)
As you can see, we need to use explicitly nullable for allow programmers to use null in notnull heritances. But... Maybe this can have problems if we are trying to inheritance two classes with different null blockage:
Easy solution
Actually, if we really need to inherit these classes, we could explicitly tell the compiler that we want a "notnull" or "nullable" class, fixing this problem ✅
With null:
Without null:
How to do it with variables
You see.. this solution is only for declaring classes as nullable or notnull, but, if we have variables that can be null, we can do something like Nullable does. We need an system, and struct called NotNull to do the opposite as Nullable
Before ending this post...
Okay!, Now let's imagine that all this is implemented, how will the numeric class shown at the beginning look?
Now will try to do exactly the same as before:
An possibly issue with this
This may possibly cause errors, since nullables are usually initialized with null, so the solution would be to internally use default to avoid problems, as well as allowing programmers to define the default instance like this:
Okay! Now you know this idea for making the keyword "notnull" actually useful, and also adding a feature to the language itself. I don't see this actually coming in a future version of Net 9.0, it's more like Net 10 (if this will exists obviously!). And I know this is just and idea, I will appreciate the comments about this :D (I'm so sorry if my english is not too good, because I'm originally talk in Spanish)
Thanks for reading all of this! I forgot to mention that it is not necessary to rewrite all the existing code in C#, since this would be a new feature for .Net 9-10+, so there is no need to change the original code!
Beta Was this translation helpful? Give feedback.
All reactions