我想利用Dart的新(实验性)enum功能,而不是使用静态const字符串堆栈,但是enum使用JSON 序列化/反序列化变量的最佳方法是什么?我已经通过这种方式使其工作,但是肯定有更好的解决方案:
enum Status {
none,
running,
stopped,
paused
}
Status status1 = Status.stopped;
Status status2 = Status.none;
String json = JSON.encode(status1.index);
print(json); // prints 2
int index = JSON.decode(json);
status2 = Status.values[index];
print(status2); // prints Status.stopped
Run Code Online (Sandbox Code Playgroud)
如果使用索引进行序列化,则可能会被锁定为永远使枚举始终保持相同的顺序,因此我更喜欢使用某种String形式。有人知道了吗?
Ano*_*P.A 13
使用枚举的name属性和 byName方法
这是一个示例代码来展示如何使用它:
import 'dart:convert';
void main() {
Person raj = Person(name: 'Raj', favIcecream: Icecream.pista);
print(raj.toJson());
Person rajV2 = Person.fromJson(raj.toJson());
print(rajV2.toJson());
final isBothInstanceEqual = raj == rajV2;
print('> Both instancecs are equal is $isBothInstanceEqual');
}
enum Icecream {
vanilla,
pista,
strawberry,
}
class Person {
String name;
Icecream favIcecream;
Person({
required this.name,
required this.favIcecream,
});
Map<String, dynamic> toMap() {
return {
'name': name,
'favIcecream': favIcecream.name, // <- this is how you should save
};
}
factory Person.fromMap(Map<String, dynamic> map) {
return Person(
name: map['name'] ?? '',
favIcecream: Icecream.values.byName(map['favIcecream']), // <- back to enum
);
}
String toJson() => json.encode(toMap());
factory Person.fromJson(String source) => Person.fromMap(json.decode(source));
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is Person &&
other.name == name &&
other.favIcecream == favIcecream;
}
@override
int get hashCode => name.hashCode ^ favIcecream.hashCode;
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Dart 2.15.0+ (Flutter 2.8.0+)
您可以使用name添加到枚举的新属性。
要将其转换为 json 值,你可以这样做
Status status1 = Status.stopped;
String jsonValue = status1.name;
print(jsonValue); // prints "stopped"
Run Code Online (Sandbox Code Playgroud)
要将其转换回枚举,您可以这样做
String jsonValue = "stopped";
Status deserializedStatus = Status.values.byName(jsonValue);
print(deserializedStatus); // prints "Status.stopped"
Run Code Online (Sandbox Code Playgroud)
正如先前提出的答案之一,如果您在客户端和服务器上共享相同的实现,那么序列化名称是我认为的最佳方法,并尊重SOLID设计中的开放/封闭原则,并指出:
“软件实体(类,模块,功能等)应打开以进行扩展,但应关闭以进行修改”
如果您需要将另一个成员添加到Enum中,则使用索引而不是名称将混乱代码的所有逻辑。但是,使用名称将允许扩展名。
最后,对枚举的名称进行序列化,然后对其进行正确的反序列化,编写一个小函数,将一个枚举以字符串形式给出,遍历枚举的所有成员并返回适当的枚举。如:
Status getStatusFromString(String statusAsString) {
for (Status element in Status.values) {
if (element.toString() == statusAsString) {
return element;
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
因此,要序列化:
Status status1 = Status.stopped;
String json = JSON.encode(status1.toString());
print(json) // prints {"Status.stopped"}
Run Code Online (Sandbox Code Playgroud)
并反序列化:
String statusAsString = JSON.decode(json);
Status deserializedStatus = getStatusFromString(statusAsString);
print(deserializedStatus) // prints Status.stopped
Run Code Online (Sandbox Code Playgroud)
这是到目前为止我发现的最好方法。希望这可以帮助 !
| 归档时间: |
|
| 查看次数: |
2315 次 |
| 最近记录: |