解决与实现接口的成员相关的错误和警告

本文介绍以下编译器错误:

  • CS0071事件的显式接口实现必须使用事件访问器语法。
  • CS0106修饰符对此项无效。
  • CS0277成员未实现接口成员,因为它不是公开的。
  • CS0425方法的类型参数的约束必须与接口方法的类型参数的约束相匹配。请考虑改用显式接口实现。
  • CS0460重写和显式接口实现方法的约束继承自基方法,因此不能直接指定它们,除非是“类”或“结构”约束。
  • CS0470方法无法实现类型的接口访问器。使用显式接口实现。
  • CS0473显式接口实现“方法名称”与多个接口成员匹配。实际选择哪个接口成员依赖于实现。请考虑改用非显式实现。
  • CS0531接口成员不能有定义。
  • CS0535成员没有实现接口成员。
  • CS0538显式接口声明中的成员不是接口。
  • CS0539在可实现的接口成员中找不到显式接口声明中的成员
  • CS0540包含类型不实现接口成员。
  • CS0541显式接口声明只能在类、记录、结构或接口中声明。
  • CS0550成员添加的访问器在接口成员中未找到。
  • CS0551显式接口实现缺少访问器。
  • CS0630成员无法实现接口成员,因为它具有__arglist参数。
  • CS0686访问器无法实现接口成员。使用显式接口实现。
  • CS0736成员不实现实例接口成员。它无法实现接口成员,因为它是静态的。
  • CS0737成员不实现接口成员。它无法实现接口成员,因为它不是公共成员。
  • CS0738成员不实现接口成员。它不能因为没有匹配的返回类型。
  • CS8705接口成员没有最具体的实现。两个成员都不是最具体的。
  • CS8854成员不实现接口成员。
  • CS9333参数类型必须与实现的成员匹配。
  • CS9334返回类型必须与实现的成员匹配。

接口声明和语法

在声明显式接口实现时,以下错误与正确的语法和结构相关:

  • CS0071事件的显式接口实现必须使用事件访问器语法。
  • CS0106修饰符对此项无效。
  • CS0531接口成员不能有定义。
  • CS0538显式接口声明中的成员不是接口。
  • CS0541显式接口声明只能在类、记录、结构或接口中声明。

可以使用以下技术更正这些错误:

  • 显式实现接口事件时,必须手动提供 addremove 事件访问器(CS0071)。 编译器不会为显式接口实现自动生成这些访问器,因此必须显式定义它们以指定事件的存储和管理方式。
  • public从显式接口实现中删除修饰符(CS0106)。 当通过接口类型进行访问时,显式接口实现是隐式公开的,这使得 public 关键字冗余且在此上下文中不允许。
  • abstract从显式接口实现中删除修饰符(CS0106)。 显式接口实现提供实际实现,不能标记为抽象,因为它们无法在派生类中重写。
  • 从接口成员声明中删除方法主体,或将实现移动到实现接口的类或结构(CS0531)。 在 C# 8.0 之前,接口成员不能包含实现;从 C# 8.0 开始,可以使用特定语法提供 默认接口方法
  • 验证显式接口声明中指定的类型是否为实际接口类型(CS0538)。 只能在显式接口实现语法中使用接口类型;尝试使用类或其他非接口类型违反了显式实现规则。
  • 将显式接口声明移动到在其基列表中声明接口的类或结构(CS0541)。 显式接口实现必须出现在类或结构类型的正文中,并且无法在命名空间级别或其他上下文中声明。

有关详细信息,请参阅 接口显式接口实现以及如何 实现接口事件

返回类型和签名

当实现方法的签名与接口成员声明不匹配时,会发生以下错误:

  • CS0738成员不实现接口成员。因为其没有匹配的返回类型,所以无法实现。
  • CS8854成员不实现接口成员。
  • CS9333参数类型必须与实现的成员匹配。
  • CS9334返回类型必须与实现的成员匹配。

