共用方式為


與傳址參數、變數和傳回相關聯的錯誤和警告

當您使用傳址參數時,可能會產生下列錯誤:

  • CS0192readonly 欄位不能作為 refout 值 (在建構函式中除外)
  • CS0199static readonly 欄位不能作為 refout 值 (在靜態建構函式中除外)
  • CS0206非參考傳回屬性或索引子不可以 outref 值形式使用
  • CS0631refout 在此內容中無效
  • CS0767無法繼承具有指定型別參數的介面,因為這會讓方法包含僅 refout 有所差異的多載
  • CS1510refout 值必須是可指派的變數
  • CS1605無法使用變數作為 refout 值,因為它是唯讀
  • CS1623迭代器不能有 refinout 參數
  • CS1649readonly 欄位的成員不能作為 refout 值 (在建構函式中除外)
  • CS1651靜態唯讀欄位的欄位不能作為 refout 值 (在建構函式中除外)
  • CS1655無法使用型別的欄位作為 refout
  • CS1657無法使用變數作為 refout
  • CS1741refout 參數不能有預設值
  • CS1939無法將範圍變數當作 outref 參數傳遞
  • CS1988非同步方法不能有 refinout 參數
  • CS7084Windows 執行階段事件不能當作 outref 參數傳遞。
  • CS8166無法藉由傳址方式傳回參數,因為其非 ref 參數
  • CS8167無法藉由傳址方式傳回參數的成員,因為其非 refout 參數
  • CS8168無法藉由傳址方式傳回 local,因為其非 ref local
  • CS8169無法藉傳址方式傳回 local 變數的成員,因為其非 ref local
  • CS8196不允許在相同引數清單中參考隱含型別 out 變數。
  • CS8325包含 ref 條件運算子的運算式無法使用 'await'
  • CS8326這兩個條件運算子的值都必須是 ref 值,或兩個都不是 ref 值
  • CS8327運算式必須為正確型別,才能符合替代 ref 值
  • CS8329無法使用變數作為 refout 值,因為它是唯讀變數
  • CS8330變數的成員無法作為 refout 值,因為它是唯讀變數
  • CS8331無法指派給變數,或將其用在 ref 指派的右側,因為它是唯讀變數
  • CS8332無法指派給變數的成員,或將其用在 ref 指派的右側,因為它是唯讀變數
  • CS8337 'ref' 擴充方法的第一個參數必須是限制為結構的實值型別或泛型型別。
  • CS8338擴充方法的第一個 'in' 或 'ref readonly' 參數必須是實體 (非泛型) 實值型別。
  • CS8351ref 條件運算子的分支不能參考具有不相容宣告範圍的變數
  • CS8373ref 指派的左側必須為 ref 變數。
  • CS8374無法 ref-assign,因為來源的逸出範圍比目的地還要窄。
  • CS8388out 變數不可宣告為 ref local
  • CS8977無法在具有 'UnmanagedCallersOnly' 屬性的方法簽章中使用 'ref'、'in' 或 'out'。
  • CS9072解構變數不可宣告為 ref local
  • CS9077無法透過 ref 參數藉由傳址方式傳回參數;其只能在 return 陳述式中傳回
  • CS9078無法透過 ref 參數藉由傳址方式傳回參數成員;其只能在 return 陳述式中傳回
  • CS9079無法 ref-assign,因為來源只能透過 return 陳述式逸出目前的方法。
  • CS9096無法 ref-assign,因為來源的值逸出範圍比目的還要寬,而允許透過逸出範圍比目的地窄的值來源進行指派。
  • CS9101UnscopedRefAttribute 只能套用至結構或虛擬介面執行個體方法和屬性,且無法套用至建構函式或僅 init 成員。
  • CS9102UnscopedRefAttribute 無法套用至介面實作,因為實作的成員沒有此屬性。
  • CS9104無法在非同步方法或非同步 Lambda 運算式中使用型別的 using 陳述式資源。
  • CS9190必須在 ref 之後指定 readonly 修飾元。
  • CS9199ref readonly 參數不能有 Out 屬性。

