'MemberNotNullWhen (or other code analysis attributes) for inherited members?

I have a class:

public abstract class InvestorAccount
{
    public bool IsRegistered => ...;
}

And a subclass:

public class PrivateInvestorAccount : InvestorAccount
{
    public Person? Holder { get; set; }
}

I would like to teach the compiler that Holder is not null when IsRegistered is true.

If both props were declared in the same class if could just annotate IsRegistered with [MemberNotNullWhen(true, nameof(Holder))]. However, in the inheritance scenario, applying [MemberNotNullWhen(true, nameof(PrivateInvestorAccount.Holder))] ends up in a compilation error:

error CS8776: Member 'Holder' cannot be used in this attribute.

Is there any way of telling the compiler that Holder is not null in this scenario?



Solution 1:[1]

You can define IsRegistered as virtual...

public abstract class InvestorAccount
{
    public virtual bool IsRegistered => ...;
}

...and then override it in your subclass...

public class PrivateInvestorAccount : InvestorAccount
{
    public override bool IsRegistered => base.IsRegistered;
    public Person? Holder { get; set; }
}

...which allows you to place an attribute on it only in the subclass (which makes sense, because Holder, and, thus, the additional meaning of your IsRegistered property, is only available in your subclass):

public class PrivateInvestorAccount : InvestorAccount
{
    [MemberNotNullWhen(true, nameof(Holder))]
    public override bool IsRegistered => base.IsRegistered;
    public Person? Holder { get; set; }
}

Solution 2:[2]

If both props were declared in the same class

They are in the same class, you're deriving there. So the syntax is as you said:

[MemberNotNullWhen(true, nameof(Holder))]

Also, nameof is syntactic sugar (more or less) for the word after it, in this case the above is equivalent, yet strictly better, to:

[MemberNotNullWhen(true, "Holder")]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Blindy