Skip to content

Latest commit

 

History

History
76 lines (51 loc) · 2.14 KB

HLQ011_ReadOnlyEnumeratorField.md

File metadata and controls

76 lines (51 loc) · 2.14 KB

HLQ011: Mutable value-type enumerators cannot be stored in a 'readonly' field.

Cause

A mutable value-type enumerators is being stored in a 'readonly' field.

Severity

Error

Rule description

Enumerators are usually mutable. They have to store the state so that, when MoveNext() is called, it moves to the next item, if available.

A rare example of an immutable enumerator is the one generated by System.Linq.Enumerable.Empty(). Its MoveNext() method implementation returns always false.

When the enumerator is a value type, this is particularly important. If the enumerator is stored in a readonly field, when MoveNext() is called, a copy of the enumerator is made and the state changed on this other one.

If the enumerator is a value type but not mutable, it should be declared as readonly struct. In this case, the copy will not be made.

How to fix violations

Either remove the readonly keyword from the field or, if possible, add the readonly keyword to the enumerator definition.

NOTE: When the readonly is removed from the field, you may get an IDE0044 warning, telling you to add it back. Disable this rule for this line.

When to suppress warnings

Should not be suppressed.

Example of a violation

class Enumerator<T>
{
    readonly MutableEnumerator source; // readonly field

    public Enumerator(MutableEnumerator source)
        => this.source = source;
}
class Enumerator<TEnumerator> where TEnumerator : struct, IEnumerator
{
    readonly TEnumerator source; // readonly field

    public Enumerator(TEnumerator source)
        => this.source = source;
}

Example of how to fix

class Enumerator<T>
{
    [SuppressMessage("Style", "IDE0044:Add readonly modifier")]
    MutableEnumerator source; // readonly removed

    public Enumerator(MutableEnumerator source)
        => this.source = source;
}
class Enumerator<TEnumerator> where TEnumerator : struct, IEnumerator
{
    [SuppressMessage("Style", "IDE0044:Add readonly modifier")]
    TEnumerator source; // readonly removed

    public Enumerator(TEnumerator source)
        => this.source = source;
}