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
相关产品推荐
相关产品推荐

