Dart 动态获取 class 属性 值

Dart get class property value dynamically

我有一个 Class YearlyReportArchive,我希望能够动态读取单个月份的值,并添加所有月份和 return 总和。

有没有比我想出的更好的解决方案?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mbpt/utils/tools/validate_double.dart';

class YearlyReportArchive {
  final double jan;
  final double feb;
  final double mar;
  final double apr;
  final double may;
  final double jun;
  final double jul;
  final double aug;
  final double sep;
  final double oct;
  final double nov;
  final double dec;

  YearlyReportArchive(
      {required this.jan,
      required this.feb,
      required this.mar,
      required this.apr,
      required this.may,
      required this.jun,
      required this.jul,
      required this.aug,
      required this.sep,
      required this.oct,
      required this.nov,
      required this.dec});

  double monthlyTotal(String monthName) {
    switch (monthName) {
      case 'jan':
        return jan;
      case 'feb':
        return feb;
      case 'mar':
        return mar;
//...
      default:
        return 0.00;
    }
  }

  double yearlyTotal() {
    return jan +
        feb +
        mar +
        apr +
        may +
        jun +
        jul +
        aug +
        oct +
        sep +
        nov +
        dec;
  }

  factory YearlyReportArchive.fromDoc(DocumentSnapshot doc) {
    Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
    return YearlyReportArchive(
        jan: validateDouble(data['jan']),
        feb: validateDouble(data['feb']),
        mar: validateDouble(data['mar']),
        apr: validateDouble(data['apr']),
        may: validateDouble(data['may']),
        jun: validateDouble(data['jun']),
        jul: validateDouble(data['jul']),
        aug: validateDouble(data['aug']),
        sep: validateDouble(data['sep']),
        oct: validateDouble(data['oct']),
        nov: validateDouble(data['nov']),
        dec: validateDouble(data['dec']));
  }
}

首先你可以创建一个enumerated type来支持你的月份:

enum Months {
  january, february, march, april //...// , december
}

这些月份有一个字符串表示(例如 jan)。为了表示它们,您可以创建一个常量映射,或者对您的枚举类型进行扩展:

  • 正在创建常量映射:
Map<Months, String> monthStrings = {
 Months.january: "jan",
 Months.february: "feb",
 Months.march: "mar",
 Months.april: "apr"
};
  • 正在为您的类型创建
extension monthName on Months {

  String get name {
    switch (this) {
      case Months.january:
        return 'jan';
      case Months.February:
        return 'feb';
      default:
        return "";
    }
  }
}

这样您就可以在 class 上访问这些值,例如:

  • 在你的双打上,你可以有一张地图将每个月与其值相关联:
class YearlyReportArchive {
Map<Months, double> values;
}
  • 每当你需要求和时,你可以使用 for:
double answer = 0;
 for (double value in values.values){
   answer += value;
 }
  • 当你需要字符串表示时,访问你制作的Map或者扩展方法:
print(monthStrings[Months.january]);
var m = Months.january;
print(m.name());

您也可以创建一个包含所有这些方法和定义的 class,但一般概念是相同的。