prefer_class_destructuring
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.
Raising the threshold
Section titled “Raising the threshold”Three accesses is the default trigger. A codebase that finds that eager can require four or more before the rule reports:
rules: prefer_class_destructuring: min_occurrences: 4// Reported at the default of 3, accepted with min_occurrences: 4String 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:
rules: prefer_class_destructuring: ignored_types: [BuildContext, ThemeData]Known limitations
Section titled “Known limitations”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
Turning this rule off
Section titled “Turning this rule off”This rule appears only in the pedantic preset because destructuring can
obscure the relationship between a value and its properties.
rules: prefer_class_destructuring: trueTo turn it off again:
rules: prefer_class_destructuring: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Options
Section titled “Options”many_lints: rules: prefer_class_destructuring: min_occurrences: 4 ignored_types: [BuildContext, ThemeData]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 |
Related rules
Section titled “Related rules”avoid_accessing_collections_by_constant_index— Avoid accessing a collection by a constant index inside a loop.avoid_collection_equality_checks— Avoid comparing collections with == or != as it checks reference equality, not contents.avoid_collection_methods_with_unrelated_types— Avoid calling collection methods with arguments whose types are unrelated to the collection’s type parameter.avoid_duplicate_collection_elements— Don’t repeat the same element in a collection literal.