當參考變數使用不正確時,就會產生下列警告:

  • CS9085這會 ref-assign 變數,但目的地的逸出範圍比來源還要窄。
  • CS9086ref 條件運算子的分支參考具有不相容宣告範圍的變數
  • CS9087這會藉由傳址方式傳回參數,但其非 ref 參數
  • CS9089這會藉由傳址方式傳回參數的成員,其非 refout 參數
  • CS9091這會藉由傳址方式傳回 local,但其非 ref local
  • CS9092這會藉由傳址方式傳回 local的成員,但其非 ref local
  • CS9093這會 ref-assign,但來源只能透過 return 陳述式逸出目前的方法。
  • CS9094這會透過 ref 參數藉由傳址方式傳回參數;但是其只能在 return 陳述式中安全地傳回
  • CS9095這會透過 ref 參數藉由傳址方式傳回參數的成員;但是其只能在 return 陳述式中安全地傳回
  • CS9097這會 ref-assign,但來源的值逸出範圍比目的還要寬,而允許透過逸出範圍比來源窄的值目的地進行指派。
  • CS9191對應至 in 參數之引數的 ref 修飾元相當於 in。請考慮改用in
  • CS9192引數應該與 refin 關鍵字一起傳遞。
  • CS9193引數應該是變數,因為它會傳遞至 ref readonly 參數
  • CS9195引數應該與 in 關鍵字一起傳遞
  • CS9196參數的參考類型修飾元不符合已覆寫或實作成員中的對應參數。
  • CS9197參數的參考類型修飾元不符合隱藏成員中的對應參數。
  • CS9198參數的參考類型修飾元不符合目標中的對應參數。
  • CS9200已指定 ref readonly 參數的預設值,但 ref readonly 只應用於參考。考慮將參數宣告為 in
  • CS9201Ref 欄位應在使用前 ref-assign。
  • CS9265字段永遠不會被重新指派給 ,而且一律會有其預設值 (Null 參考)

這些錯誤和警告會遵循下列主題:

本文使用參考變數一詞做為使用其中一個 inref readonlyrefout 修飾元,或 ref 區域變數、ref struct 中的 ref 欄, 或 ref 傳回宣告之參數的一般詞彙。 參考變數會參考另一個變數,稱為參照

語法不正確

這些錯誤表示您使用的參考變數語法不正確:

  • CS8373ref 指派的左側必須為 ref 變數。
  • CS8388out 變數不可宣告為 ref local。
  • CS9190必須在 ref 之後指定 readonly 修飾元。

您可以使用下列其中一項變更來更正錯誤:

  • = ref 運算子的左運算元必須是參考變數。 如需正確語法的詳細資訊,請參閱參考變數
  • 參數修飾元 ref readonly 必須依該順序排列。 readonly ref 不是合法的參數修飾元。 切換字組的順序。
  • 區域變數無法宣告為 out。 若要宣告區域參考變數,請使用 ref

參考變數限制

下列錯誤表示參考變數不能用於您有參考變數的位置:

  • CS0631refout 在此內容中無效
  • CS0767無法繼承具有指定型別參數的介面,因為這會讓方法包含僅 refout 有所差異的多載
  • CS1623迭代器不能有 refinout 參數
  • CS1741refout 參數不能有預設值
  • CS1939無法將範圍變數當作 outref 參數傳遞
  • CS1988非同步方法不能有 refinout 參數
  • CS7084Windows 執行階段事件不能以 outref 參數形式傳遞。
  • CS8196不允許在相同引數清單中參考隱含型別 out 變數。
  • CS8325包含 ref 條件運算子的運算式無法使用 'await'
  • CS8326這兩個條件運算子的值都必須是 ref 值,或兩個都不是 ref 值
  • CS8327運算式必須為正確型別,才能符合替代 ref 值
  • CS8337'ref' 擴充方法的第一個參數必須是限制為結構的實值型別或泛型型別。
  • CS8338擴充方法的第一個 'in' 或 'ref readonly' 參數必須是實體 (非泛型) 實值型別。
  • CS8977無法在具有 'UnmanagedCallersOnly' 屬性的方法簽章中使用 'ref'、'in' 或 'out'。
  • CS9072解構變數不可宣告為 ref local
  • CS9104無法在非同步方法或非同步 Lambda 運算式中使用型別的 using 陳述式資源。
  • CS9199ref readonly 參數不能有 Out 屬性。

