IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

C# et assignation [Débutant]


Sujet :

C#

  1. #1
    Membre régulier Avatar de kerinel
    Profil pro
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 107
    Points
    107
    Par défaut C# et assignation
    Bonjour,
    je lisais la (le ? ) msdn pour faire des événements personnalisés et plus particulièrement cette page.
    Or il y a un truc qui m'a interpellé, c'est ceci qui est dans l'exemple, classe Publisher:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Make a temporary copy of the event to avoid possibility of
    // a race condition if the last subscriber unsubscribes
    // immediately after the null check and before the event is raised.
    EventHandler<CustomEventArgs> handler = RaiseCustomEvent;
    et plus particulièrement l'affirmation que l'opérateur = réalise une copie de l'objet et non une assignation.
    D'où ma question : comment sait-on lorsque = est une assignation et lorsque = est un clonage ? Car du coup j'ai un peu l'impression de ne plus trop coder objet là.
    Merci
    Bon code,
    kerinel

  2. #2
    Membre chevronné Avatar de Er3van
    Homme Profil pro
    Architecte Logiciel
    Inscrit en
    Avril 2008
    Messages
    1 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte Logiciel
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2008
    Messages : 1 430
    Points : 2 227
    Points
    2 227
    Par défaut
    On devrait dire "le" MSDN (car MS Developer Network), mais j'ai toujours dit "la", sans doute car c'est une documentation en ligne et qu'on dit "la" JavaDoc...

    ...mais revenons à la question initiale :

    RaiseCustomEvent étant un évènement, en faisant cette assignation tu crées en réalité un nouveau délégué, tu ne fais pas une affectation.

    Cet article te l'expliquera mieux que moi je pense :Delegates are immutable
    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 --

  3. #3
    Membre régulier Avatar de kerinel
    Profil pro
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 107
    Points
    107
    Par défaut
    Bonjour,
    merci pour la réponse tardive et désolé pour le retour tardif

    Ici je n'utilise pas l'opérande += ou -= mais bien = l'objectif étant de faire une "copie de". Or pour moi si j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    myObject o1 = new MyObject();
     
    myObject o2 = o1;
    o2 et o1 sont bien deux références sur le même objet. et dans le code précédent il n'y a donc pas de duplication ou de modification de l'event.

    Merci,
    Bon code,
    kerinel

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Citation Envoyé par kerinel Voir le message
    Bonjour,
    merci pour la réponse tardive et désolé pour le retour tardif

    Ici je n'utilise pas l'opérande += ou -= mais bien = l'objectif étant de faire une "copie de". Or pour moi si j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    myObject o1 = new MyObject();
     
    myObject o2 = o1;
    o2 et o1 sont bien deux références sur le même objet. et dans le code précédent il n'y a donc pas de duplication ou de modification de l'event.

    Merci,
    Bon code,
    kerinel
    C'est pas toujours vrai! C'est uniquement les types références qui sont concernés par ton affirmation

    Exemple avec un type valeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    void Main()
    {
    	MyType a = new MyType();
    	MyType b = a;
     
    	Console.WriteLine(a.i); //0
    	Console.WriteLine(b.i); //0
     
    	b.Foo();
     
    	Console.WriteLine(a.i); //0
    	Console.WriteLine(b.i); //1
    }
     
    public struct MyType
    {
    	public int i;
     
    	public void Foo()
    	{
    		i++;
    	}
    }

  5. #5
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Il n'y a rien de magique, il s'agit bien ici d'une simple assignation et non d'une copie. Quand un abonné va se désabonner (via -=), il va créer un nouveau délégué.
    * Avant le désabonnement : RaiseCustomEvent = A = { X, Y, Z }
    * Après le désabonnement : RaiseCustomEvent = B = A - Z = { X, Y }
    Donc, après l'appel à -= RaiseCustomEvent contiendra bien une référence différente, B, et non plus A.

    Dans le code ci-dessous, tiré de MSDN, imaginons qu'il y ait au début de la méthode un seul abonné. RaiseCustomEvent est une référence vers X, le handler de cet abonné. Si entre la première et le dernière ligne l'abonné se désabonne, RaiseCustomEvent aura désormais la valeur null. Mais la variable locale, elle, contiendra toujours X. Si l'on n'avait pas utilisé cette variable locale et que l'on avait directement testé puis appelé RaiseCustomEvent, le test aurait pu être validé mais l'invocation échouer car entretemps l'unique abonné se serait désabonné.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
                EventHandler<CustomEventArgs> handler = RaiseCustomEvent;
     
                // Event will be null if there are no subscribers
                if (handler != null)
                {
                    // Format the string to send inside the CustomEventArgs parameter
                    e.Message += String.Format(" at {0}", DateTime.Now.ToString());
     
                    // Use the () operator to raise the event.
                    handler(this, e);
                }
    Tout réside dans le fait que les opérateurs "+" et "-" ne modifient pas les références existantes (puisque les délégués sont immutables) mais en créent de nouvelles. Et c'est cette nouvelle référence qui est assignée quand on utilise "+=" et "-="

  6. #6
    Membre régulier Avatar de kerinel
    Profil pro
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 107
    Points
    107
    Par défaut
    Merci a tous, je crois que je viens de comprendre. En faisant EventHandler<CustomEventArgs> handler = RaiseCustomEvent; handler et RaiseCustomEvent désignent toujours le même objet.
    Et, si rien ne se passe pendant les notifications "on s'en moque un peu".

    Par contre, si il y a un désabonnement (ou un abonnement) pendant l'opération de notification, c'est la variable RaiseCustomEvent qui dès lors désignera un nouvel objet et handler continuera à désigner le premier EventHandler, ce qui évitera les problèmes.

    (et en fait l'explication donnée en commentaire de code dans le msdn est erronée puisqu'il ne s'agit à aucun moment d'une copie de l'objet).

    merci à tous,
    Bon code,
    kerinel

  7. #7
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Euh non non, le commentaire est correcte.
    Il faut voir un évènement comme un tableau de personnes à contacter.
    "Si l'évènement se produit, appelle Toto, Titi et Tutu."
    Sauf que tu récupères toujours une copie dudit tableau, jamais l'original.
    Et c'est bien pour ca que ca marche car en cas de changement du tableau original, avec ta copie soit t'oublies d'appeller quelqu'un (qui s'est abonné entre temps), soit t'appelles quelqu'un en trop (qui s'est désabonné entre temps) mais tu aurais eu quelque chose de non null.
    Ca aurait été une référence, ca aurait pu devenir null entre temps et ca aurait levé une erreur.

  8. #8
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Nathanael, tu embrouilles tout.

    Citation Envoyé par Nathanael Marchand Voir le message
    Euh non non, le commentaire est correcte.
    Non. La ligne commentée sert à obtenir une copie de la référence. Pas une copie.

    Il faut voir un évènement comme un tableau de personnes à contacter.
    "Si l'évènement se produit, appelle Toto, Titi et Tutu."
    Sauf que tu récupères toujours une copie dudit tableau, jamais l'original.
    Non. Tu récupères toujours une copie de la référence. Jamais une copie.

    Et c'est bien pour ca que ca marche car en cas de changement du tableau original
    Le tableau (délégué MulticastDelegate) original est immutable, il ne change jamais. En revanche la variable contenant la référence vers le tableau (délégué) peut changer pour se voir assignée une autre référence vers un autre tableau (délégué).


    Le commentaire commet en réalité un abus de langage en parlant de "copie" pour signifier "copie de la référence".

  9. #9
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Au temps pour moi, j'ai toujours cru que c'était un type valeur, la doc souligne le contraire:
    http://msdn.microsoft.com/en-us/library/900fyy8e.aspx
    A delegate is a reference type that can be used to encapsulate a named or an anonymous method
    La subtilité vient donc de mutable/immutable

    Et je complète par encore la doc:
    The invocation list of a delegate is an ordered set of delegates in which each element of the list invokes exactly one of the methods represented by the delegate. An invocation list can contain duplicate methods. During an invocation, methods are invoked in the order in which they appear in the invocation list. A delegate attempts to invoke every method in its invocation list; duplicates are invoked once for each time they appear in the invocation list. Delegates are immutable; once created, the invocation list of a delegate does not change.

    Delegates are referred to as multicast, or combinable, because a delegate can invoke one or more methods and can be used in combining operations.

    Combining operations, such as Combine and Remove, do not alter existing delegates. Instead, such an operation returns a new delegate that contains the results of the operation, an unchanged delegate, or null. A combining operation returns null when the result of the operation is a delegate that does not reference at least one method. A combining operation returns an unchanged delegate when the requested operation has no effect.

  10. #10
    Membre régulier Avatar de kerinel
    Profil pro
    Inscrit en
    Février 2007
    Messages
    103
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 103
    Points : 107
    Points
    107
    Par défaut
    Je crois que je peux mettre résolu .
    Merci à tous,
    Bon code,
    kerinel

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Object] Problèmes avec Assigned
    Par Clorish dans le forum Langage
    Réponses: 9
    Dernier message: 30/06/2005, 13h22
  2. [VB.NET] Evaluer une valeur avant de l'assigner
    Par viva-emptiness dans le forum ASP.NET
    Réponses: 5
    Dernier message: 11/06/2005, 20h12
  3. probleme avec : record "new" is not assigned yet D
    Par chtieu dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 31/03/2005, 20h44
  4. Réponses: 4
    Dernier message: 04/03/2005, 17h48
  5. C'est quoi "Profile" dans le assign du XMLGram ?
    Par Lux interior dans le forum XMLRAD
    Réponses: 2
    Dernier message: 28/02/2003, 11h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo