I have some non-nullable fields which I want to initialize inside a helper methods, called from a constructor, to reduce the clutter inside the constructor:
private FlowLayoutPanel _flowPanel;
private ComboBox _printersComboBox;
//...
public PrintSettingsView(IServiceProvider serviceProvider, IPrintSettings printSettings)
{
InitializeComponent();
PostInitializeComponent(); // this is where _flowPanel etc get initialized
// ...
}
How do I avoid warnings like Non-nullable field '_flowPanel' must contain a non-null value when exiting constructor. Consider declaring the field as nullable
?
The best idea I've come up with so far:
public static void Assert([DoesNotReturnIf(false)] bool condition)
{
if (!condition) throw new InvalidOperationException();
}
public PrintSettingsView(IServiceProvider serviceProvider, IPrintSettings printSettings)
{
InitializeComponent();
PostInitializeComponent();
Assert(_flowPanel != null);
Assert(_printersComboBox != null);
//...
}
It's still getting messy when there's a lot of fields. Is there anything better than this?
It's a .NET 6 project, so I could use the latest and the greatest.
private FlowLayoutPanel _flowPanel = null!;
to shut the analyser up, and then trust yourself to correctly initialise it – Lagunas= null!
actually... not sure I like it more thanAssert
though :) – Connell[MemberNotNullWhen(true, nameof(_flowPanel)), MemberNotNullWhen(...)] bool PostInitializeComponent() { ...; return true; }
. Then in the constructorDebug.Assert(PostInitializeComponent())
. The drawback is that you must spell out every member this way, which could get tedious. – TailsMemberNotNull(nameof(...))
. – BagMemberNotNullWhen
(because it's, um, cooler). – Tailsout
arguments. – ConnellInitPrintersComboBox
etc). Tuple \ out parameters are too easy to mess up (assign value to the wrong field). – Bagpublic PrintSettingsView(IServiceProvider serviceProvider, IPrintSettings printSettings): this(/* init the UI */)
in place ofPostInitializeComponent
. – Connell