可以使用以下技术更正这些错误:

  • 更改实现方法的返回类型,以与接口成员(CS0738,CS9334)中声明的返回类型完全匹配。 实现的签名必须与接口声明完全匹配,因为方法签名是确定要实现哪个接口成员的协定的一部分。
  • 确保实现方法中的参数类型与接口成员(CS9333)中声明的参数类型完全匹配。 每个参数必须与接口声明中指定的相同位置具有相同的类型,因为参数类型是编译器用来将实现与接口成员匹配的方法签名的基本组件。
  • 当接口属性声明一个init设置器(CS8854)时,请向实现属性添加一个init访问器。 关键字 init 允许在对象构造期间初始化属性,同时防止修改之后,实现属性必须提供相同的仅初始化行为才能满足接口协定。

有关详细信息,请参阅 接口属性init-only setter

缺少或不完整的实现

当类无法完全实现接口或实现与接口协定不匹配的成员时,会发生以下错误:

  • CS0535成员不实现接口成员。
  • CS0550成员添加了接口中不存在的访问器。
  • CS0551显式接口实现缺少存取器。

可以使用以下技术更正这些错误:

  • 为接口中声明的每个成员提供实现,或将该类型声明为 abstractCS0535)。 必须实现所有成员以满足接口要求。
  • 从接口属性(CS0550)中未声明的实现属性中删除任何访问器。 实现属性只能包含接口定义中显式声明的访问器,确保实现不会添加超出接口协定指定的功能。
  • 将所有必需的访问器添加到显式接口实现,以匹配接口声明(CS0551)。 接口中声明的每个访问器必须在实现中具有匹配签名的对应访问器,因为实现必须满足接口定义的完整访问器协定。

有关详细信息,请参阅 接口属性

成员匹配和解析

尝试实现接口中不存在的接口成员或包含类型未声明接口时,会发生以下错误:

  • CS0539在可实现的接口成员中找不到显式接口声明中的成员
  • CS0540包含类型不实现接口成员。

可以使用以下技术更正这些错误:

  • 验证显式接口实现中的成员名称和签名是否与接口中声明的成员完全匹配,或删除不正确的实现(CS0539)。 尝试实现的成员实际上必须存在于具有匹配名称、返回类型和参数类型的接口定义中,因为显式接口实现需要与接口协定精确对应。
  • 将接口添加到类或结构的基列表,或删除显式接口实现(CS0540)。 类型只能显式实现它在继承列表中声明的接口成员,因此实现类型必须建立接口关系,然后才能提供显式实现。

有关详细信息,请参阅 接口显式接口实现

泛型类型约束

使用类型参数约束实现泛型接口方法时,会发生以下错误:

  • CS0425方法的类型参数的约束必须与接口方法的类型参数的约束相匹配。请考虑改用显式接口实现。
  • CS0460重写和显式接口实现方法的约束继承自基方法,因此不能直接指定它们,除非是“类”或“结构”约束。

可以使用以下技术更正这些错误:

  • where确保实现方法中的子句与接口方法声明相同,或与约束(CS0425)的语义含义匹配。 实现中的类型参数约束必须与接口或基方法中定义的类型参数约束匹配。
  • 从重写和显式接口实现方法中删除显式约束声明(CS0460)。 重写方法从基或接口方法自动继承其约束,因此重新声明这些约束是冗余的,不允许,但 C# 8 及更高版本中允许的特定情况除外。
  • 在使用 C# 9 或更高版本(CS0460)时,应用default 类型约束,以解决重写和显式接口实现中的可空引用类型歧义。 约束继承规则的这个例外允许您明确指定默认约束,以消除可空注释上下文的歧义。
  • 使用 C# 8 或更高版本启用可为 null 的引用类型批注(where T : class)时,显式指定where T : struct约束替代和显式接口实现方法。 允许这些特定约束支持对受引用或值类型约束的类型参数进行可为 null 的引用类型分析。

有关详细信息,请参阅类型参数的约束接口可空引用类型

方法可见性和修饰符

实现具有不正确辅助功能或修饰符的接口方法时,会发生以下错误:

  • CS0736成员不实现实例接口成员。它无法实现接口成员,因为它是静态的。
  • CS0737此成员不实现接口成员。它无法实现接口成员,因为它不是公共的。

