I've enabled Nullable References in my C# 8.0 project. I've also set all warnings as errors to force myself to address all such warnings. But one of them is confusing me. It is a dependency property that returns an interface pointer that might validly be null. Here is the property (inside a control called "LayerView")
private static readonly DependencyProperty ShapeBeingDrawnProperty = DependencyProperty.Register(
nameof(ShapeBeingDrawn),
typeof(IShape),
typeof(LayerView),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
public IShape ShapeBeingDrawn
{
get => GetValue(ShapeBeingDrawnProperty) as IShape; // RIGHT SIDE OF "=>" UNDERLINED IN RED
set => SetValue(ShapeBeingDrawnProperty, value);
}
With nullable references enabled, this understandably causes a warning on the getter. The entire right side of the get is underlined in red and I get this build error
1>C:\Users\jmole\Documents\Dev\Mobile\Core\Views\LayerView.xaml.cs(429,13,429,16): error CS8766:
Nullability of reference types in return type of 'IShape? LayerView.ShapeBeingDrawn.get' doesn't
match implicitly implemented member 'IShape ILayerView.ShapeBeingDrawn.get' (possibly because of
nullability attributes).
First of all, what "implicitly" implemented member are they talking about? This is an explicitly implemented member. I am literally implementing it right here. But that aside, I tried to fix this as I've fixed many other such validly nullable properties: Make the property return a nullable reference
public IShape? ShapeBeingDrawn // ONLY CHANGE IS HERE
{
get => GetValue(ShapeBeingDrawnProperty) as IShape; // NOW, JUST "get" IS UNDERLINED IN RED
set => SetValue(ShapeBeingDrawnProperty, value);
}
Unfortunately, this does not help. I still get the same error but this time the only part underlined in red is just the left side of the getter (the word "get").
Finally I was able to eliminate this error by changing the property back to a normal reference and using a hard cast in the getter
public IShape ShapeBeingDrawn
{
get => (IShape)GetValue(ShapeBeingDrawnProperty);
set => SetValue(ShapeBeingDrawnProperty, value);
}
But now, any code that tries to set this property to null (which is valid) gets a compiler error and I have to address that.
private void LayerView_OnKeyDown(object sender, KeyEventArgs e)
{
// Don't do anything if we've disabled shape mouse/touch input.
if (e.Key != Key.Escape)
return;
UnselectAll();
ShapeBeingDrawn = null; // COMPILER NO LIKEY
}
So what is the proper way to integrate nullable references and dependency properties? Should I just #pragma warning disable around such problems? I'd like to avoid that if I can.
IShape ShapeBeingDrawn
is inherited from anotherinterface
? If it does, then how is it declared in thatinterface
? I was able to reproduce your problem only when the propertyShapeBeingDrawn
was inherited from anotherinteface
, and to fix it I had to ensure that both in inteface and in the class this property was declarednullable
ornot nullable
. Please, check this sample: dotnetfiddle.net/cOQY4F. – Iliar Turdushev