本文涵蓋下列編譯器錯誤:
- 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: 宣告無效,請使用 '修飾子 <dest-type> (...' 代替
- CS8930: 使用者定義運算子的明確實作必須是靜態的。
- CS8931:明確實作必須宣告為公用,才能在類型中實作介面成員。
- CS9023: 無法勾選運算子。
- CS9024: 運算子不能設為無檢查的。
- CS9025: 運算子也需要宣告相符的未核取版本。
- CS9308: 使用者定義的運算子必須宣告為公用。
- CS9310: 此運算子的傳回類型必須是 void。
- CS9311: 類型未實作介面成員。類型無法實作成員,因為其中一個不是運算子。
- CS9312: 類型無法覆寫繼承的成員,因為其中一個不是運算子。
- CS9313: 多載的複合指派運算子會採用一個參數。
- CS9340:運算子無法套用至運算元。會顯示最接近的無效候選。
- CS9341: 運算子無法套用至運算元。將顯示最接近的不適用選項。
- CS9342: 下列成員函式之間的運算元解析具有歧義性。
操作員簽章需求
-
CS0448:運算子的
++或--傳回類型必須是包含類型,或衍生自包含類型。 -
CS0559:
++或--運算子的參數類型必須是包含類型。 - CS0562: 一元運算子的參數必須是包含類型。
- CS0563: 二進位運算子的其中一個參數必須是包含類型。
- CS0564: 多載移位運算子的第一個運算元必須具有與包含類型相同的類型,而第二個運算元的類型必須是 int。
- CS0567: 介面不能包含運算子。
- CS0590: 使用者定義的運算子無法傳回 void。
- CS9310: 此運算子的傳回類型必須是 void。
- CS9340: 運算子無法套用至運算元。會顯示最接近的不適用候選。
- CS9341:運算子無法套用至運算元。會顯示最接近但不適用的候選項目。
- CS9342:下列成員之間的運算子解析不明確。
若要宣告具有正確簽章的運算子,請遵循特定運算子類型的這些需求。 如需相關資訊,請參閱 運算子多載。
- 傳回包含型別(或衍生型別)來自
++和--運算子(CS0448)。 - 使用包含類型作為
++和--運算子的參數(CS0559)。 - 使用包含類型作為一元運算子的參數 (CS0562) 。
- 在二進位運算子中將包含類型作為至少一個參數進行包含 (CS0563)。
- 使用包含類型作為第一個參數,以及
int作為移位運算子的第二個參數 (CS0564)。 - 請勿在介面中宣告運算子 (CS0567)。 介面不能包含運算子實作。
- 從大部分運算子傳回非 void 類型 (CS0590) ,但需要
void傳回的特定運算子除外 (CS9310) 。 - 提供接受正確參數類型的運算子多載,以避免解析失敗 (CS9340、 CS9341) 。
- 使用顯式類型轉換或提供更具體的多載來消解運算元呼叫的歧義 (CS9342)。
這很重要
靜態二進位運算子和對應的實例複合賦值運算子的簽章需求是不同的。 請確定簽名與您想要的聲明相符。
下列範例示範簽章錯誤:
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: 宣告無效; 請改用 '修飾運算子 <dest-type> (...'。
- CS8930: 使用者定義運算子的明確實作必須是靜態的。
- CS8931: 顯式實作必須宣告為公共,才能在類型中實作介面中的成員。
- CS9308: 使用者定義的運算子必須宣告為公用。
若要正確宣告運算子,請遵循這些修飾子和包含類型的要求。 如需相關資訊,請參閱 運算子多載 和 使用者定義的轉換運算子。
- 同時宣告具有
static和public修飾元的運算子(CS0558、CS9308)。 - 請勿在靜態類別中宣告運算子 (CS0715)。 使用常規類別或結構。
- 使用有效、可多載的運算子符號 (CS1037)。
- 請遵循轉換運算子的正確語法:
public static implicit/explicit operator <dest-type>(<source-type> parameter)(CS1553)。 - 請確定運算子的明確介面實作是
static(CS8930) 和public(CS8931)。
下列範例示範宣告錯誤:
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
}
不一致的可訪問性
- CS0056: 協助工具不一致:傳回類型 'type' 比運算子 'operator' 更難存取。
- CS0057: 可存取性不一致:參數類型 'type' 的存取性較低於運算子 'operator'。
若要確保運算子宣告中的可存取性一致,請將公開運算子中使用的所有類型設為公開存取。 如需詳細資訊,請參閱 存取修飾元。
- 請確定傳回類型至少具有與運算子相同的可存取性 (CS0056) 。
- 請確保參數類型的存取層級至少與操作員相同 (CS0057)。
當您宣告 public 運算子時,所有用作參數或傳回值的類型也必須可公開存取。
下列範例示範無障礙錯誤:
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: 類型中重複的使用者定義轉換。
若要建立有效的使用者定義轉換運算子,請遵循下列限制。 如需詳細資訊,請參閱使用者定義轉換運算子。
- 請勿定義介面之間的轉換 (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 的傳回類型必須是 bool。
- CS0216: 運算子也需要定義相符的運算子。
- CS0217: 為了套用為短路運算子,使用者定義的邏輯運算子必須具有與其 2 個參數類型相同的傳回類型。
- CS0218: 類型必須包含運算子 true 和運算子 false 的宣告。
若要正確定義邏輯運算子,請遵循這些配對和簽章需求。 如需詳細資訊,請參閱 true 和 false 運算子、 布林邏輯運算子和 使用者定義的條件式邏輯運算子。
從 和 (CS0215)返回。 - 定義必要的配對運算子 (CS0216):
-
operator ==需要operator != -
operator <需要operator > -
operator <=需要operator >= -
operator true需要operator false
-
- 將傳回類型與使用自訂類型 (
&) 的短路運算子 (|和 ) 的參數類型相符。 - 當在布林上下文中使用自訂類型時,實作
operator true和operator false,例如&&和||(CS0218)。
下列範例示範邏輯運算子錯誤:
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關鍵字僅套用至支援的算術運算子:+、-、*、/、++、--和明確運算轉換(CS9023、CS9024)。 - 宣告已核取的運算子時,提供已核取和未核取的版本 (CS9025)。 編譯器需要兩者來處理不同的內容。
介面和繼承需求
- CS9311: 類型不會實作介面成員。類型無法實作成員,因為其中一個不是運算子
- CS9312:型別無法覆蓋繼承的成員,因為其中一個不是運算子
- CS9313: 多載的複合指派運算子採用一個參數
若要正確實作和覆寫運算子,請遵循下列要求。 如需詳細資訊,請參閱 運算子多載 和 介面。
- 請確定運算子宣告符合介面成員的簽章和類型 (CS9311) 。 運算子無法實現非運算子成員。
- 確認要覆寫的繼承成員也是運算子 (CS9312) 。 運算子無法覆寫非運算子成員。
- 使用一個參數宣告複合指派運算子 (CS9313) 。 左運算元隱含
this。
等號比較運算子
- CS0660: 類型會定義運算子 == 或運算子 !=,但不會覆寫 Object.Equals(object o)
- CS0661: 類型會定義運算子 == 或運算子 !=,但不會覆寫 Object.GetHashCode()
若要正確地實作相等性,請在定義自訂相等運算子時覆寫對應的方法Object。 如需詳細資訊,請參閱 如何定義類型的值相等性和相等運算子。
- 當您定義
operator ==或operator !=時,覆寫 Object.Equals (CS0660)。 - 當您定義
operator ==或operator !=時,請覆寫Object.GetHashCode(CS0661)。
覆寫這些方法可確保不同 API 和集合類型之間的相等行為一致。