dotnet/roslyn

CS compiler accepts contradicting signature and fails to accept exact signature when overriding a generic abstract method

Open

#76,914 opened on Jan 24, 2025

View on GitHub
 (7 comments) (0 reactions) (0 assignees)C# (4,257 forks)batch import
Area-CompilersConcept-Diagnostic ClarityFeature - Nullable Reference Typeshelp wanted

Repository metrics

Stars
 (20,414 stars)
PR merge metrics
 (Avg merge 6d 17h) (256 merged PRs in 30d)

Description

This compiles:

#nullable enable

using System;
					
namespace Demo
{
    public interface ITest
    {
        public bool TryGet<T>(out T? result) where T : notnull;
    }

    public abstract class MyAbstractClass : ITest
    {
        public abstract bool TryGet<T>(out T? result) where T : notnull;
    }

    public class MyDerivedClass : MyAbstractClass
    {
        public override bool TryGet<T>(out T result)
        {
            throw new Exception("");
        }
    }
}

public class Program
{
	public static void Main()
	{
		Console.WriteLine("Hello World");
	}
}

This fails:

#nullable enable

using System;
					
namespace Demo
{
    public interface ITest
    {
        public bool TryGet<T>(out T? result) where T : notnull;
    }

    public abstract class MyAbstractClass : ITest
    {
        public abstract bool TryGet<T>(out T? result) where T : notnull;
    }

    public class MyDerivedClass : MyAbstractClass
    {
        public override bool TryGet<T>(out T? result)
        {
            throw new Exception("");
        }
    }
}

public class Program
{
	public static void Main()
	{
		Console.WriteLine("Hello World");
	}
}

public override bool TryGet<T>(out T result) signature, the one the compiler is happy to accept, contradicts both inherited definitions while it rejects public override bool TryGet<T>(out T? result) which is exactly the same as in parents.

Contributor guide