声明重载运算符时有几个错误。 重载运算符也称为用户定义的运算符
- CS0056: 可访问性不一致:返回类型"type"的可访问性低于运算符"operator"
- CS0057:不一致的可访问性:参数类型“type”的可访问性低于运算符“operator”
- CS0215: 运算符 True 或 False 的返回类型必须为布尔值
- CS0216: 运算符“operator”需要同时定义匹配的运算符“missing_operator”
- CS0217: 为了作为短路运算符适用,用户定义的逻辑运算符('operator')必须具有与其 2 个参数的类型相同的返回类型。
- CS0218: 类型('type')必须包含运算符 true 和运算符 false 的声明
-
CS0448:运算符
++或--的返回类型必须为包含类型或派生自包含类型 - CS0552: “转换例程”:用户定义的到/从接口转换
- CS0553: “转换例程”:用户定义的到基类/从基类转换
- CS0554: “转换例程”:用户定义的到派生类/从派生类转换
- CS0555: 用户定义的运算符不能接受封闭类型的对象并转换为封闭类型的对象
- CS0556: 用户定义的转换必须转换为封闭类型或从封闭类型转换
- CS0557: 类型中重复用户定义转换
- CS0558: 用户定义的运算符必须声明为静态和公共运算符
-
CS0559:
++或--运算符的参数类型必须是包含类型 - CS0562: 一元运算符的参数必须是包含类型
- CS0563: 二进制运算符的参数之一必须是包含类型
- CS0564: 重载移位运算符的第一个作数必须与包含类型具有相同的类型,并且第二个作数的类型必须为 int
- CS0567: 接口不能包含运算符
- CS0590: 用户定义的运算符无法返回 void
-
CS0660: 类型定义
operator ==或operator !=未重写Object.Equals(object o) -
CS0661:类型定义了
operator ==或operator !=但未重写Object.GetHashCode() - CS0715: 静态类不能包含用户定义的运算符
- CS1037: 应有可重载运算符
- CS1553: 声明无效;应使用“modifier 运算符 <dest-type> (...)”而不是当前形式
- CS8930:用户定义的 运算符的显式实现必须是静态的。
- CS8931: 显式实现必须声明为公共实现,才能在类型中实现接口成员。
- CS9023:操作符无法设为检查状态。
- CS9024: 运算符无法标记为不受检查。
- CS9025: 操作员需要声明匹配的非检查版本。
- CS9308: 用户定义的运算符必须声明为公共运算符。
- CS9310: 此运算符的返回类型必须为 void。
- CS9311: 类型不实现接口成员。类型无法实现成员,因为它们之一不是运算符。
- CS9312: 类型无法替代继承的成员,因为其中一个成员不是操作员。
- CS9313: 重载复合赋值运算符采用一个参数。
以下部分提供了常见问题的示例以及如何解决这些问题。
操作员签名要求
-
CS0448:
++或--运算符的返回类型必须是包含类型或派生自包含类型的类型。 -
CS0559:
++或--运算符的参数类型必须是其所属类型。 - CS0562: 一元运算符的参数必须是包含类型。
- CS0563: 二进制运算符的参数之一必须是包含类型。
- CS0564: 重载移位运算符的第一个操作数必须与包含类型相同,并且第二个操作数的类型必须为 int。
- CS0567: 接口不能包含运算符。
- CS0590: 用户定义的运算符不能返回 void。
- CS9310: 此运算符的返回类型必须为 void。
当运算符声明不遵循所需的签名规则时,会发生这些错误。 每个运算符类型都有参数类型和返回类型的特定要求。
重要
静态二进制运算符和相应的实例复合赋值运算符的签名要求不同。 确保签名与所需的声明匹配。
有关详细信息,请参阅 运算符重载。 以下示例演示了以下错误:
class C1
{
public static int operator ++(C1 c) => 0; // CS0448
public static C1 operator --(C1 c) => null; // OK
}
public class C2
{
public static implicit operator int(C2 x) => 0;
public static implicit operator C2(int x) => new C2();
public static int operator ++(int aa) => 0; // CS0559
}
public class C3
{
public static implicit operator int(C3 x) => 0;
public static implicit operator C3(int x) => null;
public static C3 operator +(int aa) => 0; // CS0562
}
public class C4
{
public static implicit operator int(C4 x) => 0;
public static implicit operator C4(int x) => null;
public static int operator +(int aa, int bb) => 0; // CS0563
}
class C5
{
// To correct, change second operand to int, like so:
// public static int operator << (C c1, int c2)
public static int operator <<(C5 c1, C5 c2) => 0; // CS0564
}
interface IA
{
int operator +(int aa, int bb); // CS0567
}
public class C6
{
public static void operator +(C6 A1, C6 A2) { } // CS0590
}
若要修复这些错误,请确保操作员声明遵循重载的特定运算符类型的签名要求。
运算符声明要求
- CS0558: 用户定义的运算符必须声明为静态和公共运算符。
- CS0715: 静态类不能包含用户定义的运算符。
- CS1037: 需要可重载的运算符。
- CS1553:声明无效,应使用“modifier 运算符 <dest-type> (...”。
- CS8930:用户定义的 运算符的显式实现必须是静态的。
- CS8931: 显式实现必须声明为公共实现,才能在类型中实现接口成员。
- CS9308: 用户定义的运算符必须声明为公共运算符。
当运算符声明不使用所需的修饰符或语法时,会发生这些错误。 大多数用户定义的运算符必须同时具有 static , public并且转换运算符需要特定的语法。 有关详细信息,请参阅 运算符重载 和 用户定义的转换运算符。 以下代码演示了以下错误:
public class C
{
static implicit operator int(C aa) => 0; // CS0558, add public
}
public static class C1
{
public static int operator +(C1 c) => 0; // CS0715
}
class C2
{
public static int implicit operator (C2 f) => 6; // CS1553
}
若要修复这些错误,请确保运算符声明包括必需 static 和 public 修饰符,遵循转换运算符的正确语法,并且不要在静态类中声明运算符。
可访问性不一致
- CS0056:不一致的可访问性:返回类型“type”的可访问性低于运算符“operator”的可访问性。
- CS0057: 不一致性:参数类型“type”的可访问性低于运算符“operator”。
当你声明一个公共运算符并且其返回类型或参数类型的可访问性比运算符本身更为严格时,就会出现这些错误。 所有公共构造都必须对其参数和返回值使用可公开访问的类型。 有关详细信息,请参阅 访问修饰符。
以下代码片段演示了以下错误:
class C { }
public class C2
{
public static implicit operator C(C2 a) => new C(); // CS0056
}
public class C3
{
public static implicit operator C3(C c) => new C3(); // CS0057
}
若要解决这些错误,请确保公共运算符声明中使用的所有类型也可供公开访问。
用户定义的转换限制
- CS0552: 用户定义到/从接口转换。
- CS0553: 用户定义的到/从基类的转换。
- CS0554: 从派生类到/从派生类进行用户定义的转换。
- CS0555: 用户定义的运算符不能采用封闭类型的对象并转换为封闭类型的对象。
- CS0556: 用户定义的转换必须转换为封闭类型或从封闭类型转换。
- CS0557: 类型中重复用户定义转换。
尝试创建无效的用户定义转换运算符时,会发生这些错误。 转换运算符在可以互相转换的类型之间存在特定的限制。 有关详细信息,请参阅用户定义转换运算符。 以下代码演示了前面的错误:
public interface I
{
}
public class C
{
public static implicit operator I(C aa) => default;// CS0552
}
public class B
{
}
public class D : B
{
public static implicit operator B(D aa) => new B();// CS0553
}
public class B2
{
// delete the conversion routine to resolve CS0554
public static implicit operator B2(D2 d) => new B2();// CS0554
}
public class D2 : B2 { }
public class C2
{
public static implicit operator C2(C2 aa) => new C2(); // CS0555
}
public class C3
{
public static implicit operator int(byte aa) => 0; // CS0556
}
public class C4
{
public static implicit operator int(C4 aa) => 0;
// CS0557, delete duplicate
public static explicit operator int(C4 aa) => 0;
}
若要修复这些错误,请删除无效的转换运算符或重构类型层次结构,以避免受限的转换模式。
布尔运算符和短路运算符
- CS0215: 运算符 true 或 false 的返回类型必须为布尔值。
- CS0216: 该运算符需要同时定义匹配的运算符。
- CS0217: 为了作为短路运算符适用,用户定义的逻辑运算符必须与其 2 个参数的类型具有相同的返回类型。
- CS0218: 类型必须包含运算符 true 和运算符 false 的声明。
错误地定义逻辑运算符时,会发生这些错误。 某些运算符必须成对定义,短路运算符具有特定的签名要求。 有关详细信息,请参阅 true 和 false 运算符、 布尔逻辑运算符和 用户定义的条件逻辑运算符。 以下代码演示了以下错误:
class C
{
public static int operator true(C c) => 0; // CS0215
public static int operator false(C c) => 0; // CS0215
}
class C2
{
public static bool operator ==(C2 left, C2 right) => left.Equals(right); // CS0216
public override bool Equals(object? o) => base.Equals(o);
public override int GetHashCode() => base.GetHashCode();
}
public class C3
{
public static bool operator true(C3 f) => false;
public static bool operator false(C3 f) => true;
public static implicit operator int(C3 x) => 0;
public static int operator &(C3 f1, C3 f2) => new C3(); // CS0217
}
public class C4
{
public static implicit operator int(C4 x) => 0;
public static C4 operator &(C4 f1, C4 f2) => new C4();
public static void Main()
{
C4 f = new C4();
int i = f && f; // CS0218, requires operators true and false
}
}
若要修复这些错误,请确保定义所需的配对运算符,并遵循逻辑运算符的正确签名模式。
选中的运算符
- CS9023: 无法检查操作员
- CS9024:运算符无法设为未检查状态
- CS9025: 已检查的操作员需要声明匹配的非检查版本
当错误地将 checked 或 unchecked 关键字用于运算符声明时,会发生这些错误。 并非所有运算符都支持已检查/未检查的变体,在支持这些变体时,必须满足某些要求。 有关详细信息,请参阅 算术运算符 和 用户定义的检查运算符。
若要修复这些错误,请从不支持它的运算符中删除 checked 或 unchecked 关键字,或确保在需要时同时提供已检查版本和非检查版本。
接口和继承要求
- CS9311: 类型不实现接口成员。类型无法实现成员,因为其中一个不是运算符
- CS9312: 类型无法替代继承的成员,因为其中一个不是操作员
- CS9313: 重载复合赋值运算符接受一个参数
当运算符声明与接口实现或继承关系不匹配时,会发生这些错误。 运算符具有接口实现和重写的特定规则。 有关详细信息,请参阅 运算符重载 和 接口。
若要修复这些错误,请确保运算符声明正确匹配接口要求,并遵循运算符重写和复合赋值运算符的规则。
相等运算符
- CS0660: 类型定义运算符 == 或运算符 != 但不会重写 Object.Equals(object o)
- CS0661: 类型定义运算符 == 或运算符 != 但不会重写 Object.GetHashCode()
定义相等运算符或不相等运算符时,如果未重写相应的方法Object,则会出现这些警告。 定义自定义相等比较时,还应重写 Object.Equals 和 Object.GetHashCode 以确保行为一致。 有关详细信息,请参阅如何为类型定义值相等和相等运算符。
若要修复这些警告,请在定义自定义相等运算符时,同时重写Equals和GetHashCode。