Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Delegates

Îåêßíçóå áðü ôï ìÝëïò m6s. Τελευταία δημοσίευση από το μέλος PALLADIN στις 29-10-2008, 15:10. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  28-10-2008, 15:36 45810

    Delegates

    Διάβαζα για delegates και "ανόνυμες μεθόδους" και έκανα αυτό το μικρό αλγόριθμο :
    enum FunctionType {
          WithTax,
          WithOutTax
        }

        delegate double Discount<T>( T result, T disc1, T disc2, T disc3 );

        static Discount<T> Machine<T>() {
          return delegate( T result, T disc1, T disc2, T disc3 ) {
            return Double.Parse(result.ToString()) -
            ( Double.Parse(result.ToString()) * ( Double.Parse(disc1.ToString()) ) +
            Double.Parse(result.ToString()) * ( Double.Parse(disc2.ToString()) ) +
            Double.Parse(result.ToString()) * ( Double.Parse(disc3.ToString()) ) );
          };
        }

        static void Main( String[] args ) {
          Discount<double> Discount = Machine<double>();
          int result = 100;
          Console.WriteLine(Discount(result * 1.19, 0.10f, 0.08f, 0.09f).ToString("####0.000"));
          Console.Read();
        }
      }


    Σας τον υποβάλω, και θέλω να ρωτήσω αν είναι βλακεία το διπλό return? Μου κάνει εντύπωση πως το έκανα, δεδομένου ότι δεν έχω δει κάτι παρόμοιο στο ιnternet, και πραγματικά Δεν μπορώ να καταλάβω αν αυτός ο κώδικας είναι λίγο "τερατούργημα". Πρακτικά...δουλεύει(!)



  •  28-10-2008, 17:49 45814 σε απάντηση της 45810

    Απ: Delegates

    Τερατούργημα δεν είναι, αν και υπάρχουν ευκολότεροι τρόποι να κάνεις το ίδιο πράγμα στη C# 3.0. Γιατί όμως κάνει τη μετατροπή σε string και μετά σε Double? Από τη στιγμή που χρησιμοποιείς generics, μπορείς να γράψεις απευθείας τη συνάρτηση χωρίς μετατροπές φτάνει αν ο τύπος που χρησιμοποιείς να έχει ορισμένους τους τελεστές *, +.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  28-10-2008, 18:30 45815 σε απάντηση της 45814

    Απ: Delegates

    Η παρατήρηση για την μετατροπή string->double...να πώ την αλήθεια είναι καλή παρατήρηση που δεν μπορώ να απαντήσω.
    Μπορούσα σε C#2, χωρίς να κάνω 2 φορές return να έχω το αποτέλεσμα αυτό...Και σε C#3? ποια ήταν η εναλλακτική πρόταση;
  •  29-10-2008, 02:10 45826 σε απάντηση της 45815

    Απ: Delegates

    Η αλήθεια είναι ότι δεν χρειάζεται να κάνεις όλο αυτό το κόπο που κάνεις στο Snippet που παρέθεσες.
    Αλλά πριν προχωρήσω στο τι θα μπορούσες να κάνεις πιο εύκολα ας προσπαθήσω να ξεκαθαρίσω λίγο την έννοια των delegates γιατί από το κώδικα που είδα νομίζω ότι υπάρχει κάποια σύγχηση.
    Ένα Delegate αποτελεί πρακτικά ένα Function Pointer (δείκτη) σε μια μέθοδο και χρησιμοποιείται πολύ συχνά (έως πάντα) ως ένας τρόπος να δώσεις στο χρήστη της κλάσης σου (όχι τον user, αλλά το developer χρήστη) ένα τρόπο να γράψει κώδικά που εσύ σαν implementor μόνο της κλάσης σου δε γνωρίζεις εξαρχής, ο οποίος θα τρέξει κάποια δεδομένη χρονική στιγμή που εσύ θα αποφασήσεις. Έτσι για παράδειγμα θα μπορούσα να γράψω μια κλάση Person που να ενημερώνει το χρήστη για την αλλαγή ενός property και να του επιτρέπει να γράψει και να εκτελέσει κώδικα (που εγώ αυτή τη στιγμή δε γνωρίζω) καλώντας το delegate ως εξής:

    public delegate void OnPersonChange(Person p);

    public class Person
    {
       public OnPersonChange RegisteredDelegate { get; set; }
       private string m_name;

       public string Name
       {
         get { return m_name; }
         set
         {
           m_name = value;
           if (
    RegisteredDelegate != null)
             RegisteredDelegate(this);
         }
      }
    }


    Τότε από το κώδικα που χρησιμοποιεί το Person θα μπορούσα να γράψω κάτι της μορφής:
    ....
    Person p = new Person();

    p.RegisteredDelegate = delegate(Person p)
    {
      System.Diagnostics.Debug.WriteLine(p.Name);
    };

    p.Name = "spantos"; // Μετά από αυτό το σημείο τρέχει ο πιο πάνω κώδικας που γράφει το όνομα
    ....


    Στη περίπτωση σου δε χρειάζεται πάντως κάτι από αυτά μιας και ξέρεις εξαρχής τι θέλεις να κάνει ο κώδικας σου. Οπότε μπορείς πολύ απλά να μετατρέψεις τη μέθοδο που κατασκευάζει και επιστρέφει ένα delegate σε μέθοδο που κάνει τη δουλειά πραγματικά. Δηλαδή:


    static T CalcDiscount<T>( T result, T disc1, T disc2, T disc3 )
    {
      return result -
        ( result * disc1 + result * disc2 + result * disc3 );
    }

    static void Main( String[] args )
    {
      int result = 100;
      double discount = CalcDiscount<double>(result * 1.19, 0.10f, 0.08f, 0.09f);
      Console.WriteLine(discount.ToString("####0.000"));
      Console.Read();
    }


    και βέβαια όπως είπε και ο Παναγιώτης νωρίτερα δε σου χρειάζονται τα castings αφού η μέθοδος σου είναι Generic και ξέρει το τυπο του T. Ίσως όμως έχεις πρόβλημα αν προσπαθήσεις να περάσεις Reference Type ως παράμετρο στη Generic μέθοδο σου που να μην έχει υλοποιήσει τα operators +, -, * κλπ οπότε καλύτερα να κάνεις restrict το T σε promitive types μονο ή και να το ελέγχεις στο body της μεθόδου σου.

    Ελπίζω να βοήθησα κάπως τη κατάσταση.



    MSc Konstantinos Pantos
    MCP Software Engineer
    http://blog.pantos.name
    http://kostas.pantos.name
  •  29-10-2008, 15:10 45845 σε απάντηση της 45826

    Απ: Delegates

    Μια μικρή διόρθωση... στα C# generic types δεν μπορούμε να χρησιμοποιήσουμε arithmetic operators

    Ένα workaround

    Και διαφορες ανάμεσα σε C++ templates και C# generics


    Palladinos Nick
    Software Engineer
    -----------------------
    The limits of my language mean the limits of my world. (Ludwig Wittgenstein)
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems