Open sandboxFocusImprove this doc

LAMA0888: A member of an immutable type is passed as an out argument

Severity Warning
Reported by Metalama.Framework
Message '<Type>' must be written in an immutable style because it is an aspect, a fabric, a validator, or another type bound by the [ImmutableType] contract, but '<Member>' is passed as an 'out' argument here, which writes it. Pass a local instead, and assign the member in a constructor.

Cause

Aspects, fabrics and validators must be written in an immutable style, because Metalama can share one instance among several threads and several compilations. A type is subject to this rule when it carries the [ImmutableType] attribute or when it derives from, or implements, a type that requires immutability, such as IAspect or Fabric.

An out argument is a write, but it doesn't look like an assignment, so it is easy to miss. Metalama reports LAMA0888 when an instance field or automatic property of such a type is passed as an out argument, for example int.TryParse( text, out this._value ), outside a constructor or an init accessor of the declaring type. In the message, <Type> is the type that must be immutable and <Member> is the name of the field or property that is passed.

An out argument in a constructor is part of the construction and isn't reported. The analyzer doesn't report ref arguments either, because the called method can only read the value, as Volatile.Read does. A direct assignment is reported by LAMA0887.

This diagnostic is reported by a Roslyn analyzer, and snapshot tests of aspects don't run analyzers, so this article has no example.

Resolution

Pass a local variable as the out argument, and assign the member from the local variable in a constructor. If the value must change after construction, don't keep it in the aspect, fabric or validator.

See also