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 aref
orout
value (except in a constructor) - CS0199: A
static readonly
field cannot be used as aref
orout
value (except in a static constructor) - CS0206: A non ref-returning property or indexer may not be used as an
out
orref
value - CS0631:
ref
andout
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
andout
- CS1510: A
ref
orout
value must be an assignable variable - CS1605: Cannot use variable as a
ref
orout
value because it is read-only - CS1623: Iterators cannot have
ref
,in
orout
parameters - CS1649: Members of a
readonly
field cannot be used as aref
orout
value (except in a constructor) - CS1651: Fields of a static readonly field cannot be used as a
ref
orout
value (except in a static constructor) - CS1655: Cannot use fields of type as a
ref
orout
value - CS1657: Cannot use variable as a
ref
orout
value - CS1741: A
ref
orout
parameter cannot have a default value - CS1939: Cannot pass the range variable as an
out
orref
parameter - CS1988: Async methods cannot have
ref
,in
orout
parameters - CS7084: A Windows Runtime event may not be passed as an
out
orref
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
orout
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 aref
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
orout
value because it is a readonly variable - CS8330: Members of variable cannot be used as a
ref
orout
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 afterref
. - 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
orout
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 toin
parameter is equivalent toin
. Consider usingin
instead. - CS9192: Argument should be passed with
ref
orin
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, butref readonly
should be used only for references. Consider declaring the parameter asin
. - CS9201: Ref field should be ref-assigned before use.
These errors and warnings follow these themes:
- Incorrect syntax: The syntax of your declaration or usage is invalid.
- Language constructs where
ref
variables aren't valid: Some C# idioms don't allow variables. Usually this is because ref safety analysis can't be performed reliably. - Value expression used where a reference variable is needed: The expression used as a reference variable must be a variable, not a value expression.
- Writable reference variables referring to readonly variables: A reference to a readonly variable can't be passed by writable reference.
- violations of ref safety: A reference variable can't refer to a variable that has a narrower context. That would mean the reference variable could refer to invalid memory.
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 afterref
.
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, useref
.
Reference variable restrictions
The following errors indicate that a reference variable can't be used where you have one:
- CS0631:
ref
andout
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
andout
- CS1623: Iterators cannot have
ref
,in
orout
parameters - CS1741: A
ref
orout
parameter cannot have a default value - CS1939: Cannot pass the range variable as an
out
orref
parameter - CS1988: Async methods cannot have
ref
,in
orout
parameters - CS7084: A Windows Runtime event may not be passed as an
out
orref
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, butref readonly
should be used only for references. Consider declaring the parameter asin
. - 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
, andout
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 removeref
from one expression, or add it to the other. If it's aref
conditional expression, both expressions must be the same type. ref
andout
parameters can't have default values. Either remove theref
orout
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 inasync
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
andout
. For example, one interface declaresvoid M(ref int i)
and another interface declaresvoid 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
orref
value - CS1510: A
ref
orout
value must be an assignable variable
Warnings:
- CS9191: The
ref
modifier for argument corresponding toin
parameter is equivalent toin
. Consider usingin
instead. - CS9192: Argument should be passed with
ref
orin
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 aref
orout
value (except in a constructor) - CS0199: A
static readonly
field cannot be used as aref
orout
value (except in a static constructor) - CS1605: Cannot use variable as a
ref
orout
value because it is read-only - CS1649: Members of a
readonly
field cannot be used as aref
orout
value (except in a constructor) - CS1651: Fields of a
static readonly
field cannot be used as aref
orout
value (except in a static constructor) - CS1655: Cannot use fields of type as a
ref
orout
value - CS1657: Cannot use variable as a
ref
orout
value - CS8329: Cannot use variable as a
ref
orout
value because it is a readonly variable - CS8330: Members of variable cannot be used as a
ref
orout
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
orout
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
orout
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.