Skip to content

prefer_class_destructuring

v0.4.0WarningFixConfigurableCollection & Type

This rule is in the pedantic preset.

Flags a block that reads three or more distinct properties from the same local variable or parameter. A single Dart 3 destructuring declaration extracts them all at once. The quick fix writes it.

Four user. prefixes carrying no information — the reader parses the same receiver four times to find the four values that matter:

class UserProfile {
const UserProfile({
required this.name,
required this.email,
required this.age,
required this.city,
});
final String name;
final String email;
final int age;
final String city;
}
String describe(UserProfile user) {
return 'Hello, ${user.name} <${user.email}>, '
'${user.age}, from ${user.city}';
}
class UserProfile {
const UserProfile({
required this.name,
required this.email,
required this.age,
required this.city,
});
final String name;
final String email;
final int age;
final String city;
}
String describe(UserProfile user) {
final UserProfile(:name, :email, :age, :city) = user;
return 'Hello, $name <$email>, $age, from $city';
}

The declaration also states, in one line, exactly which properties this function depends on.

Three accesses is the default trigger. A codebase that finds that eager can require four or more before the rule reports:

many_lints.yaml
rules:
prefer_class_destructuring:
min_occurrences: 4
// Reported at the default of 3, accepted with min_occurrences: 4
String summarise(UserProfile user) {
return '${user.name} (${user.age}) — ${user.city}';
}

Exempting types where destructuring reads worse

Section titled “Exempting types where destructuring reads worse”

A theme or context object is usually read for a handful of unrelated properties, and pulling them into bare names loses the thing that told you where they came from:

many_lints.yaml
rules:
prefer_class_destructuring:
ignored_types: [BuildContext, ThemeData]

Only locals and parameters are tracked. A field or a top-level variable is never reported — this.config.host and friends stay as they are.

Distinct properties, not total reads. Reading user.name five times counts as one property, so it does not reach the threshold on its own.

Method calls are not property accesses. user.toString() and user.copyWith(...) do not count toward the total.

Each block is counted separately. Accesses split across a body and a nested closure are not pooled, since the collector stops at function boundaries.

See also: Dart patterns

This rule appears only in the pedantic preset because destructuring can obscure the relationship between a value and its properties.

many_lints.yaml
rules:
prefer_class_destructuring: true

To turn it off again:

many_lints.yaml
rules:
prefer_class_destructuring: false

To keep the rule on but skip certain paths, use per-rule exclude.

analysis_options.yaml
many_lints:
rules:
prefer_class_destructuring:
min_occurrences: 4
ignored_types: [BuildContext, ThemeData]
Option Type Default Description
min_occurrences int 3 Minimum number of distinct property accesses on the same variable before the rule reports
ignored_types list of strings [] Type names never reported, for types where destructuring reads worse than repeated access