avoid_accessing_other_classes_private_members
This rule flags one class reading another class’s private member.
Dart scopes privacy to the library, not the class. _field is visible to every declaration in the same file — and to every part of it. Most people write _ meaning “mine”, and the language quietly means “this file’s”. In a long file, or a part-heavy library, a class ends up depending on another’s internals with nothing in the code to mark it.
This rule is in the pedantic preset and works with its defaults.
See also: Dart: libraries and privacy
Both classes live in one file, so this compiles. Nothing marks that Report
now breaks whenever Account renames a field:
class Account { int _balance = 0;}
class Report { int total(Account account) => account._balance;}Expose what the other class actually needs:
class Account { int _balance = 0;
int get balance => _balance;}
class Report { int total(Account account) => account.balance;}More examples
Section titled “More examples”Another instance of the same class is fine
Section titled “Another instance of the same class is fine”other._value inside ==, copyWith or a comparison is the pattern, not a
violation — it is the class reaching into itself:
class Money { const Money(this._cents);
final int _cents;
// Not reported — `other` is a Money too. bool isMoreThan(Money other) => _cents > other._cents;
@override bool operator ==(Object other) => other is Money && _cents == other._cents;
@override int get hashCode => _cents.hashCode;}A State reading widget._foo
Section titled “A State reading widget._foo”A StatefulWidget and its State are one object the framework split in two,
so a read through widget is never reported:
class CounterState extends State<Counter> { // Not reported. int get start => widget._initial;}The exemption keys on the receiver being spelled widget, which is the
convention flutter create and every Flutter template produce. A State that
renames it loses the exemption.
Allowing your own merge-style members
Section titled “Allowing your own merge-style members”copyWith, operator ==, hashCode and toString are exempt by default —
they exist precisely to read another instance’s fields. Add your own:
rules: avoid_accessing_other_classes_private_members: additional_ignored_members: [merge, mergeWith]class Settings { Settings(this._values);
final Map<String, String> _values;
// Not reported with the config above. Settings merge(Settings other) => Settings({..._values, ...other._values});}Use ignored_members instead to replace the default list rather than add to
it.
Known limitations
Section titled “Known limitations”Only reads from inside a class are reported. A top-level function in the same library reaching into a class’s private field is not flagged:
class Account { int _balance = 0;}
// Not reported — no enclosing class.int total(Account account) => account._balance;this._x and a bare _x are the class’s own business and are never reported.
Options
Section titled “Options”many_lints: rules: avoid_accessing_other_classes_private_members: additional_ignored_members: [merge]rules: avoid_accessing_other_classes_private_members: additional_ignored_members: [merge]| Option | Type | Default | Description |
|---|---|---|---|
ignored_members |
list of strings | [copyWith, ==, hashCode, toString] |
Members whose job is to read another instance’s fields |
additional_ignored_members |
list of strings | [] |
Names to add to that list |
Turning this rule off
Section titled “Turning this rule off”To disable this rule:
rules: avoid_accessing_other_classes_private_members: falseTo keep the rule on but skip certain paths, use per-rule exclude.
Related rules
Section titled “Related rules”prefer_private_named_parameters— Prefer private named parameters (Dart 3.12+) over initializer-list boilerplate.prefer_widget_private_members— A widget’s public API is its constructor.avoid_commented_out_code— Detect and flag commented-out code.avoid_complex_conditions— Keep boolean conditions within an operand budget.