解決代理與函式指標的錯誤與警告

本文涵蓋下列編譯器錯誤和警告:

  • CS0059可及性不一致:參數型別「type」的可及性低於委託「delegate」。
  • CS0123沒有任何「方法」的重載與「委派」匹配。
  • CS0148代理「代理」沒有有效的建構子。
  • CS0410「方法」的多載沒有正確的參數和回傳類型。
  • CS0644:「 類別」無法來自特殊類別「類別」。
  • CS1599方法、代理或函式指標的回傳類型不能是「型別」。
  • CS1958物件與集合初始化運算式不得套用於代理建立表達式。
  • CS8755「修飾符」不能用作函數指標參數的修飾符。
  • CS8756函式指標「型別」不接受「count」參數。
  • CS8757沒有對應函式指標「類型」的「方法」超載。
  • CS8758參考「方法」與函式指標「型別」之間的不匹配。
  • CS8759無法為「方法」建立函式指標,因為它不是靜態方法。
  • CS8786'convention' 的呼叫慣例與 'convention' 不相容。
  • CS8787無法將方法群組轉換成函式指標。(你是不是漏了一個「&」?)
  • CS8788無法使用以接收器為「&」運算子目標的擴展方法。
  • CS8789固定語句中宣告的本地類型不能是函式指標類型。
  • CS8806:語言 不支援「convention」的呼叫慣例。
  • CS8807:「 specifier」並非函式指標的有效呼叫慣例指定符。
  • CS8808:「修飾符」不是有效的函式指標回傳類型修飾符。有效的修飾符是「ref」和「ref readonly」。
  • CS8809一個返回類型只能有一個“modifier”修飾符。
  • CS8811無法將方法群組 'method' 轉換為委派類型 'type'。
  • CS8909比較函數指標可能會產生意想不到的結果,因為指向同一函數的指標可能不同。
  • CS8911:在此 情境下不支援使用函式指標類型。

代表簽名不符

  • CS0059可及性不一致:參數型別「類型」比委派「委派」更難被存取。
  • CS0123「方法」的重載無法匹配「委派」。
  • CS0148代理「代理」沒有有效的建構子。
  • CS0410「函式」的多載沒有符合正確的參數和回傳類型。

當你建立或指派代理時,編譯器會驗證目標方法的簽名是否與代理類型的宣告相符。 簽章包含參數類型、回傳類型及可存取性。 完整規則請參閱 C# 規範中的 代理可及性限制

  • 將代理宣告中的所有參數類型改為至少與代理本身一樣可存取的類型(CS0059)。 public代理無法在參數列表中引用較難存取的型別,因為集合外的呼叫者無法提供該參數。 如需詳細資訊,請參閱 存取修飾元
  • 調整方法簽章或代理簽章,使參數類型與回傳類型完全一致(CS0123)。 編譯器在指派方法給代理時,必須有精確的簽名匹配。
  • 確認該代理是由符合規範的編譯器(CS0148)編譯的。 此錯誤發生在您匯入由編譯器所建立的管理裝配,而該編譯器產生了一個未成形的代理建構器時。 用符合標準的編譯器重新編譯組合語言以解決錯誤。

備註

CS0410 已不再由現行 C# 編譯器產生。 同樣條件現在會產生 CS0123。 使用早期編譯器編譯的舊組譯組語言仍可能引用此錯誤碼。

CS0148 是僅在建置時才有的診斷工具:

備註

此警告僅在明確的 建置重建 操作期間報告。 在 IDE 輸入時,IntelliSense 診斷時不會顯示這個問題。 這表示如果你透過使用欄位或移除該欄位來修正警告,該警告可能會持續存在於錯誤清單中,直到你再次建置或重建專案。

代表類型限制

  • CS0644:「 類別」無法來自特殊類別「類別」。
  • CS1599方法、代理或函式指標的回傳類型不能是「型別」。
  • CS1958物件與集合初始化運算式不得套用於代理建立表達式。

C# 語言限制了某些特殊類型的使用方式,包括 System.Delegate。 關於代理宣告的完整規則,請參閱 C# 規範中的代理與代理

  • 移除明確的基底類別,改用delegate宣告(CS0644)。 類別不能明確繼承自 System.DelegateSystem.EnumSystem.ValueTypeSystem.Array或 。 編譯器將這些類型作為隱含的基底類別使用。 例如,每個 delegate 宣告隱含地從 衍生出 System.Delegate
  • 將返回類型改成允許作為返回值的類型(CS1599)。 .NET 類別函式庫中的某些類型,如 TypedReferenceRuntimeArgumentHandleArgIterator,無法用作方法、代理或函式指標的回傳型別,因為它們可能促成不安全的堆疊操作。
  • 移除委派建立表達式後的括號(CS1958)。 Delegate 不具有可以透過物件或集合初始化器語法來設定的成員。 如果在 new DelegateType(method) 表達式之後有 { },請移除括號。

