Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The interface cannot be used as type argument. Static member does not have a most specific implementation in the interface

I have the following implementation which uses .NET 7’s static abstract member functionality:

public interface IFoo
{
    public static abstract string Bar { get; }
}

public class Foo : IFoo
{
    public static string Bar => "Bar"
}

Now, whenever I use the interface as a type parameter to a generic class, I get an error. For example, if my Program.cs looks like this:

List<IFoo> fooList = new List<Foo>();

I get the following error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

error CS8920: The interface ‘IFoo’ cannot be used as type argument.
Static member ‘IFoo.Bar’ does not have a most specific implementation
in the interface.

I guess that, for whatever reason, this is a C# restriction. I could be wrong, though, so now I’m asking: is there any way to solve this case or at least get around this restriction?

>Solution :

I guess that, for whatever reason, this is a C# restriction.

Yes, the restriction is explained in the specification and the reason is type safety. Example from the linked github issue:

interface I
{
    static abstract string P { get; }
}
class C<T> where T : I
{
    void M() { Console.WriteLine(T.P); }
}
new C<I>().M(); // Error

You can "fix" it by using the static virtual method:

public interface IFoo
{
    public static virtual string Bar => throw new Exception();
}

Problem here is that now implementors do not need to implement the method:

public class Foo1 : IFoo // valid now
{
}

Another approach is to use marker interface (though it can be considered an antipattern):

public interface IAmActuallyFoo
{
    
}
public interface IFoo : IAmActuallyFoo
{
    public static abstract string Bar { get; }
}

var fooList = new List<IAmActuallyFoo>();

P.S.

Note that List<IFoo> fooList = new List<Foo>(); is invalid anyway because variance is not supported by classes (see docs, this and/or this answer).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading