Errors and warnings associated with reference parameters, variables, and returns

The following errors can be generated when you're working with reference variables:

  • CS0192: A readonly field cannot be used as a ref or out value (except in a constructor)
  • CS0199: A static readonly field cannot be used as a ref or out value (except in a static constructor)
  • CS0206: A non ref-returning property or indexer may not be used as an out or ref value
  • CS0631: ref and out are not valid in this context
  • CS0767: Cannot inherit interface with the specified type parameters because it causes method to contain overloads which differ only on ref and out
  • CS1510: A ref or out value must be an assignable variable
  • CS1605: Cannot use variable as a ref or out value because it is read-only
  • CS1623: Iterators cannot have ref, in or out parameters
  • CS1649: Members of a readonly field cannot be used as a ref or out value (except in a constructor)
  • CS1651: Fields of a static readonly field cannot be used as a ref or out value (except in a static constructor)
  • CS1655: Cannot use fields of type as a ref or out value
  • CS1657: Cannot use variable as a ref or out value
  • CS1741: A ref or out parameter cannot have a default value
  • CS1939: Cannot pass the range variable as an out or ref parameter
  • CS1988: Async methods cannot have ref, in or out parameters
  • CS7084: A Windows Runtime event may not be passed as an out or ref parameter.
  • CS8166: Cannot return a parameter by reference because it is not a ref parameter
  • CS8167: Cannot return by reference a member of parameter because it is not a ref or out parameter
  • CS8168: Cannot return local by reference because it is not a ref local
  • CS8169: Cannot return a member of local variable by reference because it is not a ref local
  • CS8196: Reference to an implicitly-typed out variable is not permitted in the same argument list.
  • CS8325: 'await' cannot be used in an expression containing a ref conditional operator
  • CS8326: Both conditional operator values must be ref values or neither may be a ref value
  • CS8327: The expression must be of correct type to match the alternative ref value
  • CS8329: Cannot use variable as a ref or out value because it is a readonly variable
  • CS8330: Members of variable cannot be used as a ref or out value because it is a readonly variable
  • CS8331: Cannot assign to variable or use it as the right hand side of a ref assignment because it is a readonly variable
  • CS8332: Cannot assign to a member of variable or use it as the right hand side of a ref assignment because it is a readonly variable
  • CS8337: The first parameter of a 'ref' extension method must be a value type or a generic type constrained to struct.
  • CS8338: The first 'in' or 'ref readonly' parameter of the extension method must be a concrete (non-generic) value type.
  • CS8351: Branches of a ref conditional operator cannot refer to variables with incompatible declaration scopes
  • CS8373: The left-hand side of a ref assignment must be a ref variable.
  • CS8374: Cannot ref-assign source has a narrower escape scope than destination.
  • CS8388: An out variable cannot be declared as a ref local
  • CS8977: Cannot use 'ref', 'in', or 'out' in the signature of a method attributed with 'UnmanagedCallersOnly'.
  • CS9072: A deconstruction variable cannot be declared as a ref local
  • CS9077: Cannot return a parameter by reference through a ref parameter; it can only be returned in a return statement
  • CS9078: Cannot return by reference a member of parameter through a ref parameter; it can only be returned in a return statement
  • CS9079: Cannot ref-assign because source can only escape the current method through a return statement.
  • CS9096: Cannot ref-assign because source has a wider value escape scope than destination allowing assignment through source of values with narrower escapes scopes than destination.
  • CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members.
  • CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member doesn't have this attribute.
  • CS9104: A using statement resource of type cannot be used in async methods or async lambda expressions.
  • CS9190: readonly modifier must be specified after ref.
  • CS9199: A ref readonly parameter cannot have the Out attribute.

The following warnings are generated when reference variables are used incorrectly:

  • CS9085: This ref-assigns variable but destination has a narrower escape scope than source.
  • CS9086: The branches of the ref conditional operator refer to variables with incompatible declaration scopes
  • CS9087: This returns a parameter by reference but it is not a ref parameter
  • CS9089: This returns by reference a member of parameter that is not a ref or out parameter
  • CS9091: This returns local by reference but it is not a ref local
  • CS9092: This returns a member of local by reference but it is not a ref local
  • CS9093: This ref-assigns but source can only escape the current method through a return statement.
  • CS9094: This returns a parameter by reference through a ref parameter; but it can only safely be returned in a return statement
  • CS9095: This returns by reference a member of parameter through a ref parameter; but it can only safely be returned in a return statement
  • CS9097: This ref-assigns but source has a wider value escape scope than destination allowing assignment through destination of values with narrower escapes scopes than source.
  • CS9191: The ref modifier for argument corresponding to in parameter is equivalent to in. Consider using in instead.
  • CS9192: Argument should be passed with ref or in keyword.
  • CS9193: Argument should be a variable because it is passed to a ref readonly parameter
  • CS9195: Argument should be passed with the in keyword
  • CS9196: Reference kind modifier of parameter doesn't match the corresponding parameter in overridden or implemented member.
  • CS9197: Reference kind modifier of parameter doesn't match the corresponding parameter in hidden member.
  • CS9198: Reference kind modifier of parameter doesn't match the corresponding parameter in target.
  • CS9200: A default value is specified for ref readonly parameter, but ref readonly should be used only for references. Consider declaring the parameter as in.
  • CS9201: Ref field should be ref-assigned before use.

