編譯器會因介面中靜態抽象或虛擬成員的無效宣告產生以下錯誤:
- 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:介面 中宣告的等號或不等式運算子的其中一個參數必須是受限於介面的型別參數
對於在介面中宣告的一元運算子,請確保參數要麼是介面類型本身,要麼是受限於實作介面的型別參數TT(CS8921)。 此限制確保操作符只能套用於實作該介面的型別,使編譯器能在編譯時解析正確的實作。
對於遞增(++)與遞減(--)運算子,請確認參數遵循與其他一元運算子相同的規則(CS8922)。 此外,回傳型別必須與參數型別相符、從參數衍生,或是介面型別參數,且受限於介面(CS8923)。 這些規則確保遞增與遞減操作回傳相容型別,且可重新指派給原始變數。
對於二進位運算子,至少兩個參數中必須有一個是包含介面類型或受限於實作介面的型別參數(CS8924)。 此要求允許其他參數為任意類型,使得 T operator +(T left, int right) 運算子如一般數學情境中得以實現。
對於移位運算子(<< 和 >>),第一個運算元必須是包含的型別或其受約束型別參數(CS8925)。 第二個運算元遵循標準的移位運算子規則,通常為int。
對於使用者定義的轉換運算子,轉換必須包含一個受限於包圍介面類型(CS8931)的型別參數。 你無法在介面中定義任意類型之間的轉換;轉換必須與實作該介面的型別相關。
對於等號(==)與不等號(!=)運算子,至少有一個參數必須是受限於介面的型別參數,而不僅僅是介面型別本身(CS9046)。 這種對等式運算子的嚴格要求,確保了在透過介面比較實例時的適當型別安全。
欲了解更多關於介面中運算子宣告規則的資訊,請參閱 介面中的靜態抽象成員。 欲了解實作這些模式的實用指南,請參見 「探索靜態抽象介面成員」。
型別實作介面宣告錯誤
當你定義一個實作具有 static abstract 或 static virtual 方法的介面的類型時,可能會遇到以下錯誤:
- CS8928: 類型不實作靜態介面成員。該方法無法實作介面成員,因為它不是靜態的。
- CS8930:使用者 定義運算子的明確實作必須宣告為靜態
- CS8932:「UnmanagedCallersOnly」方法無法在類型中實作介面成員
- CS9044: 類型不實作介面成員。方法無法隱含實作不可存取的成員。
當你實作靜態抽象或靜態虛擬介面成員時,請使用 static 修飾符(CS8928)宣告實作方法。 與由實例方法實作的實例介面成員不同,靜態抽象成員需要靜態實作,因為執行時是在型別本身調用它們,而非實例。
對於介面中使用者定義運算子的明確實作,請在實作中包含 static 修飾符(CS8930)。 運算子的顯式介面實作遵循與隱含實作相同的靜態要求。
移除任何實作介面成員的方法(System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute)中的屬性。 使用此屬性標記的方法只能從未受管理的程式碼呼叫,且無法參與介面實作,因為執行時必須透過介面派遣機制呼叫這些方法。
如果實作方法的存取限制比介面成員更嚴格(例如,將private或public方法實作於internal介面成員),則應使用明確界面的實作語法,而非隱式實作(CS9044)。 隱式實作要求實作成員的存取權限至少與其實作的介面成員相同。
欲了解更多關於實作介面成員的資訊,請參見 介面 與 明確介面實作。
呼叫靜態抽象介面成員的錯誤
當你嘗試呼叫定義為介面中static abstract或static virtual成員時,可能會看到以下錯誤:
- CS8920: 介面不能用作型別參數。靜態成員在介面中沒有最具體的實作。
- CS8926: 靜態虛擬或抽象介面成員只能透過型別參數存取。
當你使用靜態抽象成員作為型別參數的介面時,請確保所有靜態抽象成員都有最具體的實作可用(CS8920)。 當編譯器無法判斷該使用哪個實作時,通常會看到這個錯誤,通常是因為多個介面階層提供衝突的預設實作,或根本沒有實作存在。
透過一個受限於實作介面的型別參數來存取靜態抽象或靜態虛擬介面成員,而非直接透過介面型別(CS8926)。 例如,使用 T.MemberName 其中 T 受限制於 where T : IMyInterface,而非 IMyInterface.MemberName。 編譯器需要一個具體型別來解析要呼叫哪個實作,而受限型態參數透過通用專用化在編譯時提供該具體型別。
欲了解更多關於存取靜態抽象成員的資訊,請參閱 介面中的靜態抽象成員。