sebmafate
Messages postés4936Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention14 février 2014
-
30 nov. 2005 à 16:14
kimwu
Messages postés40Date d'inscriptiondimanche 23 novembre 2003StatutMembreDernière intervention25 juin 2011
-
18 mars 2011 à 21:04
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
kimwu
Messages postés40Date d'inscriptiondimanche 23 novembre 2003StatutMembreDernière intervention25 juin 20111 18 mars 2011 à 21:04
Avec plaisir..
J'espere qu'elle pourra t'être utilse, perso je m'en sert toujours
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 17 mars 2011 à 10:11
J'aime bien cette astuce du Serialize. A retenir, mercu kimwu
kimwu
Messages postés40Date d'inscriptiondimanche 23 novembre 2003StatutMembreDernière intervention25 juin 20111 3 nov. 2009 à 11:53
J'oubliais : En fait ce que cela fait est de serializer puis de suite DEserializer .. du coup cela crée un clone parfais (Deep clone et non Shalow clone qui eux garde les même references d'objets)
kimwu
Messages postés40Date d'inscriptiondimanche 23 novembre 2003StatutMembreDernière intervention25 juin 20111 3 nov. 2009 à 11:50
Bonjour,
Je sais que cette source date un peu.. mais je voulais apporter une petite contribution - DeepClone :
public static object DeepClone(object obj)
{
object objResult = null;
using (MemoryStream ms =
new MemoryStream())
{
BinaryFormatter bf =
new BinaryFormatter();
bf.Serialize(ms, obj);
J'ai essayé cette source et elle fonctionne très bien pour le moment. Je ne suis pas allé plus en détail, car tout ce que j''avais à faire était de deepcloner une generic list(of string).. mais d'apres les commentaires des auteurs cela pourrait deepcloner des objets assez complexes.
credit : http://www.code-magazine.com/Article.aspx?quickid=0601121
:)
spikeyz
Messages postés10Date d'inscriptionvendredi 17 octobre 2003StatutMembreDernière intervention21 novembre 2008 28 août 2006 à 16:46
Voila moi je viens de finir une methode un peu plus complete que celle-ci si ca interresse quelqu'un.
public object Clone()
{
//Creation de la nouvelle instance de l'objet
Object newObject = Activator.CreateInstance(this.GetType());
//Recuperation de toutes les proprietes de l'objet
PropertyInfo[] infos = newObject.GetType().GetProperties();
foreach (PropertyInfo info in infos)
{
//Test de la propriete pour savoir si elle supporte l'interface ICloneable
Type ICloneType = info.PropertyType.GetInterface("ICloneable", true);
if (ICloneType != null)
{
//Recuperation de l'interface ICloneable de l'objet
ICloneable IClone = (ICloneable)info.GetValue(this, null);
//utilisation de la methode clone() pour assigner la nouvelle valeur de la propriete
info.SetValue(newObject, IClone.Clone(), null);
}
else
//Si la propriete ne supporte pas l'interface, assignation juste de la valeur
info.SetValue(newObject, info.GetValue(this, null), null);
//Test de la propriete pour savoir si elle supporte l'interface IEnumerable
Type IEnumerabletype = info.PropertyType.GetInterface("IEnumerable", true);
if (IEnumerabletype != null)
{
//Recuperation de l'interface IEnumerable de la propriete
IEnumerable IEnum = (IEnumerable)info.GetValue(this, null);
Type IListType = info.PropertyType.GetInterface("IList", true);
Type IDicType = info.PropertyType.GetInterface("IDictionary", true);
int j = 0;
if (IListType != null)
{
//recuperation de l'interface IList
IList list = (IList)info.GetValue(newObject,null);
foreach (Object obj in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = obj.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable clone = (ICloneable)obj;
list[j] = clone.Clone();
}
j++;
}
}
else if (IDicType != null)
{
//Recuperation de l'interface IDictionary
IDictionary dic = (IDictionary)info.GetValue(newObject,null);
j = 0;
foreach (DictionaryEntry de in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
//Recuperation de tous les champs de cette instance
FieldInfo[] fields = newObject.GetType().GetFields();
foreach (FieldInfo fi in this.GetType().GetFields())
{
//Test du champs pour savoir si il supporte l'interface ICloneable
Type ICloneType = fi.FieldType.GetInterface("ICloneable", true);
if (ICloneType != null)
{
//Recuperation de l'interface ICloneable de l'objet
ICloneable IClone = (ICloneable)fi.GetValue(this);
//utilisation de la methode clone() pour assigner la nouvelle valeur du champs
fi.SetValue(newObject, IClone.Clone());
}
else
{
//Si le champs ne supporte pas l'interface, assignation juste du champs
fi.SetValue(newObject, fi.GetValue(this));
}
//Test du champs pour savoir si il support l'interface IEnumerable
Type IEnumerabletype = fi.FieldType.GetInterface("IEnumerable", true);
if (IEnumerabletype != null)
{
//Recuperation de l'interface IEnumerable du champs
IEnumerable IEnum = (IEnumerable)fi.GetValue(this);
Type IListType = fi.FieldType.GetInterface("IList", true);
Type IDicType = fi.FieldType.GetInterface("IDictionary", true);
int j = 0;
if (IListType != null)
{
//recuperation de l'interface IList
IList list = (IList)fi.GetValue(newObject);
foreach (Object obj in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = obj.GetType().GetInterface("ICloneable", true);
foreach (DictionaryEntry de in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
Bubuss
Messages postés147Date d'inscriptionsamedi 7 juin 2003StatutMembreDernière intervention 8 décembre 2007 8 août 2006 à 11:07
Chapeau pour ce code, je l'ai intégré au mien mais comme mes classes héritaient déjà dune autre classe j'ai juste récupérer ta fonction et je l'appelle ponctuellement! ça marche très bien!
Je signale cependant un bug car pour certaine propriété de mes objets je n'avais aucune instanciation de faite donc j'ai rajouté après le premier foreach item:
if (Item.GetValue(vObj, null) != null)
{
(... code ...)
}
Voilà je te remercie pour le partage de ce code Salut!
PS : Je crois que cette vérification est nécessaire seulement dans le premier foreach car je ne penses pas que les champs peuvent être = null
TheSaib
Messages postés2367Date d'inscriptionmardi 17 avril 2001StatutMembreDernière intervention26 décembre 200723 1 déc. 2005 à 00:21
Tu as benchmarqué ou pas ?
Si à l'occasion tu le fais ca m'interresserait :)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 1 déc. 2005 à 00:16
moins rapide, je suppose, que de tout cloner soit-même, invoquant en cascade, la methode Clone des Classes filles qui le supporte
reste que là, les fistons sont bien clonés, et que l'on a pas a y retoucher sans cesse...
TheSaib
Messages postés2367Date d'inscriptionmardi 17 avril 2001StatutMembreDernière intervention26 décembre 200723 1 déc. 2005 à 00:12
En terme de perf çà donne quoi ?
sebmafate
Messages postés4936Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention14 février 201437 30 nov. 2005 à 16:51
oui et non... comme on me l'a fait remarqué y a pas si longtemps... C# peut aussi vouloir Mono... ou tout autre chose... du moment qu'il existe un compilateur...
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 30 nov. 2005 à 16:43
Je suis en train de gonfler la classe, avec la gestion des tableaux, etc...
désolé pour la case .Net .... j'avais pas fais gaffe à sa présence, je veux dire, C# implique .Net (enfin, me semble-t'il ^^)
sebmafate
Messages postés4936Date d'inscriptionlundi 17 février 2003StatutMembreDernière intervention14 février 201437 30 nov. 2005 à 16:14
Nickel... mais n'oublie pas de cocher la case 'Ceci est une source .net' ;)
18 mars 2011 à 21:04
J'espere qu'elle pourra t'être utilse, perso je m'en sert toujours
17 mars 2011 à 10:11
3 nov. 2009 à 11:53
3 nov. 2009 à 11:50
Je sais que cette source date un peu.. mais je voulais apporter une petite contribution - DeepClone :
public static object DeepClone(object obj)
{
object objResult = null;
using (MemoryStream ms =
new MemoryStream())
{
BinaryFormatter bf =
new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Position = 0;
objResult = bf.Deserialize(ms);
}
return objResult;
}
J'ai essayé cette source et elle fonctionne très bien pour le moment. Je ne suis pas allé plus en détail, car tout ce que j''avais à faire était de deepcloner une generic list(of string).. mais d'apres les commentaires des auteurs cela pourrait deepcloner des objets assez complexes.
credit : http://www.code-magazine.com/Article.aspx?quickid=0601121
:)
28 août 2006 à 16:46
public object Clone()
{
//Creation de la nouvelle instance de l'objet
Object newObject = Activator.CreateInstance(this.GetType());
//Recuperation de toutes les proprietes de l'objet
PropertyInfo[] infos = newObject.GetType().GetProperties();
foreach (PropertyInfo info in infos)
{
//Test de la propriete pour savoir si elle supporte l'interface ICloneable
Type ICloneType = info.PropertyType.GetInterface("ICloneable", true);
if (ICloneType != null)
{
//Recuperation de l'interface ICloneable de l'objet
ICloneable IClone = (ICloneable)info.GetValue(this, null);
//utilisation de la methode clone() pour assigner la nouvelle valeur de la propriete
info.SetValue(newObject, IClone.Clone(), null);
}
else
//Si la propriete ne supporte pas l'interface, assignation juste de la valeur
info.SetValue(newObject, info.GetValue(this, null), null);
//Test de la propriete pour savoir si elle supporte l'interface IEnumerable
Type IEnumerabletype = info.PropertyType.GetInterface("IEnumerable", true);
if (IEnumerabletype != null)
{
//Recuperation de l'interface IEnumerable de la propriete
IEnumerable IEnum = (IEnumerable)info.GetValue(this, null);
Type IListType = info.PropertyType.GetInterface("IList", true);
Type IDicType = info.PropertyType.GetInterface("IDictionary", true);
int j = 0;
if (IListType != null)
{
//recuperation de l'interface IList
IList list = (IList)info.GetValue(newObject,null);
foreach (Object obj in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = obj.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable clone = (ICloneable)obj;
list[j] = clone.Clone();
}
j++;
}
}
else if (IDicType != null)
{
//Recuperation de l'interface IDictionary
IDictionary dic = (IDictionary)info.GetValue(newObject,null);
j = 0;
foreach (DictionaryEntry de in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable clone = (ICloneable)de.Value;
dic[de.Key] = clone.Clone();
}
j++;
}
}
}
}
//Recuperation de tous les champs de cette instance
FieldInfo[] fields = newObject.GetType().GetFields();
foreach (FieldInfo fi in this.GetType().GetFields())
{
//Test du champs pour savoir si il supporte l'interface ICloneable
Type ICloneType = fi.FieldType.GetInterface("ICloneable", true);
if (ICloneType != null)
{
//Recuperation de l'interface ICloneable de l'objet
ICloneable IClone = (ICloneable)fi.GetValue(this);
//utilisation de la methode clone() pour assigner la nouvelle valeur du champs
fi.SetValue(newObject, IClone.Clone());
}
else
{
//Si le champs ne supporte pas l'interface, assignation juste du champs
fi.SetValue(newObject, fi.GetValue(this));
}
//Test du champs pour savoir si il support l'interface IEnumerable
Type IEnumerabletype = fi.FieldType.GetInterface("IEnumerable", true);
if (IEnumerabletype != null)
{
//Recuperation de l'interface IEnumerable du champs
IEnumerable IEnum = (IEnumerable)fi.GetValue(this);
Type IListType = fi.FieldType.GetInterface("IList", true);
Type IDicType = fi.FieldType.GetInterface("IDictionary", true);
int j = 0;
if (IListType != null)
{
//recuperation de l'interface IList
IList list = (IList)fi.GetValue(newObject);
foreach (Object obj in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = obj.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable clone = (ICloneable)obj;
list[j] = clone.Clone();
}
j++;
}
}
else if(IDicType != null)
{
//Recuperation de l'interface IDictionary
IDictionary dic = (IDictionary)fi.GetValue(newObject);
j = 0;
foreach (DictionaryEntry de in IEnum)
{
//Test de l'objet pour savoir si il supporte l'interface ICloneable
ICloneType = de.Value.GetType().GetInterface("ICloneable", true);
if (ICloneType != null)
{
ICloneable clone = (ICloneable)de.Value;
dic[de.Key] = clone.Clone();
}
j++;
}
}
}
}
return newObject;
}
8 août 2006 à 11:07
Je signale cependant un bug car pour certaine propriété de mes objets je n'avais aucune instanciation de faite donc j'ai rajouté après le premier foreach item:
if (Item.GetValue(vObj, null) != null)
{
(... code ...)
}
Voilà je te remercie pour le partage de ce code Salut!
PS : Je crois que cette vérification est nécessaire seulement dans le premier foreach car je ne penses pas que les champs peuvent être = null
1 déc. 2005 à 00:21
Si à l'occasion tu le fais ca m'interresserait :)
1 déc. 2005 à 00:16
reste que là, les fistons sont bien clonés, et que l'on a pas a y retoucher sans cesse...
1 déc. 2005 à 00:12
30 nov. 2005 à 16:51
30 nov. 2005 à 16:43
désolé pour la case .Net .... j'avais pas fais gaffe à sa présence, je veux dire, C# implique .Net (enfin, me semble-t'il ^^)
30 nov. 2005 à 16:14