Précédent   Forum du club des développeurs et IT Pro > Dotnet > Général Dotnet > Contribuez
Contribuez Proposez vos articles, cours, tutoriels, faq, sources pour .NET
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Actualité déjà publiée
 
Outils de la discussion
Publicité
'
Vieux 17/11/2011, 14h27   #1
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 350
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 350
Points : 2 867
Points : 2 867
Envoyer un message via MSN à GuruuMeditation
Par défaut Variance en C# 4.0

Bonjour,

Mon premier article est en ligne, il parle d'une nouveauté méconnue de .NET 4.0 : la variance en C# 4.0.
Les suggestions/commentaires sont bienvenus !

Bonne lecture!
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 60
Vieux 17/11/2011, 16h31   #2
DonQuiche
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 366
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 366
Points : 2 589
Points : 2 589
Bonjour à toi.
Et avant tout, bonne initiative.

Première remarque : une légère incohérence dans le plan. La section (2b) sur la création d'interfaces et de délégués covariants est une sous-section de la covariance (2) tandis que son pendant sur les contravariants est une section à part (4), distincte à la section sur la contravariance (3).

Second remarque : dans l'introduction tu affirmes que la covariance et la contravariance ont été introduites avec dotnet 4.0. Tu corriges plus tard en précisant que dotnet supportait déjà la covariance de tableaux (mais aussi les délégués covariants). Du coup l'intro m'a un peu fait tiquer.

Troisième remarque : rien sur l'implémentation ou les performances. Le lecteur pourrait penser qu'il s'agit d'un truc du compilateur qui créerait un wrapper autour de la structure originale (ce qui impliquerait une allocation et tout le bazar). Il me semble important de préciser que covariance et contravariance sont en fait gérées au niveau du clr lui-même, par exemple en montrant que le code IL est inchangé quand on use ou non de la co/contravariance. Et donc que le concept est portable entre langages (même si certains compilateurs non à jour peuvent signaler des erreurs). Enfin, j'aurais personnellement aimé voir quelle est le coût sur les performances : je soupçonne qu'il est faible mais je ne l'ai jamais mesuré.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 10h18   #3
antoine.debyser
Membre éprouvé
 
Homme
Ingénieur développement logiciels
Inscription : mars 2011
Messages : 258
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mars 2011
Messages : 258
Points : 418
Points : 418
Bonjour,

Oula voila un sujet pas facile à traiter, je vais m'empresser de le lire, ayant quelques lacunes sur le sujet
antoine.debyser est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 13h28   #4
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 350
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 350
Points : 2 867
Points : 2 867
Envoyer un message via MSN à GuruuMeditation
Citation:
Envoyé par DonQuiche Voir le message
Bonjour à toi.
Et avant tout, bonne initiative.

