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

"Implement abstract class" should add "where T : default" when a parameter is covariant in T? #62092

Closed
SolalPirelli opened this issue Jun 23, 2022 · 2 comments · Fixed by #66615
Labels
Area-IDE Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it
Milestone

Comments

@SolalPirelli
Copy link

Version Used: Visual Studio 17.2.5 (VisualStudio.17.Release/17.2.5+32616.157 ; C# Tools 4.2.0-4.22281.5+8d3180e5f00d42f0f0295165f756f368f0cbfa44)

Steps to Reproduce:

  1. Write the following code:
interface I<out T> { }

abstract class C
{
    protected abstract void M1<T>(T? t);
    protected abstract void M2<T>(I<T?> i);
}

class C2 : C
{
}
  1. Use "Implement abstract class" on C2

Expected Behavior:

The resulting code should compile.

Actual Behavior:

M1 is correctly implemented but M2 is not, as it is missing where T : default and thus does not compile:

    protected override void M1<T>(T? t) where T : default
    {
        throw new NotImplementedException();
    }

    protected override void M2<T>(I<T?> i) // <- this does not compile
    {
        throw new NotImplementedException();
    }

A more realistic example for is using a Func<T?> as parameter.

It took me a while to even understand what the issue was, since the compiler doesn't say anything about where T : default being something you can do in the resulting error messages. Perhaps the compiler could detect that there is an override that would work if it had where T : default and warn about that?

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Jun 23, 2022
@SolalPirelli SolalPirelli changed the title "Implement abstract class" should add "where T : default" when a parameter is covariant in T "Implement abstract class" should add "where T : default" when a parameter is covariant in T? Jun 23, 2022
@Youssef1313
Copy link
Member

I think I missed this case in #53318.

@SolalPirelli
Copy link
Author

This happens for implementing interfaces implicitly as well:

interface I<out T> { }

interface I2
{
    void M1<T>(I<T?> i);
}

class C : I2
{
}

"Implement interface" produces valid code, "Implement all members explicitly" does not. (I like how the preview for the latter already shows the red squiggles within the preview -- how cool is that? 😄 )

@vatsalyaagrawal vatsalyaagrawal added Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Jul 11, 2022
@vatsalyaagrawal vatsalyaagrawal added this to the 17.4 milestone Jul 11, 2022
@arunchndr arunchndr modified the milestones: 17.4, 17.6 P3 Jan 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Bug help wanted The issue is "up for grabs" - add a comment if you are interested in working on it
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants