Skip to content
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

MemberNotNullWhen does not work when overridden in derived interface #76743

Closed
Ilchert opened this issue Jan 14, 2025 · 2 comments
Closed

MemberNotNullWhen does not work when overridden in derived interface #76743

Ilchert opened this issue Jan 14, 2025 · 2 comments
Labels

Comments

@Ilchert
Copy link

Ilchert commented Jan 14, 2025

Version Used:
SDK 9.0.101
Steps to Reproduce:

  1. Mark overridden property as MemberNotNullWhen from base interface
  2. Roslyn ignores this attribute

sharplab

string Get(IResponse<string> s) {
        if(s.IsSuccess)
            return s.Content; // warning CS8603: Possible null reference return.
        return  "default";
    }

interface IResponse
{
     bool IsSuccess {get;}
}

interface IResponse<T>:IResponse
{
    [MemberNotNullWhen(true,nameof(Content))]
     abstract bool IResponse.IsSuccess {get;}
     T? Content {get;}
}

Diagnostic Id:
warning CS8603: Possible null reference return.

Expected Behavior:
Should not trigger warning.

Actual Behavior:
As far I understand MemberNotNullWhen can reference only properties/methods from same class. Like in the example. But in this case, it ignores the attribute on IsSuccess override.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Jan 14, 2025
@RikkiGibson
Copy link
Contributor

I think when the IsSuccess declaration is an explicit interface implementation, that member is not "seen" at the use site. Only the signature of the implemented member is seen. So if you want attributes and such to have an effect at the use site you may want to do something like this: SharpLab

using System.Diagnostics.CodeAnalysis;

string Get(IResponse<string> s) {
        if(s.IsSuccess)
            return s.Content; // ok
        return  "default";
    }

interface IResponse
{
     bool IsSuccess {get;}
}

interface IResponse<T>:IResponse
{
    bool IResponse.IsSuccess => IsSuccess;

    [MemberNotNullWhen(true,nameof(Content))]
     abstract new bool IsSuccess {get;}
     T? Content {get;}
}

@RikkiGibson RikkiGibson added Question Resolution-Answered The question has been answered labels Jan 15, 2025
@RikkiGibson
Copy link
Contributor

Closing out as answered. Feel free to follow up with any more questions or concerns. Thanks!

@dotnet-policy-service dotnet-policy-service bot removed the untriaged Issues and PRs which have not yet been triaged by a lead label Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants