编译器为接口中静态抽象或虚拟成员的无效声明生成以下错误:
- CS8920: 接口不能用作类型参数。静态成员在接口中没有最具体的实现。
- CS8921: 一元运算符的参数必须是包含类型,或其类型参数必须约束为该类型。
-
CS8922:
++或--运算符的参数类型必须是包含类型,或是对其进行约束的类型参数。 -
CS8923:
++或--运算符的返回类型必须与参数类型匹配,或者派生自参数类型,或者是包含类型的与其受约束的类型参数,除非参数类型是一个不同的类型参数。 - CS8924: 二进制运算符的参数之一必须是包含类型,或其类型参数受约束。
- CS8925:重载移位运算符的第一个操作数必须与包含类型相同,或者其类型参数被约束为相同的类型
- CS8926: 静态虚拟或抽象接口成员只能在类型参数上访问。
- CS8928: 类型不实现静态接口成员。该方法无法实现接口成员,因为它不是静态的。
- CS8930: 必须声明用户定义的运算符的显式实现
- CS8931:接口中的用户定义转换必须转换为或从封闭类型的类型参数进行转换,而该类型参数受限于封闭类型
- CS8932: “UnmanagedCallersOnly”方法无法在类型中实现接口成员
- CS9044: 类型不实现接口成员。方法无法隐式实现不可访问的成员。
- CS9046: 接口中声明的相等运算符的参数之一必须是受接口约束的类型参数
这些错误发生在代码的三个位置:
接口声明中的错误
声明具有 static abstract 或 static virtual 成员的接口时,可能会遇到以下错误:
- CS8921: 一元运算符的参数必须是包含类型,或其类型参数必须被约束为包含类型。
-
CS8922:
++或--运算符的参数类型必须是包含类型,或其类型参数受到该类型的约束。 -
CS8923:
++或--运算符的返回类型必须与参数类型匹配,或者派生自参数类型中,或者是包含类型中约束于它的类型参数,除非参数类型是不同的类型参数。 - CS8924: 二进制运算符的参数之一必须是包含类型,或其类型参数受约束。
- CS8925:重载移位运算符的第一个作数必须与包含类型相同,或其类型参数已约束为该类型
- CS8931:接口中的用户定义转换必须从封闭类型上类型参数转换或转换为封闭类型
- CS9046: 接口中声明的相等运算符的参数之一必须是受接口约束的类型参数
对于接口中声明的一元运算符,请确保参数是接口类型本身或受T约束实现接口的类型参数T(CS8921)。 此约束可确保运算符只能应用于实现接口的类型,使编译器能够在编译时解析正确的实现。
对于增量(++)和递减(--)运算符,请验证参数是否遵循与其他一元运算符(CS8922)相同的规则。 此外,返回类型必须与参数类型匹配、派生自该类型,或者是受接口约束的接口类型参数(CS8923)。 这些规则确保递增和递减操作返回的类型能够分配给原始变量。
对于二进制运算符,至少两个参数中的一个必须是包含接口类型或受约束以实现接口的类型参数(CS8924)。 此要求允许其他参数为任意类型,从而启用运算符,例如 T operator +(T left, int right) 在泛型数学方案中。
对于 Shift 运算符(<< 和 >>),第一个操作数必须是包含类型或其约束类型参数(CS8925)。 第二个操作数遵循标准移位运算符规则,通常为int。
对于用户定义的转换运算符,转换必须涉及限制为封闭接口类型(CS8931)的类型参数。 不能在接口中定义任意类型之间的转换;转换必须与实现接口的类型相关。
对于相等()和不相等(==!=)运算符,至少一个参数必须是受接口约束的类型参数,而不仅仅是接口类型本身(CS9046)。 这种更严格的相等运算符要求可确保在通过接口比较实例时正确类型安全性。
有关接口中运算符声明的规则的详细信息,请参阅 接口中的静态抽象成员。 有关实现这些模式的实用指南,请参阅 探索静态抽象接口成员。
实现接口声明的类型中的错误
定义一个实现包含 static abstract 或 static virtual 方法的接口的类型时,可能会遇到以下错误:
- CS8928: 类型不实现静态接口成员。该方法无法实现接口成员,因为它不是静态的。
- CS8930: 必须声明用户定义的运算符的显式实现
- CS8932: “UnmanagedCallersOnly”方法无法在类型中实现接口成员
- CS9044: 类型不实现接口成员。方法无法隐式实现不可访问的成员。
实现静态抽象或静态虚拟接口成员时,请使用 static 修饰符(CS8928)声明实现方法。 与实例方法实现的实例接口成员不同,静态抽象成员需要静态实现,因为运行时在类型本身而不是实例上调用它们。
对于接口中用户定义的运算符的显式实现,请在实现中包括 static 修饰符(CS8930)。 运算符的显式接口实现遵循与隐式实现相同的静态要求。
System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute从实现接口成员的任何方法中删除属性(CS8932)。 使用此属性标记的方法只能从非托管代码调用,并且不能参与接口实现,因为运行时需要通过接口调度机制调用它们。
如果实现方法的可访问性比接口成员(例如实现public接口成员的private或internal方法)更具限制性,请使用显式接口实现语法而非隐式实现(CS9044)。 隐式实现要求实现成员至少可以像实现的接口成员一样易于访问。
有关实现接口成员的详细信息,请参阅 接口 和 显式接口实现。
调用静态抽象接口成员时出错
当您尝试调用定义为某个接口的 static abstract 或 static virtual 成员时,可能会看到以下错误:
- CS8920: 接口不能用作类型参数。静态成员在接口中没有最具体的实现。
- CS8926: 静态虚拟或抽象接口成员只能在类型参数上访问。
将具有静态抽象成员的接口用作类型参数时,请确保所有静态抽象成员都具有可用的最具体的实现(CS8920)。 当编译器无法确定要使用的实现时,你会看到此错误,这通常是因为多个接口层次结构提供冲突的默认实现或不存在任何实现。
通过受约束实现接口的类型参数(而不是直接通过接口类型(CS8926)访问静态抽象或静态虚拟接口成员。 例如,使用T.MemberName,在T受where T : IMyInterface限制的情况下,而不是 IMyInterface.MemberName。 编译器需要具体类型来解析要调用的实现,约束类型参数通过泛型专用化在编译时提供具体类型。
有关访问静态抽象成员的详细信息,请参阅 接口中的静态抽象成员。