These errors and warnings follow these themes:

This article uses the term reference variable as a general term for a parameter declared with one of the in, ref readonly, ref, or out modifiers, or a ref local variable, a ref field in a ref struct, or a ref return. A reference variable refers to another variable, called the referent.

Incorrect syntax

These errors indicate that you're using incorrect syntax regarding reference variables:

  • CS8373: The left-hand side of a ref assignment must be a ref variable.
  • CS8388: An out variable cannot be declared as a ref local.
  • CS9190: readonly modifier must be specified after ref.

You can correct the error with one of these changes:

  • The left operand of an = ref operator must be a reference variable. For more information on the correct syntax, see reference variables.
  • The parameter modifier ref readonly must be in that order. readonly ref is not a legal parameter modifier. Switch the order of the words.
  • A local variable can't be declared as out. To declare a local reference variable, use ref.

Reference variable restrictions

The following errors indicate that a reference variable can't be used where you have one:

  • CS0631: ref and out are not valid in this context
  • CS0767: Cannot inherit interface with the specified type parameters because it causes method to contain overloads which differ only on ref and out
  • CS1623: Iterators cannot have ref, in or out parameters
  • CS1741: A ref or out parameter cannot have a default value
  • CS1939: Cannot pass the range variable as an out or ref parameter
  • CS1988: Async methods cannot have ref, in or out parameters
  • CS7084: A Windows Runtime event may not be passed as an out or ref parameter.
  • CS8196: Reference to an implicitly-typed out variable is not permitted in the same argument list.
  • CS8325: 'await' cannot be used in an expression containing a ref conditional operator
  • CS8326: Both conditional operator values must be ref values or neither may be a ref value
  • CS8327: The expression must be of correct type to match the alternative ref value
  • CS8337: The first parameter of a 'ref' extension method must be a value type or a generic type constrained to struct.
  • CS8338: The first 'in' or 'ref readonly' parameter of the extension method must be a concrete (non-generic) value type.
  • CS8977: Cannot use 'ref', 'in', or 'out' in the signature of a method attributed with 'UnmanagedCallersOnly'.
  • CS9072: A deconstruction variable cannot be declared as a ref local
  • CS9104: A using statement resource of type cannot be used in async methods or async lambda expressions.
  • CS9199: A ref readonly parameter cannot have the Out attribute.

The following warnings indicate that a reference variable shouldn't be used, and might be unsafe:

  • CS9196: Reference kind modifier of parameter doesn't match the corresponding parameter in overridden or implemented member.
  • CS9197: Reference kind modifier of parameter doesn't match the corresponding parameter in hidden member.
  • CS9198: Reference kind modifier of parameter doesn't match the corresponding parameter in target.
  • CS9200: A default value is specified for ref readonly parameter, but ref readonly should be used only for references. Consider declaring the parameter as in.
  • CS9201: Ref field should be ref-assigned before use.

To fix the error, remove the reference variable where it isn't allowed:

  • Remove in, ref, and out parameters from indexers, iterators, and async methods.
  • Remove ref conditional expressions (? :) that include an await.
  • Remove the ref modifier from the first parameter of a extension method where that type isn't a value type or a generic type constrained as a value type.
  • Either both or neither [conditional operator expressions] must be ref variables. Either remove ref from one expression, or add it to the other. If it's a ref conditional expression, both expressions must be the same type.
  • ref and out parameters can't have default values. Either remove the ref or out modifier, or remove the default value.
  • An implicitly typed out variable declaration can't also appear elsewhere in the same argument list.
  • You can't put reference variables in a using statement in async methods lambda expressions.
  • The range variable in a LINQ query expression can't be passed by reference.
  • You can't deconstruct an object into reference variables. Replace the reference variables with value variables.
  • You can't implement multiple interfaces where method overloads differ only on ref and out. For example, one interface declares void M(ref int i) and another interface declares void M(out int i). A class can't implement both interfaces because the methods aren't distinguishable. You can only implement one of those interfaces.
  • Methods attributed with System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute can't use reference parameters.
  • A Windows runtime event can't be passed as a reference variable.
  • A ref readonly parameter can't have the System.Runtime.InteropServices.OutAttribute applied to it in remoting API.

unscoped ref restrictions

The unscoped qualifier on ref parameters isn't allowed in some locations:

  • CS9101: UnscopedRefAttribute can only be applied to struct instance or virtual interface methods and properties, and cannot be applied to constructors or or init-only members.
  • CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member doesn't have this attribute..

You must remove the unscoped modifier on the parameter declaration that caused the error.

Reference variables require a referent

You must supply a variable as an argument to a reference parameter, reference return, or ref local assignment:

  • CS0206: A non ref-returning property or indexer may not be used as an out or ref value
  • CS1510: A ref or out value must be an assignable variable

Warnings:

  • CS9191: The ref modifier for argument corresponding to in parameter is equivalent to in. Consider using in instead.
  • CS9192: Argument should be passed with ref or in keyword.
  • CS9193: Argument should be a variable because it is passed to a ref readonly parameter
  • CS9195: Argument should be passed with the in keyword

The compiler emits these errors when you use an expression that calculates a value where a variable must be used. You must store the result of that expression in a variable to use it. For example, properties and indexers return values, not variables. You must store the result in a variable and pass a reference to that variable.

Writable reference variables require a writable referent

A writable reference variable requires that the referent also is writable. The following errors indicate that the variable isn't writable:

  • CS0192: A readonly field cannot be used as a ref or out value (except in a constructor)
  • CS0199: A static readonly field cannot be used as a ref or out value (except in a static constructor)
  • CS1605: Cannot use variable as a ref or out value because it is read-only
  • CS1649: Members of a readonly field cannot be used as a ref or out value (except in a constructor)
  • CS1651: Fields of a static readonly field cannot be used as a ref or out value (except in a static constructor)
  • CS1655: Cannot use fields of type as a ref or out value
  • CS1657: Cannot use variable as a ref or out value
  • CS8329: Cannot use variable as a ref or out value because it is a readonly variable
  • CS8330: Members of variable cannot be used as a ref or out value because it is a readonly variable
  • CS8331: Cannot assign to variable or use it as the right hand side of a ref assignment because it is a readonly variable
  • CS8332: Cannot assign to a member of variable or use it as the right hand side of a ref assignment because it is a readonly variable

Examples of variables that aren't writable include:

  • readonly fields, both instance and static fields.
  • Members of readonly fields.
  • The this variable.
  • The foreach iteration variable
  • A using variable, or a fixed variable.

You must copy the value and pass a reference to the copy.

Ref safety violations

The compiler tracks the safe context of referents and reference variables. The compiler issues errors, or warnings in unsafe code, when a reference variable refers to a referent variable that's no longer valid. The referent must have a safe context that is at least as wide as the ref safe context of The reference variable. Violating these safety checks means the reference variable accesses random memory instead of the referent variable.

  • CS8166: Cannot return a parameter by reference because it is not a ref parameter
  • CS8167: Cannot return by reference a member of parameter because it is not a ref or out parameter
  • CS8168: Cannot return local by reference because it is not a ref local
  • CS8169: Cannot return a member of local variable by reference because it is not a ref local
  • CS8345: Field or auto-implemented property cannot be of type unless it is an instance member of a ref struct.
  • CS8351: Branches of a ref conditional operator cannot refer to variables with incompatible declaration scopes
  • CS8374: Cannot ref-assign source has a narrower escape scope than destination.
  • CS9077: Cannot return a parameter by reference through a ref parameter; it can only be returned in a return statement
  • CS9078: Cannot return by reference a member of parameter through a ref parameter; it can only be returned in a return statement
  • CS9079: Cannot ref-assign source to destination because source can only escape the current method through a return statement.
  • CS9096: Cannot ref-assign source to destination because source has a wider value escape scope than destination allowing assignment through destination of values with narrower escapes scopes than source.

Warnings:

  • CS9085: This ref-assigns source to destination but source has a narrower escape scope than destination.
  • CS9086: The branches of the ref conditional operator refer to variables with incompatible declaration scopes
  • CS9087: This returns a parameter by reference but it is not a ref parameter
  • CS9089: This returns by reference a member of parameter that is not a ref or out parameter
  • CS9091: This returns local by reference but it is not a ref local
  • CS9092: This returns a member of local by reference but it is not a ref local
  • CS9093: This ref-assigns source to destination but source can only escape the current method through a return statement.
  • CS9094: This returns a parameter by reference through a ref parameter; but it can only safely be returned in a return statement
  • CS9095: This returns by reference a member of parameter through a ref parameter; but it can only safely be returned in a return statement
  • CS9097: This ref-assigns source to destination but source has a wider value escape scope than destination allowing assignment through destination of values with narrower escapes scopes than source.

The compiler uses static analysis to determine if the referent is valid at all points where the reference variable can be used. You need to refactor code so that the referent remains valid at all locations where the reference variable might refer to it. For details on the rules for ref safety, see the C# standard on ref safe contexts.