| Severity | Warning |
| Reported by | Metalama.Framework (Roslyn analyzer) |
| Message | '<Member>' is marked [Durable] but is assigned a value of type '<ValueType>', which is not durable. Retention path: <RetentionPath>. |
Cause
Applying [Durable] (defined in the Metalama.Framework.Utilities namespace) to a field or to an automatically implemented property waives the check on the declared type of the member and requires instead that every value stored in the member be durable. This is the form to use for a member typed as an interface, as object, or as a delegate, none of which can vouch for what it holds. A durable value is safe to keep across compilations, so it must not hold a compilation, a syntax tree, a symbol, a semantic model, or anything that reaches one. See LAMA0870 for the full rationale.
Metalama reports LAMA0871 when the analyzer finds a value that isn't durable stored in such a member. It checks the following stores:
- a simple, compound, or null-coalescing assignment, including each element of a deconstruction assignment;
- the initializer of the field or property;
- an
outargument that receives a value into the member, in which case the analyzer judges the declared type of the parameter.
The warning is reported on the assigned expression. In the message, <Member> is the name of the durable member, <ValueType> is the type of the assigned expression, and <RetentionPath> is the chain of types that explains why it isn't durable, followed by the reason in parentheses.
When the assigned value is a lambda expression, the analyzer examines what the lambda captures, because a lambda holds its closure. In that case, it reports a different diagnostic, LAMA0878, at the captured variable.
The analyzer runs in the compiler and in the IDE, not in the Metalama aspect pipeline, so this diagnostic can't be shown in an example that runs a Metalama aspect test.
Resolution
- Assign a durable value. Store an IDurableRef (call
ToDurableRef()on a declaration), a SerializableDeclarationId, or a string, instead of the symbol, the syntax node, or the declaration. - Assign a delegate that captures nothing unsafe. A static method group captures nothing, and the analyzer checks a lambda for what it actually captures.
- Use
DurableDangerous<T>. If the value is durable in fact but the analyzer can't establish it, wrap it inDurableDangerous<T>. - Remove
[Durable]from the member if the member isn't held across compilations. In that case, make sure that the object holding the member is short-lived.