可以使用以下技术更正这些错误:

  • static从实现接口成员的方法声明中删除修饰符(CS0736)。 在 C# 10 之前,接口成员是实例成员,而不是静态成员。
  • public 访问修饰符添加到实现接口成员的方法(CS0737)。 所有接口成员都是 public 隐式的,因为接口定义了公共行为的协定,因此实现方法还必须具有可通过接口引用访问的公共可访问性。

有关详细信息,请参阅 接口访问修饰符

访问器实现和冲突

使用具有可见性问题或命名冲突的访问器方法实现接口属性或事件时,会发生以下错误:

  • CS0277成员不实现接口成员,因为它不是公共成员。
  • CS0470方法无法实现类型的接口访问器。使用显式接口实现。
  • CS0686访问器无法实现接口成员。使用显式接口实现。

可以使用以下技术更正这些错误:

  • 从属性访问器中删除任何访问修饰符,这些访问修饰符将可见性限制为低于 public,或者添加 public 修饰符(如果缺少)。CS0277 所有接口成员都是隐式 public的,因此实现访问器还必须具有公共可访问性才能满足接口协定,并且可通过接口类型进行访问。
  • 使用显式接口实现(CS0470)将带有类似访问器名称(如get_PropertyName)的方法替换为合适的属性语法。 编译器在内部为属性生成访问器方法;试图手动创建与这些保留名称相同的方法会与属性实现机制发生冲突。
  • 当接口包含与自动生成的访问器方法(CS0686)匹配的方法名称时,使用显式接口实现语法来解决命名冲突。 编译器自动为属性生成诸如get_Propertyset_Property等方法,并为事件生成add_Eventremove_Event等方法,因此,如果接口声明了这些确切名称的方法,则需要显式实现以消除接口方法和编译器生成的访问器之间的歧义。

有关详细信息,请参阅 接口属性事件

不明确和冲突的实现

当编译器无法确定要使用的接口实现时,会发生以下错误:

  • CS0473显式接口实现“方法名称”与多个接口成员匹配。实际选择哪个接口成员依赖于实现。请考虑改用非显式实现。
  • CS8705接口成员“member”没有最具体的实现。两者都不是最具体的。

可以使用以下技术更正这些错误:

  • 消除显式接口实现,而是对两个接口方法(CS0473)使用单个隐式公共实现。 当一个泛型方法具有与非泛型方法相同的签名(例如在实现 ITest<int> 时,TestMethod(int)TestMethod(T) 变得相同时),公共语言基础结构的元数据系统无法明确判断哪个接口成员绑定到哪个实现槽,因此,通过隐式实现,一个方法可以同时满足这两个接口的要求。
  • 在实现类或结构中提供显式实现,用于解析多个默认实现(CS8705)之间的歧义性。 此错误通常发生在钻石继承模式中,其中一个类实现多个接口,每个接口都为同一成员提供默认实现。 编译器需要您显式指定要使用的实现方案,或者提供您自己的实现方案。
  • 重构接口层次结构以避免钻石继承冲突,其中多个接口为同一成员(CS8705)提供默认实现。 通过重新设计接口关系或将默认实现合并到单个接口中,可以消除阻止编译器确定最具体实现的歧义性。

有关详细信息,请参阅 接口默认接口方法

特殊实现限制

使用与接口实现不兼容的特殊参数类型时,会发生以下错误:

  • CS0630成员无法实现接口成员,因为它具有__arglist参数。

可以使用以下技术更正此错误:

  • __arglist从实现方法中删除参数(CS0630)。 关键字 __arglist 允许方法以非托管方式接受可变数量的参数,但此功能与接口实现不兼容,因为接口协定需要可预测的类型安全签名,这些签名可以在编译时进行验证。
  • __arglist 参数替换为 params 可变长度参数列表的数组参数(CS0630)。 与上述不同 __arglist,该 params 关键字提供了一种类型安全机制,用于接受与接口实现完全兼容的可变数量的参数,并维护接口所需的编译时类型安全性。

有关详细信息,请参阅 接口参数关键字