我有以下使用 .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# 的限制。不过,我可能是错的,所以现在我问:有没有办法解决这个问题,或者至少绕过这个限制?
我猜想,无论出于什么原因,这是 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>();是无效的,因为类不支持方差(请参阅文档,这个和/或这个答案)。