函數指標簽名不匹配

  • CS8755「修飾符」不能用作函數指標參數的修飾符。
  • CS8756函式指標「型別」不接受「count」參數。
  • CS8757沒有對應函式指標「類型」的「方法」超載。
  • CS8758參考「方法」與函式指標「型別」之間的不匹配。
  • CS8759無法為「方法」建立函式指標,因為它不是靜態方法。
  • CS8787無法將方法群組轉換成函式指標。(你是不是漏了一個「&」?)
  • CS8788無法使用以接收器為「&」運算子目標的擴展方法。
  • CS8811無法將 'method' 方法群組轉換為 'type' 委派型別。

當你使用 address-of(&) 運算子將方法指派給函式指標時,編譯器會檢查該方法的簽名是否與函式指標類型相符。 關於函式指標宣告與使用的完整規則,請參見 函式指標不安全程式碼

  • 移除函數指標參數(CS8755)中未支援的修飾符。 函式指標參數僅支援 refoutin 修飾符。 其他參數修飾符,例如 params,在函式指標類型的宣告中並不有效。
  • 將呼叫站點的參數數調整為與函式指標的參數數量(CS8756)相符。 函式指標型別定義固定數量的參數,且必須傳遞恰好相同數量的參數。
  • 調整方法的簽名,使其參數型別、回傳型別和參數數量與函式指標類型(CS8757)相符。 與代理不同,函式指標不支援相容方法簽名間的隱式轉換。 匹配必須完全一致。
  • refoutin修飾符在方法的參數與函式指標類型的參數之間對齊(CS8758)。 每個參數的參考型態必須完全一致。 參數 ref 無法滿足 in 函式指標類型中的 OR out 位置。
  • 將目標方法改為 staticCS8759)。 函式指標只能指向靜態方法,因為它們代表原始函式位址,且沒有相關物件實例。
  • 指派到函式指標(CS8787)時,請將&運算子放在方法群組前。 與代理不同,函式指標需要明確的位址運算子: delegate*<void> ptr = &MyMethod;
  • 使用靜態方法代替帶有接收器的擴展方法(CS8788)。 運算子 & 需要直接的方法參考。 在實例上呼叫的擴充方法有一個隱含的接收器,無法被函式指標捕捉。
  • 移除運算 & 子改用代理語法,或將目標型別從代理改為函式指標(CS8811)。 &運算子產生的是函式指標,而非代理。 若要將方法群組指派到代理型別,請省略 , & 改用標準代理建立語法。

函式指標呼叫慣例與回傳類型

  • CS8786「convention」的呼叫約定與「convention」不相容。
  • CS8806:語言 不支援「convention」的呼叫慣例。
  • CS8807:「 specifier」並非函式指標的有效呼叫慣例指定符。
  • CS8808:「修飾詞」不是有效的函式指標回傳類型修飾詞。有效的修飾詞有「ref」和「ref readonly」。
  • CS8809一個返回類型只能有一個「modifier」修飾符。

函式指標宣告包含呼叫慣例及可選的回傳類型修飾符。 編譯器會驗證這些選項。 完整規則請參見 函數指標

  • 改變方法的呼叫慣例或函式指標的呼叫慣例,使其相符(CS8786)。 當你將方法指派給函式指標時,呼叫慣例必須相容。 例如,使用Cdecl的方法不能指派給宣告的Stdcall函式指標。
  • 在函式指標宣告中使用支援的呼叫慣例(CS8806)。 語言支援 managedunmanaged。 對於特定的非管理慣例,請使用 unmanaged 帶有該慣例的方括號關鍵字,例如 unmanaged[Cdecl]unmanaged[Stdcall]unmanaged[Thiscall]unmanaged[Fastcall]
  • 將無效的指定詞替換為支援的呼叫慣例(CS8807)。 使用 managedunmanagedunmanaged搭配方括號內指定的呼叫慣例類型(例如,unmanaged[Cdecl])。
  • 僅可使用 refref readonly 作為返回類型修飾符(CS8808)。 其他修飾符,如 outin,對於函式指標回傳類型並不適用。
  • 移除重複回傳類型修飾符,只會出現一個 refref readonlyCS8809)。 編譯器最多允許在函式指標宣告時使用一個回傳類型修飾符。

函式指標使用限制

  • CS8789固定語句中宣告的本地類型不能是函式指標類型。
  • CS8909比較函數指標可能會產生意想不到的結果,因為指向同一函數的指標可能不同。
  • CS8911:在此 情境下不支援使用函式指標類型。

編譯器會限制函式指標類型在特定情境下的使用方式。 完整規則請參見 函數指標

  • 將語句中的 fixed 本地變數類型改為資料指標型別,而非函式指標型別(CS8789)。 該 fixed 敘述將記憶體中的受管理物件固化,以便存取資料。 函式指標代表的是程式碼位址,不是資料,且無法釘選。
  • 避免比較函數指標以取得等號(CS8909)。 此警告表示比較函式指標 ==!= 可能產生意外結果。 執行時可能會因實作細節(如 thunking 或 JIT 編譯)而回傳不同的指標。 若要在確認比較是有意而為時抑制警告,請使用 #pragma warning disable CS8909
  • 將函式指標的使用移至支援的上下文(CS8911)。 函式指標型別不能在某些位置使用,例如屬性參數或 typeof 表達式。 重新結構程式碼,避免在不支援的情境中使用函式指標型別。