C# 11 - 通过抽象类在接口中静态抽象成员?

问题描述 投票:0回答:1

C# 11 引入了接口中的静态抽象成员

但从我正在试验的情况来看,它只会强制“直接子级”实现这些“static abstract”成员。该

static abstract
修饰符不能在
abstract class
中使用。
我正在尝试做的一个示例,但无法编译:

public interface IMyInterface { public static abstract void DoSomething(); } public abstract class MyAbstractClass : IMyInterface { public static abstract void DoSomething(); //Error: Overridable method cannot be static } public class MyClass : MyAbstractClass { public static override void DoSomething() => Console.Log("Hello, World!"); }

但是它们之间没有 
abstract class

MyClass
确实可以正常编译:
public class MyClass : IMyInterface
{
    public static void DoSomething() => Console.Log("Hello, World!");
}

我错过了什么吗?为什么会这样呢?

我相信我已经知道我的案例的解决方法,但这种方式不会强制
MyAbstractClass

的每个孩子都实现

IMyInterface
,就像我们对常规接口成员所做的那样。
public interface IMyInterface
{
    public static abstract void DoSomething();
}

public abstract class MyAbstractClass
{
    
}

public class MyClass : MyAbstractClass, IMyInterface
{
    public static void DoSomething() => Console.Log("Hello, World!");
}

	
c# inheritance interface abstract-class c#-11.0
1个回答
0
投票
但是根据我的实验,它只会强制直接子级实现这些静态抽象成员。该
static abstract

修饰符不能在

abstract class
中使用。

正确。

我错过了什么吗?为什么会这样呢?

这是设计使然。
  • ...因为没有理由向
  • static abstract
  • 成员介绍
    class
    类型。
    ...因为这样的成员永远无法使用。
  • ...因为
  • static
  • 成员不是通过虚拟调用(vtable 查找)调用的,因为没有
    this
    引用可从中获取 vtable 引用。
    ...因为它是
  • static
  • 
    
  • 但是,
interface

类型

do
支持static abstract成员,但这只是因为它们在泛型方法约束的上下文中很有用,因为它允许泛型代码为非虚拟的调用站点指定方法: JIT/运行时实例化一个通用方法,它发出
static
方法调用,而不是基于 vtable 的调用。 (对于 Swift 用户来说,这有点像

protocol

类型与 C# 或 Java interface 类型不同,因为

protocol
支持对值类型的非装箱调用,而(在非泛型中)方法)C#
interface
类型始终被视为引用类型,但无论如何)。

我相信我已经知道我的案例的解决方法,但这种方式并不能强迫
MyAbstractClass

的每个孩子都实施
IMyInterface


听起来你正在使用接口类型作为一种

linter

,以保证一组class类型都遵循某种通用的编码约定并实现一些通用的成员集(在此情况下,static成员),即使您从未在程序中的任何地方使用该

interface
- 但这不是 C# 中
interface
类型的用途。

    
	

© www.soinside.com 2019 - 2024. All rights reserved.