接口不能用作类型参数。静态成员在接口中没有最具体的实现

And*_*löw 5 .net c#

我有以下使用 .NET 7 的静态抽象成员功能的实现:

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

public class Foo : IFoo
{
    public static string Bar => "Bar"
}
Run Code Online (Sandbox Code Playgroud)

现在,每当我使用接口作为泛型类的类型参数时,我都会收到错误。例如,如果我的 Program.cs 如下所示:

List<IFoo> fooList = new List<Foo>();
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

错误CS8920:接口“IFoo”不能用作类型参数。静态成员“IFoo.Bar”在接口中没有最具体的实现。

我猜想,无论出于什么原因,这是 C# 的限制。不过,我可能是错的,所以现在我问:有没有办法解决这个问题,或者至少绕过这个限制?

Gur*_*ron 4

我猜想,无论出于什么原因,这是 C# 的限制。

是的,规范中解释了限制,原因是类型安全。链接的github 问题中的示例:

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

您可以使用以下static virtual方法“修复”它:

public interface IFoo
{
    public static virtual string Bar => throw new Exception();
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是现在实现者不需要实现该方法:

public class Foo1 : IFoo // valid now
{
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用标记接口(尽管它可以被视为反模式):

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

var fooList = new List<IAmActuallyFoo>();
Run Code Online (Sandbox Code Playgroud)

聚苯乙烯

请注意,无论如何这List<IFoo> fooList = new List<Foo>();是无效的,因为类不支持方差(请参阅文档这个和/或这个答案)。