LAA1002 : DictionariesOrSetsShouldBeOrderedToEnumerate
Since there is no explicit order to enumerate dictionaries or sets,
enumerating them breaks IAction
's determinism. They should be explicitly
ordered before being enumerated.
Applied interfaces are:
System.Collections.Generic.IDictionary<K, V>
System.Collections.Generic.IReadOnlyDictionary<K, V>
System.Collections.Generic.ISet<V>
System.Collections.Immutable.IImmutableSet<V>
System.Collections.IDictionary
However, the following containers are excepted as they are already sorted:
System.Collections.Generic.SortedDictionary<K, V>
System.Collections.Generic.SortedSet<T>
System.Collections.Immutable.ImmutableSortedDictionary<K, V>
System.Collections.Immutable.ImmutableSortedSet<T>
Bencodex.Types.Dictionary
(which became to guarantee enumeration order since Bencodex 0.4.0-dev.20211116020419+abea0858)
Examples
The following code is warned by the rule LAA1002:
public IAccountStateDelta Execute(IActionContext context)
{
var states = context.PreviousState;
if (states.GetState(_address) is Bencodex.Types.Dictionary d)
{
string list = d.Keys
.OfType<Bencodex.Types.Text>(k => k.Value); // LAA1002
states.SetState(_targetAddress, (Bencodex.Types.Text)list);
}
return states;
}
This can be addressed like below:
public IAccountStateDelta Execute(IActionContext context)
{
var states = context.PreviousState;
if (states.GetState(_address) is Bencodex.Types.Dictionary d)
{
string list = d.Keys
.OfType<Bencodex.Types.Text>(k => k.Value)
.OrderBy(k => k); // Fixed
states.SetState(_targetAddress, (Bencodex.Types.Text)list);
}
return states;
}