Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The following errors can be generated when you're working with reference variables:
- CS0192: A
readonlyfield cannot be used as areforoutvalue (except in a constructor) - CS0199: A
static readonlyfield cannot be used as areforoutvalue (except in a static constructor) - CS0206: A non ref-returning property or indexer may not be used as an
outorrefvalue - CS0631:
refandoutare 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
refandout - CS1510: A
reforoutvalue must be an assignable variable - CS1605: Cannot use variable as a
reforoutvalue because it is read-only - CS1623: Iterators cannot have
ref,inoroutparameters - CS1649: Members of a
readonlyfield cannot be used as areforoutvalue (except in a constructor) - CS1651: Fields of a static readonly field cannot be used as a
reforoutvalue (except in a static constructor) - CS1655: Cannot use fields of type as a
reforoutvalue - CS1657: Cannot use variable as a
reforoutvalue - CS1741: A
reforoutparameter cannot have a default value - CS1939: Cannot pass the range variable as an
outorrefparameter - CS1988: Async methods cannot have
ref,inoroutparameters - CS7084: A Windows Runtime event may not be passed as an
outorrefparameter. - 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 arefconditional 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
reforoutvalue because it is a readonly variable - CS8330: Members of variable cannot be used as a
reforoutvalue because it is a readonly variable - CS8331: Cannot assign to variable or use it as the right hand side of a
refassignment because it is a readonly variable - CS8332: Cannot assign to a member of variable or use it as the right hand side of a
refassignment 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. - CS8373: The left-hand side of a
refassignment must be a ref variable. - CS8388: An
outvariable cannot be declared as a ref local - CS8977: Cannot use '
ref', 'in', or 'out' in the signature of a method attributed with 'UnmanagedCallersOnly'. - CS8986: The 'scoped' modifier of parameter doesn't match target.
- CS8987: The 'scoped' modifier of parameter doesn't match overridden or implemented member.
- CS9061: The 'scoped' modifier cannot be used with discard.
- CS9062: Types and aliases cannot be named 'scoped'.
- CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default.
- CS9065: Do not use 'System.Runtime.CompilerServices.ScopedRefAttribute'. Use the 'scoped' keyword instead.
- CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier.
- CS9072: A deconstruction variable cannot be declared as a ref local
- 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
usingstatement resource of type cannot be used in async methods or async lambda expressions. - CS9190:
readonlymodifier must be specified afterref. - CS9199: A
ref readonlyparameter cannot have the Out attribute.
The following warnings are generated when reference variables are used incorrectly:
- CS9073: The 'scoped' modifier of parameter doesn't match target.
- CS9074: The 'scoped' modifier of parameter doesn't match overridden or implemented member.
- CS9191: The
refmodifier for argument corresponding toinparameter is equivalent toin. Consider usingininstead. - CS9192: Argument should be passed with
reforinkeyword. - CS9193: Argument should be a variable because it is passed to a
ref readonlyparameter - CS9195: Argument should be passed with the
inkeyword - 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 readonlyparameter, butref readonlyshould be used only for references. Consider declaring the parameter asin. - CS9201: Ref field should be ref-assigned before use.
- CS9205: Expected interpolated string.
- CS9265: Field is never ref-assigned to, and will always have its default value (null reference)
These errors and warnings follow these themes:
- Incorrect syntax: The syntax of your declaration or usage is invalid.
- Language constructs where
refvariables 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.
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
refassignment must be a ref variable. - CS8388: An
outvariable cannot be declared as a ref local. - CS9190:
readonlymodifier must be specified afterref. - CS9205: Expected interpolated string.
To correct these errors:
- Ensure the left operand of a
= refoperator is a reference variable rather than a value expression or non-reference local. Ref assignment requires both sides to be reference variables that can create an alias to the same storage location (CS8373). - When declaring reference parameters, write the modifier as
ref readonlyrather thanreadonly ref. The C# language specification requires therefkeyword to precede thereadonlymodifier in parameter declarations to maintain consistent syntax across all reference parameter types (CS9190). - Use the
refkeyword instead ofoutwhen declaring local reference variables.outis exclusively a parameter modifier that indicates a method must assign a value before returning, whereasrefis the appropriate keyword for creating local variables that alias other storage locations (CS8388). - Pass a regular variable or value expression instead of an interpolated string when calling a method with an
outparameter. Interpolated strings are immutable temporary values that can't be used as output parameters since they don't represent assignable storage locations (CS9205).
For more information about reference variables and their syntax requirements, see reference variables and the C# Language Specification.
Reference variable restrictions
The following errors indicate that a reference variable can't be used where you have one:
- CS0631:
refandoutare 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
refandout - CS1623: Iterators cannot have
ref,inoroutparameters - CS1741: A
reforoutparameter cannot have a default value - CS1939: Cannot pass the range variable as an
outorrefparameter - CS1988: Async methods cannot have
ref,inoroutparameters - CS7084: A Windows Runtime event may not be passed as an
outorrefparameter. - CS8196: Reference to an implicitly-typed
outvariable is not permitted in the same argument list. - CS8325: 'await' cannot be used in an expression containing a
refconditional 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
usingstatement resource of type cannot be used in async methods or async lambda expressions. - CS9199: A
ref readonlyparameter 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 readonlyparameter, butref readonlyshould be used only for references. Consider declaring the parameter asin. - CS9201: Ref field should be ref-assigned before use.
- CS9265: Field is never ref-assigned to, and will always have its default value (null reference)
To correct these errors:
- Remove reference parameters from indexers. Indexers are designed to provide array-like access syntax and the compiler can't guarantee safe lifetime tracking for references passed through indexer accessors (CS0631, CS1623).
- Remove reference parameters from iterator methods. Iterators execute code lazily across multiple calls using state machines, and the compiler can't ensure referenced variables remain valid across yield return boundaries where execution is suspended and resumed (CS1623).
- Remove reference parameters from async methods. Async methods might suspend execution at await points and resume on different threads, making it impossible to guarantee that referenced variables remain valid and accessible throughout the method's execution (CS1988).
- Avoid using await expressions inside ref conditional expressions. The await operation might suspend execution and invalidate the references being selected by the conditional operator, leading to potential use of invalidated references when execution resumes (CS8325).
- Ensure both branches of a ref conditional operator return references or neither returns a reference, and when both are references they must be the same type. The conditional operator must produce a consistent result type that can be safely used by the calling code regardless of which branch is selected (CS8326, CS8327).
- Remove default values from
refandoutparameters. Reference parameters must always be provided at the call site to establish the required aliasing relationship between the parameter and an existing variable, making default values semantically meaningless (CS1741). - Avoid declaring an implicitly typed
outvariable in an argument list that also references that same variable. The compiler must infer the variable's type from the method signature while simultaneously validating uses of that variable within the same expression, creating a circular dependency (CS8196). - Don't pass LINQ query range variables as reference parameters. Range variables are compiler-generated iteration variables whose lifetime is managed by the query execution model and don't have stable memory locations that can be safely referenced (CS1939).
- Use regular value variables instead of ref locals when deconstructing objects. Deconstruction creates new variables to receive the deconstructed values and reference variables would attempt to alias these temporary values rather than store them independently (CS9072).
- Avoid implementing multiple interfaces where methods differ only by
refversusoutmodifiers on parameters. The C# language specification treats these as distinct signatures but doesn't provide a way to disambiguate which implementation to call since bothrefandoutshare the same calling syntax at implementation boundaries (CS0767). - Remove reference parameters from methods decorated with System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute. These methods are callable from unmanaged code that doesn't understand C#'s reference safety rules and can't guarantee proper lifetime management of referenced variables across the managed/unmanaged boundary (CS8977).
- Use the
refmodifier on extension method first parameters only for value types or generic types constrained to value types. Reference types are already passed by reference at the CLR level and addingrefwould create a reference to a reference, while value type extensions withrefenable mutation of the extended instance (CS8337, CS8338). - Don't pass Windows Runtime events as reference parameters. These events follow the Windows Runtime type system, which has different lifetime and threading semantics than .NET references and doesn't support the aliasing behavior required by C# reference parameters (CS7084).
- Remove the System.Runtime.InteropServices.OutAttribute from
ref readonlyparameters. This attribute is designed for marshaling semantics in platform invoke scenarios where the parameter direction is outbound only, which conflicts withref readonly's guarantee that the parameter references existing data that won't be reassigned (CS9199). - Ensure all
reffields in a type are assigned either in field initializers or in all constructor code paths before the constructor completes. Uninitialized ref fields would contain invalid references that could lead to memory corruption if accessed (CS9201, CS9265). - Match the reference kind modifiers (
ref,in,out,ref readonly) between a method and its overridden base method or implemented interface method. The reference modifier is part of the method signature contract that derived types must honor to maintain substitutability and caller expectations (CS9196, CS9197, CS9198). - Declare parameters as
inrather thanref readonlywhen providing default values.ref readonlyis designed for scenarios where the caller passes a reference to an existing variable, whereasinparameters can accept both references and temporary copies of values, making default values meaningful (CS9200).
For more information about where reference variables are allowed, see Method parameters, Iterators, Asynchronous programming patterns, and the C# Language Specification.
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 init-only members.
- CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member doesn't have this attribute.
To correct these errors:
- Remove the
unscopedmodifier or the System.Diagnostics.CodeAnalysis.UnscopedRefAttribute attribute from struct constructors and init-only members. These members have special initialization semantics where the compiler must ensure that any references don't outlive the initialization phase, and allowing unscoped references would violate the guarantee that initialization completes before the struct becomes fully accessible (CS9101). - Remove the
unscopedmodifier from interface implementation methods when the corresponding interface method doesn't have it. The unscoped characteristic affects the method's contract regarding reference lifetime guarantees, and implementations must maintain the same contract as the interface they're implementing to ensure callers can rely on consistent lifetime behavior regardless of which implementation is invoked (CS9102).
For more information about scoped and unscoped references, see Method parameters and the low-level struct improvements feature specification.
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
outorrefvalue - CS1510: A
reforoutvalue must be an assignable variable
Warnings:
- CS9191: The
refmodifier for argument corresponding toinparameter is equivalent toin. Consider usingininstead. - CS9192: Argument should be passed with
reforinkeyword. - CS9193: Argument should be a variable because it is passed to a
ref readonlyparameter - CS9195: Argument should be passed with the
inkeyword
To correct these errors:
- Store the result of a property or indexer access in a local variable before passing it as a reference parameter. Properties and indexers are methods that return values rather than providing direct access to storage locations, and reference parameters require an actual variable with a stable memory location that can be aliased (CS0206, CS1510).
- Use the
inmodifier instead ofrefwhen passing arguments toinparameters. Whilereftechnically works due to backward compatibility, theinmodifier more clearly expresses the intent that the argument is read-only and may be passed more efficiently as a reference without copying (CS9191, CS9195). - Add the appropriate reference modifier (
ref,in, orref readonly) when passing arguments to parameters that expect references. Omitting the modifier might cause the compiler to create a temporary copy of the value, which is inefficient and can lead to unexpected behavior if the calling code expects modifications to be reflected in the original variable (CS9192, CS9193).
For more information about reference parameters and passing variables by reference, see Method parameters, ref keyword, and the C# Language Specification.
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
readonlyfield cannot be used as areforoutvalue (except in a constructor) - CS0199: A
static readonlyfield cannot be used as areforoutvalue (except in a static constructor) - CS1605: Cannot use variable as a
reforoutvalue because it is read-only - CS1649: Members of a
readonlyfield cannot be used as areforoutvalue (except in a constructor) - CS1651: Fields of a
static readonlyfield cannot be used as areforoutvalue (except in a static constructor) - CS1655: Cannot use fields of type as a
reforoutvalue - CS1657: Cannot use variable as a
reforoutvalue - CS8329: Cannot use variable as a
reforoutvalue because it is a readonly variable - CS8330: Members of variable cannot be used as a
reforoutvalue because it is a readonly variable - CS8331: Cannot assign to variable or use it as the right hand side of a
refassignment because it is a readonly variable - CS8332: Cannot assign to a member of variable or use it as the right hand side of a
refassignment because it is a readonly variable
To correct these errors:
- Copy the value from a readonly field to a local variable and pass the local variable as a
reforoutparameter. Readonly fields are immutable after initialization (except within constructors) and allowing writable references to them would violate the immutability guarantee that readonly provides (CS0192, CS0199, CS1649, CS1651). - Use
ref readonlyorinparameters instead ofreforoutwhen you need to pass readonly variables, iteration variables, or other non-writable values by reference. These modifiers indicate that the method will only read the referenced value without attempting to modify it. That aligns with the immutability constraints of the original variable (CS1605, CS1655, CS1657, CS8329). - Copy members of readonly variables to local variables before passing them as writable references. Even though the member itself might not be declared as readonly, it's accessed through a readonly path (via a readonly field,
inparameter, orref readonlylocal), and the compiler enforces transitivity of readonly-ness to prevent indirect mutation of readonly data (CS8330, CS8332). - Avoid writable ref assignments to readonly variables, foreach iteration variables, using statement resources, or fixed statement variables. These variables have special lifetime semantics managed by the compiler. The variable is automatically finalized or disposed at the end of its scope. External references create dangling references after disposal (CS8331).
For more information about readonly semantics and reference parameters, see readonly keyword, in parameter modifier, ref readonly, and the C# Language Specification.