Première remarque : ...
Merci pour les encouragements (et les remarques, vu qu'elles sont constructives).
Effectivement, remarques judicieuses. Je ferais bien, d'ici la fin de l'année, une version 1.1 de l'article (on peut faire ça?) en tenant compte de tout ça. Avec une section supplémentaire pour ta troisième remarque.
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 13h40   #5
Max
Responsable Relectures

 
Avatar de Max
 
Homme Maxime Gault
Artisan développeur
Inscription : mai 2007
Messages : 2 387
Détails du profil
Informations personnelles :
Nom : Homme Maxime Gault
Âge : 30
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Artisan développeur
Secteur : Industrie

Informations forums :
Inscription : mai 2007
Messages : 2 387
Points : 14 328
Points : 14 328
Salut.

D'après moi, un article sur ce sujet manquait clairement sur DVP.

Donc c'est cool de l'avoir écrit, et encore plus de l'avoir bien fait . Avec une mention particulière pour le choix des exemples, les fruits ou les animaux facilitant grandement l'approche des concepts par rapport à T et U.

Bravo .
Max est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 14h21   #6
antoine.debyser
Membre éprouvé
 
Homme
Ingénieur développement logiciels
Inscription : mars 2011
Messages : 258
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mars 2011
Messages : 258
Points : 418
Points : 418
Ca y est, j'ai lu, et commencer à digérer l'article.

Très bon point, on comprend parfaitement de quoi il s'agit, et les exemples sont bien choisit.

Citation:
Envoyé par _Max_
D'après moi, un article sur ce sujet manquait clairement sur DVP.
Exacte, il manquait même un bon article en français.

Pour autant y'a des choses flou, d'ailleurs DonQuiche a commencé à pointer le problème.
De la variance on en fait tous les jours
Code :
object toto = new MaClass()
C'est de la covariance, et le framework a toujours gérer cela. La nouveauté c'est le support de la variance sur les générique. Même si on peut pas encore tout faire, comme
Code :
IList<object> list = new List<string>()
D'ailleur je ne comprend pas le problème avec IList<T>, il doit surement avoir une raison, la méthode "CopyTo" peut-etre?
antoine.debyser est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/11/2011, 14h55   #7
tomlev
Rédacteur/Modérateur


 
Avatar de tomlev
 
Homme Thomas Levesque
Développeur .NET
Inscription : février 2004
Messages : 17 778
Détails du profil
Informations personnelles :
Nom : Homme Thomas Levesque
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2004
Messages : 17 778
Points : 34 026
Points : 34 026
Citation:
Envoyé par antoine.debyser Voir le message
D'ailleur je ne comprend pas le problème avec IList<T>, il doit surement avoir une raison, la méthode "CopyTo" peut-etre?
La covariance ne fonctionne que si le type pour lequel l'interface est covariante ne se trouve qu'en position de sortie (par exemple dans IEnumerable<T>, T est seulement en sortie, jamais en entrée). Or dans IList<T>, T se retrouve aussi bien en entrée qu'en sortie (par exemple la méthode Add(T item)), la covariance ne peut donc pas fonctionner. Si IList<T> était covariante, ça "casserait" la sécurité de type, parce qu'on pourrait avoir à l'exécution des erreurs de typage :

Code :
1
2
IList<object> list = new List<string>();
list.Add(DateTime.Now);
Si la première ligne était valide, ce code compilerait sans problème (un DateTime étant un object), mais ça planterait à l'exécution, car on ne peut pas ajouter un DateTime à une collection de String.

Le problème existe déjà pour les tableaux, qui sont covariants depuis .NET 1 :

Code :
1
2
object[] array = new string[1];
array[0] = DateTime.Now;
Ce code compile, mais provoque une ArrayTypeMismatchException. Voir cet article pour plus d'infos à ce sujet
__________________

Pas de questions techniques par MP ! Le forum est là pour ça...

Tutoriels : Les markup extensions en WPF - La sérialisation XML avec .NET (Aller plus loin) - Une visite guidée de WPF (traduction)
Projet : Dvp.NET, la librairie .NET open-source des membres de Developpez !
tomlev est actuellement connecté   Envoyer un message privé Réponse avec citation 20
Vieux 18/11/2011, 14h57   #8
DonQuiche
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 366
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 366
Points : 2 589
Points : 2 589
Citation:
Envoyé par antoine.debyser Voir le message
De la variance on en fait tous les jours
Code :
object toto = new MaClass()
C'est de la covariance, et le framework a toujours gérer cela.
Non, à strictement parler ce n'est pas de la covariance, c'est du simple polymorphisme. On parle de covariance ou de contravariance quand les règles du polymorphisme sont étendues à des compositions/fonctions/applications de type. Il faut se référer la théorie des catégories.

Pour résumer : si T assignable à U (polymorphisme), f:X->T est assignable à f:X->U (covariance).

Pour IList<T>, je pense que la raison est qu'assigner un List<String> à un IList<Object> peut ensuite conduire l'utilisateur à tenter d'ajouter autre chose qu'une string à la liste et que cela pue le design bancal à cent mètres. Cela dit cette raison n'a pas empêchée l'équipe dotnet d'autoriser la covariance de tableaux (une erreur selon moi, qui a fait débat à l'époque dans l'équipe des concepteurs de dotnet et qui a malheureusement entraîné un coût pour toutes les assignations dans des tableaux).
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 21/11/2011, 13h58   #9
antoine.debyser
Membre éprouvé
 
Homme
Ingénieur développement logiciels
Inscription : mars 2011
Messages : 258
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mars 2011
Messages : 258
Points : 418
Points : 418
Citation:
Envoyé par tomlev
Si la première ligne était valide, ce code compilerait sans problème (un DateTime étant un object), mais ça planterait à l'exécution, car on ne peut pas ajouter un DateTime à une collection de String.
Effectivement je n'avais pas pensé à ce cas.

Citation:
Envoyé par DonQuiche
Non, à strictement parler ce n'est pas de la covariance, c'est du simple polymorphisme. On parle de covariance ou de contravariance quand les règles du polymorphisme sont étendues à des compositions/fonctions/applications de type. Il faut se référer la théorie des catégories.
Je ne suis pas d'accord.
Le concept de polymorphisme utilise sur les concepts de covariance et contravariance. C'est surement pour cela qu'on en parle très peu.
Bien sur la variance n'est pas suffisante pour définir le polymorphisme, il faut aussi lui rajouter des concepts lié au morphisme (mathématique)
antoine.debyser est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/11/2011, 14h51   #10
DonQuiche
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 366
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 366
Points : 2 589
Points : 2 589
@Antione Debyser
Désolé mais je vois difficilement comment.

Pour reprendre la théorie des catégories d'où sont issues ces notions, un foncteur covariant/contravariant est défini comme l'association de deux objets de catégories différentes qui préserve l'identité des morphismes et leurs compositions. Autrement dit : pour définir un foncteur (et les notions de covariance/contravariance), on n'a besoin que des seules notions de morphisme et de catégorie (cette dernière étant elle-même définie à partir du concept de morphisme).

Quant au polymorphisme, il est simplement défini comme un ensemble de morphismes distincts ayant la même catégorie cible : chien et chat sont tous deux assignables à animal en langage objet. Je ne vois pas où faire intervenir la covariance et la contravariance là-dedans.

Et, pour revenir à l'informatique, qui découle des mathématiques mais sans les calquer, je n'ai jamais vu appelée covariance une simple assignation. Et à mon humble avis ça ne peut que créer de la confusion.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/11/2011, 10h38   #11
antoine.debyser
Membre éprouvé
 
Homme
Ingénieur développement logiciels
Inscription : mars 2011
Messages : 258
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mars 2011
Messages : 258
Points : 418
Points : 418
Citation:
Envoyé par DonQuiche
Et à mon humble avis ça ne peut que créer de la confusion.
C'est pas faux

Citation:
un foncteur covariant/contravariant
j'ajouterai que l'assignation est foncteur, même si c'est l'un des plus basique.

Citation:
Quant au polymorphisme, il est simplement défini comme un ensemble de morphismes distincts ayant la même catégorie cible : chien et chat sont tous deux assignables à animal en langage objet. Je ne vois pas où faire intervenir la covariance et la contravariance là-dedans.
Justement de le fait qu'ils appartiennent à la même catégorie cible.
Si on ne pouvais pas faire l'assignation sur une variable plus faiblement typé, le polymorphisme n’aurait aucun intérêt.
antoine.debyser est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/11/2011, 14h07   #12
DonQuiche
Expert Confirmé
 
Avatar de DonQuiche
 
Inscription : septembre 2010
Messages : 1 366
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 366
Points : 2 589
Points : 2 589
Je comprends pourquoi nous n'arrivions pas à discuter.

Tu considères l'assignation comme un foncteur. Autrement dit, tu considères que le morphisme dans un langage objet est définit comme la capacité abstraite de substituer un objet à un autre et il est effectivement définit ainsi conceptuellement. Mais, dans les faits, il me semble que le morphisme est en fait définit en langage objet par la capacité d'assigner un type vers un autre.

Et ça me semble plus cohérent puisque, si l'on suit ta logique, tu te sens obligé de faire appel à la notion de covariance pour définir le morphisme (*) en programmation objet alors qu'au contraire le morphisme est un pré-requis pour définir la covariance en mathématiques. Qui plus est, si l'assignation est un foncteur, alors, lors de l'appel d'un délégué, ce n'est plus le délégué lui-même qui peut être covariant mais les assignations de ses paramètres.

(*) Le polymorphisme n'est qu'un cas particulier où le langage permet d'avoir plusieurs classes filles. On pourrait très bien imaginer la même problématique avec un langage qui n'autoriserait qu'une seule classe fille, ce qui serait moins puissant mais conserverait un intérêt pratique.

Bref, pour ma part je trouve plus explicite, élégant et consistant de considérer que le (poly)morphisme est définit en programmation objet comme la capacité à assigner un type à un autre et la covariance comme la capacité à assigner l'application F d'un type à l'application F d'un autre type.
DonQuiche est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 22/11/2011, 14h28   #13
tomlev
Rédacteur/Modérateur


 
Avatar de tomlev
 
Homme Thomas Levesque
Développeur .NET
Inscription : février 2004
Messages : 17 778
Détails du profil
Informations personnelles :
Nom : Homme Thomas Levesque
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2004
Messages : 17 778
Points : 34 026
Points : 34 026
Oula les gars, ça devient vraiment high level votre discussion, je suis un peu perdu
__________________

Pas de questions techniques par MP ! Le forum est là pour ça...

Tutoriels : Les markup extensions en WPF - La sérialisation XML avec .NET (Aller plus loin) - Une visite guidée de WPF (traduction)
Projet : Dvp.NET, la librairie .NET open-source des membres de Developpez !
tomlev est actuellement connecté   Envoyer un message privé Réponse avec citation 11
Vieux 22/11/2011, 17h24   #14
antoine.debyser
Membre éprouvé
 
Homme
Ingénieur développement logiciels
Inscription : mars 2011
Messages : 258
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : mars 2011
Messages : 258
Points : 418
Points : 418
Citation:
Envoyé par DonQuiche
Tu considères l'assignation comme un foncteur. Autrement dit, tu considères que le morphisme dans un langage objet est définit comme la capacité abstraite de substituer un objet à un autre et il est effectivement définit ainsi conceptuellement. Mais, dans les faits, il me semble que le morphisme est en fait définit en langage objet par la capacité d'assigner un type vers un autre.
Tout à fait d'accord pour l'assignation. Pour le morphisme d’instinct je dirai oui, et dans ce cas on peut toujours considérer l'assignation comme un functeur.

Citation:
Envoyé par DonQuiche
Et ça me semble plus cohérent puisque, si l'on suit ta logique, tu te sens obligé de faire appel à la notion de covariance pour définir le morphisme (*) en programmation objet
Oui est non. Car la covariance est définit sur le morphisme (je ne parle pas de polymorphisme), la covariance est un cas particulier.

Citation:
Envoyé par DonQuiche
Bref, pour ma part je trouve plus explicite, élégant et consistant de considérer que le (poly)morphisme est définit en programmation objet comme la capacité à assigner un type à un autre et la covariance comme la capacité à assigner l'application F d'un type à l'application F d'un autre type.
C'est effectivement une façons concrète d'expliquer le polymorphisme à des débutant (les exemples c'est bien ^^). Mais elle relève d'un petit abus.
Du au fait qu'on utilise le polymorphisme principalement par sous-typage.
Le polymorphisme c'est l'abstraction qui permet de travailler sur les membres d'un objet sans connaitre la nature final de l'objet.
En tout cas je trouve cela plus juste.

Bon après c'est vrai que je ne suis pas forcement très alaise avec les derniers évolution sur les théories des langages (notament F-Bounds, et le typage de second ordre).
D'ailleurs j'ai l'impression que j'ai une vision classique du typage, et toi une vision plus moderne (avec le typage de second ordre).
antoine.debyser est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2011, 16h50   #15
GuruuMeditation
Expert Confirmé
 
Avatar de GuruuMeditation
 
Homme Olivier Matis
.Net Architect
Inscription : octobre 2010
Messages : 1 350
Détails du profil
Informations personnelles :
Nom : Homme Olivier Matis
Âge : 38
Localisation : Belgique

Informations professionnelles :
Activité : .Net Architect
Secteur : Conseil

Informations forums :
Inscription : octobre 2010
Messages : 1 350
Points : 2 867
Points : 2 867
Envoyer un message via MSN à GuruuMeditation
Je vous remercie pour vos commentaires, ça fait plaisir (Et me motive pour un autre article!).
La discussion est très intéressante mais, comme Thomas le dit, je commence à être perdu. Ce qui est grave quand on est le rédacteur
__________________
Microsoft MVP : Visual C#

MCPD - Windows Phone Developer
MCPD - Windows Developer 4

http://www.guruumeditation.net

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”
(Edsger W. Dijkstra)
GuruuMeditation est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/11/2011, 17h17   #16
tomlev
Rédacteur/Modérateur


 
Avatar de tomlev
 
Homme Thomas Levesque
Développeur .NET
Inscription : février 2004
Messages : 17 778
Détails du profil
Informations personnelles :
Nom : Homme Thomas Levesque
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur .NET
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2004
Messages : 17 778
Points : 34 026
Points : 34 026
Citation:
Envoyé par GuruuMeditation Voir le message
La discussion est très intéressante mais, comme Thomas le dit, je commence à être perdu. Ce qui est grave quand on est le rédacteur
Comme quoi on est pas obligé d'être super fort en théorie mathématique pour pour comprendre la covariance
__________________

Pas de questions techniques par MP ! Le forum est là pour ça...

Tutoriels : Les markup extensions en WPF - La sérialisation XML avec .NET (Aller plus loin) - Une visite guidée de WPF (traduction)
Projet : Dvp.NET, la librairie .NET open-source des membres de Developpez !
tomlev est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/11/2011, 14h31   #17
worm83
Membre expérimenté
 
Avatar de worm83
 
Homme worm
Consultant .Net
Inscription : février 2010
Messages : 276
Détails du profil
Informations personnelles :
Nom : Homme worm
Âge : 30
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultant .Net
Secteur : Conseil

Informations forums :
Inscription : février 2010
Messages : 276
Points : 555
Points : 555
Article très intéressant, exemple bien choisis, la discussion aussi. Ça force a revoir/apprendre des concepts de la programmation objet.

sans vouloir faire le rabat joie une petite coquille qui m'a sauté aux yeux :
Citation:

Si nous avons une liste de Dog, on ceci est valide :
__________________
"Le train de tes injures roule sur le rail de mon indifférence."

"Monde de merde !!"

Georges Abitbol.
worm83 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/05/2012, 08h35   #18
Er3van
Modérateur
 
Avatar de Er3van
 
Homme Clément Lehalle
Architecte Logiciel
Inscription : avril 2008
Messages : 1 426
Détails du profil
Informations personnelles :
Nom : Homme Clément Lehalle
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 426
Points : 2 377
Points : 2 377
Citation:
Envoyé par DonQuiche Voir le message
Enfin, j'aurais personnellement aimé voir quelle est le coût sur les performances : je soupçonne qu'il est faible mais je ne l'ai jamais mesuré.
Je déterre la discussion car je me suis posé la question hier.
Est-ce que quelqu'un a eu l'occasion de tester ce point?

Par défaut je ne pense pas que ça ait d'impact sur les performances, mais la question est judicieuse et j'avoue que je ne sais pas du tout si cela a un impact au niveau du CLR, particulièrement sur des gros volumes d'objets.

A défaut de réponse j'en donnerai surement une d'ici quelques semaines !
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Actualité déjà publiée
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 16h05.


 
 
 
 
Partenaires

Hébergement Web