151 votes

Comment cloner un objet (copie profonde) dans Dart ?

Existe-t-il un moyen, supporté par le langage, de faire une copie complète (profonde) d'un objet dans Dart ?

Secondaire uniquement ; existe-t-il plusieurs façons de procéder, et quelles sont les différences ?

Merci pour la clarification !

11voto

Maicon Perin Points 15

Pour copier un objet sans référence, la solution que j'ai trouvée est similaire à celle postée ici, cependant si l'objet contient MAP ou LIST vous devez le faire de cette façon :

class Item {
  int id;
  String nome;
  String email;
  bool logado;
  Map mapa;
  List lista;
  Item({this.id, this.nome, this.email, this.logado, this.mapa, this.lista});

  Item copyWith({ int id, String nome, String email, bool logado, Map mapa, List lista }) {
    return Item(
      id: id ?? this.id,
      nome: nome ?? this.nome,
      email: email ?? this.email,
      logado: logado ?? this.logado,
      mapa: mapa ?? Map.from(this.mapa ?? {}),
      lista: lista ?? List.from(this.lista ?? []),
    );
  }
}

Item item1 = Item(
    id: 1,
    nome: 'João Silva',
    email: 'joaosilva@gmail.com',
    logado: true,
    mapa: {
      'chave1': 'valor1',
      'chave2': 'valor2',
    },
    lista: ['1', '2'],
  );

// -----------------
// copy and change data
Item item2 = item1.copyWith(
    id: 2,
    nome: 'Pedro de Nobrega',
    lista: ['4', '5', '6', '7', '8']
  );

// -----------------
// copy and not change data
Item item3 = item1.copyWith();

// -----------------
// copy and change a specific key of Map or List
Item item4 = item1.copyWith();
item4.mapa['chave2'] = 'valor2New';

Voir un exemple sur dartpad

https://dartpad.dev/f114ef18700a41a3aa04a4837c13c70e

7voto

Baig Points 393

Elle ne fonctionne que pour les types d'objets qui peuvent être représentés par JSON.

ClassName newObj = ClassName.fromMap(obj.toMap());

o

ClassName newObj = ClassName.fromJson(obj.toJson());

7voto

En référence à la réponse de @Phill Wiggins, voici un exemple avec un constructeur .from et des paramètres nommés :

class SomeObject{
  String parameter1;
  String parameter2;

  // Normal Constructor
  SomeObject({
    this.parameter1,
    this.parameter2,
  });

  // .from Constructor for copying
  factory SomeObject.from(SomeObject objectA){
    return SomeObject(
      parameter1: objectA.parameter1,
      parameter2: objectA.parameter2,
    );
  }

}

Ensuite, faites-le là où vous voulez copier :

SomeObject a = SomeObject(parameter1: "param1", parameter2: "param2");
SomeObject copyOfA = SomeObject.from(a);

6voto

Gauranga Points 510

Disons que vous avez une classe

Class DailyInfo

  { 
     String xxx;
  }

Créer un nouveau clone de l'objet de classe dailyInfo par

 DailyInfo newDailyInfo =  new DailyInfo.fromJson(dailyInfo.toJson());

Pour que cela fonctionne, votre classe doit avoir implémenté

 factory DailyInfo.fromJson(Map<String, dynamic> json) => _$DailyInfoFromJson(json);

Map<String, dynamic> toJson() => _$DailyInfoToJson(this);

ce qui peut être fait en rendant la classe sérialisable en utilisant

@JsonSerializable(fieldRename: FieldRename.snake, includeIfNull: false)
Class DailyInfo{ 
 String xxx;
}

5voto

Baker Points 2243

Il n'y a pas d'API pour le clonage/la copie profonde intégrée à Dart.

Nous devons écrire clone() méthodes nous-mêmes & (pour le meilleur ou pour le pire) les auteurs de Dart le veulent ainsi.

Copie profonde de l'objet /w Liste

Si l'objet que l'on clone a une List d'Objets en tant que champ, nous devons List.generate ce champ et ces Objets ont besoin de leur propre méthode de clonage.

Exemple de méthode de clonage ( copyWith() ) sur un Order avec une classe List d'objets (et ces objets imbriqués ont également une copyWith() ) :

  Order copyWith({
    int? id,
    Customer? customer,
    List<OrderItem>? items,
  }) {
    return Order(
      id: id ?? this.id,
      customer: customer ?? this.customer,
      //items: items ?? this.items, // this will NOT work, it references 
      items: items ?? List.generate(this.items.length, (i) => this.items[i].copyWith()),
    );
  }

Gunter mentionne ceci ici .

Note, nous ne peut pas utiliser List.from(items) ni [...items] . Ces deux éléments ne font que copies superficielles .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X