You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中构造函数未触发Setter验证的问题及解决方法

问题原因与解决办法

你的代码里setter的验证逻辑没触发,核心原因是构造函数直接给私有字段_car、_model赋值了,完全绕过了setter方法,所以空字符串的检查根本没执行,导致空值对象被创建出来。

下面是几种解决这个问题的方案:

方法1:构造函数内调用setter赋值

把构造函数改成通过setter来设置字段,而不是直接给私有变量赋值,这样就能触发验证逻辑:

void main() {
  CarCarCar car1 = CarCarCar('Toyota', 'Corolla', 1983);
  // 此处会抛出ArgumentError
  CarCarCar car2 = CarCarCar('', '', 2014);

  List<CarCarCar> cars = [car1, car2];

  for (var car in cars) {
    print(car.getCarModel());
  }
}

class CarCarCar {
  String _car;
  String _model;
  int uretimYili;

  // 构造函数里调用setter,而非直接赋值私有字段
  CarCarCar(String car, String model, this.uretimYili) {
    this.car = car;
    this.model = model;
  }

  String get car => _car;

  set car(String car) {
    if (car.isNotEmpty) {
      _car = car;
    } else {
      throw ArgumentError('Car değeri bulunamadı: $car');
    }
  }

  String get model => _model;

  set model(String model) {
    if (model.isNotEmpty) {
      _model = model;
    } else {
      throw ArgumentError('Model değeri bulunamadı: $model');
    }
  }

  String getCarModel() {
    return '$_car, $_model, $uretimYili';
  }
}

方法2:构造函数内直接做参数验证

如果不想依赖setter,直接在构造函数里对参数做检查并抛出错误:

void main() {
  CarCarCar car1 = CarCarCar('Toyota', 'Corolla', 1983);
  // 此处会抛出ArgumentError
  CarCarCar car2 = CarCarCar('', '', 2014);

  List<CarCarCar> cars = [car1, car2];

  for (var car in cars) {
    print(car.getCarModel());
  }
}

class CarCarCar {
  String _car;
  String _model;
  int uretimYili;

  CarCarCar(String car, String model, this.uretimYili) {
    if (car.isEmpty) {
      throw ArgumentError('Car değeri bulunamadı: $car');
    }
    if (model.isEmpty) {
      throw ArgumentError('Model değeri bulunamadı: $model');
    }
    _car = car;
    _model = model;
  }

  String get car => _car;

  set car(String car) {
    if (car.isNotEmpty) {
      _car = car;
    } else {
      throw ArgumentError('Car değeri bulunamadı: $car');
    }
  }

  String get model => _model;

  set model(String model) {
    if (model.isNotEmpty) {
      _model = model;
    } else {
      throw ArgumentError('Model değeri bulunamadı: $model');
    }
  }

  String getCarModel() {
    return '$_car, $_model, $uretimYili';
  }
}

方法3:用初始化列表做验证

初始化列表是构造函数执行前的逻辑,适合做参数合法性检查,写法更简洁:

void main() {
  CarCarCar car1 = CarCarCar('Toyota', 'Corolla', 1983);
  // 此处会抛出AssertionError
  CarCarCar car2 = CarCarCar('', '', 2014);

  List<CarCarCar> cars = [car1, car2];

  for (var car in cars) {
    print(car.getCarModel());
  }
}

class CarCarCar {
  String _car;
  String _model;
  int uretimYili;

  // 初始化列表中做参数验证
  CarCarCar(String car, String model, this.uretimYili)
      : assert(car.isNotEmpty, 'Car değeri bulunamadı: $car'),
        assert(model.isNotEmpty, 'Model değeri bulunamadı: $model'),
        _car = car,
        _model = model;

  String get car => _car;

  set car(String car) {
    if (car.isNotEmpty) {
      _car = car;
    } else {
      throw ArgumentError('Car değeri bulunamadı: $car');
    }
  }

  String get model => _model;

  set model(String model) {
    if (model.isNotEmpty) {
      _model = model;
    } else {
      throw ArgumentError('Model değeri bulunamadı: $model');
    }
  }

  String getCarModel() {
    return '$_car, $_model, $uretimYili';
  }
}

注意:assert默认只在开发模式生效,生产模式会被忽略。如果需要生产模式也强制验证,可替换为直接抛出ArgumentError。

方法4:结合空安全与初始化列表抛出错误

如果使用Dart 2.12+的空安全特性,可以给参数加上required,同时在初始化列表里抛出错误,确保参数非空且合法:

void main() {
  CarCarCar car1 = CarCarCar(car: 'Toyota', model: 'Corolla', uretimYili: 1983);
  // 此处会抛出ArgumentError
  CarCarCar car2 = CarCarCar(car: '', model: '', uretimYili: 2014);

  List<CarCarCar> cars = [car1, car2];

  for (var car in cars) {
    print(car.getCarModel());
  }
}

class CarCarCar {
  String _car;
  String _model;
  int uretimYili;

  CarCarCar({required String car, required String model, required this.uretimYili})
      : _car = car.isNotEmpty ? car : throw ArgumentError('Car değeri bulunamadı: $car'),
        _model = model.isNotEmpty ? model : throw ArgumentError('Model değeri bulunamadı: $model');

  String get car => _car;

  set car(String car) {
    if (car.isNotEmpty) {
      _car = car;
    } else {
      throw ArgumentError('Car değeri bulunamadı: $car');
    }
  }

  String get model => _model;

  set model(String model) {
    if (model.isNotEmpty) {
      _model = model;
    } else {
      throw ArgumentError('Model değeri bulunamadı: $model');
    }
  }

  String getCarModel() {
    return '$_car, $_model, $uretimYili';
  }
}

内容的提问来源于stack exchange,提问作者UF7K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 17:37:42