下列警告指出不應該使用參考變數,而且可能不安全:

  • CS9196參數的參考類型修飾元不符合已覆寫或實作成員中的對應參數。
  • CS9197參數的參考類型修飾元不符合隱藏成員中的對應參數。
  • CS9198參數的參考類型修飾元不符合目標中的對應參數。
  • CS9200已指定 ref readonly 參數的預設值,但 ref readonly 只應用於參考。考慮將參數宣告為 in
  • CS9201Ref 欄位應在使用前 ref-assign。
  • CS9265字段永遠不會被重新指派給 ,而且一律會有其預設值 (Null 參考)

若要修正錯誤,請移除不允許使用的參考變數:

  • 索引子迭代器,以及非同步方法中移除inrefout 參數。
  • 移除 ref 條件運算式 (? :),其中包含 await
  • 擴充方法的第一個參數中移除 ref 修飾元,其中該型別不是實值型別或限制為實值型別的泛型型別。
  • 兩個 [條件運算子運算式] 都必須或都不能是 ref 變數。 請從一個運算式中移除 ref,或將其新增至另一個運算式。 如果是 ref 條件運算式,則這兩個運算式必須為相同型別。
  • refout 參數不能有預設值。 請移除 refout 修飾元,或移除預設值。
  • 隱含型別 out 變數宣告也無法出現在相同引數清單中的其他地方。
  • 您無法將參考變數放在 async 方法 Lambda 運算式的 using 陳述式中。
  • LINQ 查詢運算式中的範圍變數無法藉由傳址方式傳遞。
  • 您無法將物件解構為參考變數。 以實值變數取代參考變數。
  • 您無法實作多個介面,其中方法多載在 refout 上有所不同。 例如,一個介面宣告 void M(ref int i),而另一個介面宣告 void M(out int i)。 類別無法實作這兩個介面,因為無法辨別方法。 您只能實作其中一個介面。
  • 具有 System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute 屬性的方法無法使用傳址參數。
  • Windows 執行階段事件不能當作參考變數傳遞。
  • ref readonly 參數無法在遠端 API 中套用 System.Runtime.InteropServices.OutAttribute
  • 初始化建 ref 構函式中的欄位,或做為欄位初始化表達式。

unscoped ref 限制

某些位置不允許 ref 參數上的 unscoped 限定詞:

  • CS9101UnscopedRefAttribute 只能套用至結構執行個體或虛擬介面方法和屬性,且無法套用至建構函式或僅 init 成員。
  • CS9102UnscopedRefAttribute 無法套用至介面實作,因為實作的成員沒有此屬性。

您必須在造成錯誤的參數宣告上移除 unscoped 修飾元。

參考變數需要參照

您必須提供變數做為傳址參數、參考傳回或 ref local 指派的引數:

  • CS0206非參考傳回屬性或索引子不可以 outref 值形式使用
  • CS1510refout 值必須是可指派的變數

警告:

  • CS9191對應至 in 參數之引數的 ref 修飾元相當於 in。請考慮改用 in
  • CS9192引數應該與 refin 關鍵字一起傳遞。
  • CS9193引數應該是變數,因為它會傳遞至 ref readonly 參數
  • CS9195引數應該與 in 關鍵字一起傳遞

當您使用運算式來計算必須使用變數的值時,編譯器會發出這些錯誤。 您必須將該運算式的結果儲存在變數中,才能加以使用。 例如,屬性和索引子會傳回值,而不是變數。 您必須將結果儲存在變數中,並傳遞該變數的參考。

可寫入參考變數需要可寫入的參照

