-
Notifications
You must be signed in to change notification settings - Fork 985
refactor: Added nullable annotations to Annotations classes of Core library. #1935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: Added nullable annotations to Annotations classes of Core library. #1935
Conversation
|
Sorry I've not got around to looking at this yet, I'll try to find time tomorrow to go through it properly. |
|
Main thing to work out, I think, is how we are going to signal properties that have no default but must be assigned, e.g. Pinging @Jonarw because he reviewed my original attempts at this. |
|
For now, I've just settled on simply throwing |
|
Context I'm imagining is a user who is assembling an object from different places (so can't just throw all the properties together at once without needing a builder or shadow type of some kind) who may fail to set the value of one of these required-but-with-no-default properties: they may either not realise that they are meant to assign the value, or it may not be assigning it without realising (or indeed may be assinging it null without realising). As you say, hopefully OxyPlot itself isn't going to assign e.g. |
VisualMelon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of small things, otherwise I think this is all good.
| /// </summary> | ||
| /// <value>The text.</value> | ||
| public string? Text { get; set; } | ||
| public string Text { get; set; } = string.Empty; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should remain as string? Text initialised to null
(Sorry, my original comment wasn't very clear: with it nullable we need to add checks when calling into MathRenderingExtensions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that might be inevitable. I'll take a closer look now, but I don't think we can change the default to non-null in a hurry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only see problems with this if users with Nullable disable can sometimes have null instead of this value. But this will result in an NRE for them anyway.
While exceptions will let the user know that they forgot to set the Text property, the very use of TextualAnnotation implies this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same problem as ImageAnnotation.ImageSource etc.: it has to be set, but there's almost 10 years of code that might not be initialising the object all at once, and may even be using null to signal to different parts of code that it needs to be changed: changing the default at this point will cover-over failing to assign the value, and be a silent code-breaking change for some users. Perhaps we can try to gauge how big a deal this will be?
Regarding the last point, PointAnnotation and friends don't actually require the text property to be set; however, the behaviour won't change for PointAnnotation with your proposal, but it may change the behaviour of consuming code. It may just be the old versions of everything we're using, but I'm surprised by the error in that case, as the usage is within an if (!String.IsNullOrEmpty) check.
Looking back at old posts, I think my previous remarks express my current feelings rather well:
I think the main benefit we might see from this will just be in informing us where we should be throwing more helpful errors. Short of breaking every plot element in two, I don't think there is too much we can achieve to tighten the API, so it will mostly be limited to expressing which things may be null, which dilutes the meaning for those which are expected to be null.
The problem is that OxyPlot is basically a bundle of mutable objects without defaults (which means that null signals something to the consumer). This (TextualAnnotation.Text) is obviously a case where I'm advocating for making something nullable because it might happen to be null, rather than because it is intended to be null.
@Jonarw has previously described the possibility of just leaving nullable off for certain types; I'm going to do some reading/experimentation to see if this might be a possibility in these cases. I've previously been opposed to this, but I could certainly buy the benefit of having nullable annotations on all methods but omitting it on a class of properties if it's not too misleading for the consumer. In particular, we could leave these unannotated now, and then annotate them e.g. when we have required: benefit of required is that it expresses the intention well, means simple and correct code will continue to work fine, and will noisily break old code, so is OK for a major release.
I'm torn between respecting the type system - which tells me to keep these nullable and use documentation to talk to the user instead - and trying to express the intention that these should be initialised to a non-null value by the user - which tells me to make these non-null and just initialise them to null anyway (is there any precedent for this in other libs?). I'm definitely opposed to adding non-null defaults for everything at the moment, though in this specific case, perhaps string.Empty would be OK..
Sorry, no decisions in there... I'd like to take a bit more time to think about this. My instinct still is to keep them nullable, and add more useful exceptions and inline documentation. Feel free to dump any vaguely relevant thoughts you might have here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pinging @Jonarw again should be want to jump in on this
|
@HavenDV thanks for pushing that (if nothing else makes it easier to talk about): what's your reckoning? ( |
Sorry, I didn't understand what you mean, English is not my native language |
|
Sorry, I'm not sure that's even good English to be honest. Just wanted to know your opinion on your latest commit; obviously it's not pretty, but I don't think we can do better while continuing to support netstandard1.0 if we do make |
|
I've been doing this since the early days of nullable enable and I'm already used to it, so it looks ok to me. |
|
Cool; I suspect most other strings where we'll need these checks will be left as nullable, so shouldn't be wide-spread. |
|
I've not done a complete review again, but I think if you're happy with the current state of this PR, then I am also happy. If so, will merge once 2.1.1 is out of the way (so hopefully next weekend). |
|
Hi. Any news? |
|
2.1.1 became 2.1.2 when I made a mistake, but let's ignore that and merge this. |

Checklist
Changes proposed in this pull request:
@oxyplot/admins