可寫入參考變數要求參照也可寫入。 下列錯誤表示變數不可寫入:

  • CS0192readonly 欄位不能作為 refout 值 (在建構函式中除外)
  • CS0199static readonly 欄位不能作為 refout 值 (在靜態建構函式中除外)
  • CS1605無法使用變數作為 refout 值,因為它是唯讀
  • CS1649readonly 欄位的成員不能作為 refout 值 (在建構函式中除外)
  • CS1651static readonly 欄位的欄位不能作為 refout 值 (在靜態建構函式中除外)
  • CS1655無法使用型別的欄位作為 refout
  • CS1657無法使用變數作為 refout
  • CS8329無法使用變數作為 refout 值,因為它是唯讀變數
  • CS8330變數的成員無法作為 refout 值,因為它是唯讀變數
  • CS8331無法指派給變數,或將其用在 ref 指派的右側,因為它是唯讀變數
  • CS8332無法指派給變數的成員,或將其用在 ref 指派的右側,因為它是唯讀變數

無法寫入的變數範例包括:

  • readonly 欄位 (執行個體和靜態欄位)。
  • readonly 欄位的成員。
  • this 變數。
  • foreach 反覆運算變數
  • using 變數,或 fixed 變數。

您必須複製值,並將參考傳遞至複本。

Ref 安全違規

編譯器會追蹤參照和參考變數的安全內容。 當參考變數參考不再有效的參照變數時,編譯器會在不安全的程式碼中發出錯誤或警告。 參照必須具有至少與參考變數的 ref 安全內容一樣寬的安全內容。 違反這些安全檢查表示參考變數會存取隨機記憶體,而不是參照變數。

  • CS8166無法藉由傳址方式傳回參數,因為其非 ref 參數
  • CS8167無法藉由傳址方式傳回參數的成員,因為其非 refout 參數
  • CS8168無法藉由傳址方式傳回 local,因為其非 ref local
  • CS8169無法藉由傳址方式傳回 local 變數的成員,因為其非 ref local
  • CS8345欄位或自動實作屬性不可為型別,除非它是 ref struct 的執行個體成員。
  • CS8351ref 條件運算子的分支不能參考具有不相容宣告範圍的變數
  • CS8374無法 ref-assign,因為來源的逸出範圍比目的地還要窄。
  • CS9077無法透過 ref 參數藉由傳址方式傳回參數;其只能在 return 陳述式中傳回
  • CS9078無法透過 ref 參數藉由傳址方式傳回參數成員;其只能在 return 陳述式中傳回
  • CS9079無法將來源 ref-assign 給目的地,因為來源只能透過 return 陳述式逸出目前的方法。
  • CS9096無法將來源 ref-assign 給目的地,因為來源的值逸出範圍比目的還要寬,而允許透過逸出範圍比來源窄的值目的地進行指派。

警告:

  • CS9085這會將來源 ref-assign 給目的地,但來源的逸出範圍比目的地還要窄。
  • CS9086Ref 條件運算子的分支參考具有不相容宣告範圍的變數
  • CS9087這會藉由傳址方式傳回參數,但其非 ref 參數
  • CS9089這會藉由傳址方式傳回參數的成員,其非 refout 參數
  • CS9091這會藉由傳址方式傳回 local,但其非 ref local
  • CS9092這會藉由傳址方式傳回 local的成員,但其非 ref local
  • CS9093這會將來源 ref-assign 給目的地,但來源只能透過 return 陳述式逸出目前的方法。
  • CS9094這會透過 ref 參數藉由傳址方式傳回參數;但是其只能在 return 陳述式中安全地傳回
  • CS9095這會透過 ref 參數藉由傳址方式傳回參數的成員;但是其只能在 return 陳述式中安全地傳回
  • CS9097這會將來源 ref-assign 給目的地,但來源的值逸出範圍比目的還要寬,而允許透過逸出範圍比來源窄的值目的地進行指派。

編譯器會使用靜態分析來判斷參照是否在可使用參考變數的所有點都有效。 您必須重構程式碼,讓參照在參考變數可能參考它的所有位置維持有效。 如需 ref 安全規則的詳細資料,請參閱 ref 安全內容的 C# 標準。