Προς το περιεχόμενο

Γενικό thread αποριών για τη C#.


Alithinos

Προτεινόμενες αναρτήσεις

  • Απαντ. 505
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Συχνή συμμετοχή στο θέμα

Δημοσιευμένες Εικόνες

Αυτό όμως είναι κακό, γιατί ένας απ' τους σημαντικότερους λόγους που οι delegates φαίνεται να είναι χρήσιμοι πέραν της χρήσης τους σε events, είναι το να μπορούν να εκτελούν ένα αριθμό μεθόδων σε μια γραμμή, χωρίς να φτιάχνω μεθόδους που καλούν μεθόδους.

Ας πουμε τι θα καναμε χωρις delegates και events.

 


using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace test
{
    
    interface OnDoSomthingEvent
    {
        void OnDoSomthing(object sender, EventArgs e);
    }
    
    class ThisClassHasAnEvent
    {
        List<OnDoSomthingEvent> register;
        public ThisClassHasAnEvent()
        {
            register = new List<OnDoSomthingEvent>();
        }
        public void RegisterDoSomthingEvent(OnDoSomthingEvent ev)
        {
            register.Add(ev);
        }
        public void UnregisterDoSomthingEvent(OnDoSomthingEvent ev)
        {
            register.Remove(ev);
        }
        public void FireTheEvent()
        {
            foreach (var item in register)
            {
                item.OnDoSomthing(this, new EventArgs());
            }
        }
    }
    public class Program : OnDoSomthingEvent
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            ThisClassHasAnEvent theEventClass = new ThisClassHasAnEvent();
            theEventClass.RegisterDoSomthingEvent(p);

            theEventClass.FireTheEvent();
            Console.Read();

        }


        public void OnDoSomthing(object sender, EventArgs e)
        {
            Console.WriteLine("Event Fiered form:{0}", sender.ToString());
        }
    }
}
  • Like 2
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλά δεν είπα σε καμία περίπτωση πως δεν είναι χρήσιμα τα events και οι delegates όπως είναι τώρα.

Απλά θα ήταν κομματάκι πιο βολικό να μπορούσα να αρχικοποιήσω τον delegate σε μια σειρά όπως

κάνω και με άλλους τύπους, αντί να σπάω υποχρεωτικά τη δήλωση και την ανάθεση σε δύο μέρη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλά δεν είπα σε καμία περίπτωση πως δεν είναι χρήσιμα τα events και οι delegates όπως είναι τώρα.

Απλά θα ήταν κομματάκι πιο βολικό να μπορούσα να αρχικοποιήσω τον delegate σε μια σειρά όπως

κάνω και με άλλους τύπους, αντί να σπάω υποχρεωτικά τη δήλωση και την ανάθεση σε δύο μέρη.

 

 

   Για πιο λογο θα το εκανε πιο βολικο; Δεν ειναι αυτοσκοπος οταν προγραμματιζεις να εχεις οσο το δυνατον λιγοτερες γραμμες κωδικα, αλλα να ειναι ο κωδικας σου ευαναγνωστος σε αλλους περα απο σενα.

 

   Επιπλεον αμα ηθελες σε μια αλλη περιπτωση να εχεις αλλο delegate ωστε να διαχειριστεις τυχων δεδομενα που μεταφερει το event διαφορετικα, θα επρεπε να εχεις ενα τελειως διαφορετικο event, και αυτην ακριβως ειναι η εννοια του spaghetti code γιατι καθε φορα θα επρεπε να κανεις raise 2 διαφορετικα events and you get the idea. 

 

   Ασε που πως ακριβως θα εκανες unsubscribe απο το event; 

Αυτό όμως είναι κακό, γιατί ένας απ' τους σημαντικότερους λόγους που οι delegates φαίνεται να είναι χρήσιμοι πέραν της χρήσης τους σε events, είναι το να μπορούν να εκτελούν ένα αριθμό μεθόδων σε μια γραμμή, χωρίς να φτιάχνω μεθόδους που καλούν μεθόδους.

 

 

Τι κακο εχει μια μεθοδο να καλει μια αλλη μεθοδο;

 

  PS : Στο παραδειγμα που παρεθεσες δεν κανεις unsubscribe.  

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αλλά όχι, τα events θέλουν σώνει και καλά αλλού να γράφεται η δημιουργία του, και αλλού ο ορισμός του handler.  Ούτε  στην ίδια σειρά, ούτε καν εντός του ίδιου scope.

 

αυτό μου φαίνεται περιττή παραξενιά. 

Γιατί ? Γιατί κάνει τον κώδικα σπαγγέτι. Αντί να τα χω ωραία και τακτοποιημένα σε ένα σημείο, πρέπει να είναι αλλού το ένα μέρος, και αλλού το άλλο.

 

Υπάρχει κάποιος σοβαρός λόγος να μη μπορώ να κάνω την αρχικοποίηση του Kazabubu στην ίδια γραμμή ?

        static event Publisher Kazabubu += NumberBeyond10;

Άλλους τύπους όπως int και object με αφήνει να τους αρχικοποιήσω ως class members.

Τα events γιατί όχι ?

 

Δεν υπάρχει τεχνικός λόγος που δε μπορεί να γίνει αυτό. Αλλά προσωπικά δε θα ήθελα να δω αυτό το feature να εμφανίζεται γιατί ήδη έχει γαμηθεί ο Δίας με τα features που βάζουν το ένα πάνω στο άλλο, και γιατί δε νομίζω πως "πείθει" για τη χρησιμότητά του.

 

Πρώτον, αν μπορούσες να το κάνεις αυτό ο delegate που περνάς θα έπρεπε αναγκαστικά να είναι κάτι static. Άρα αυτό το feature θα ήταν άχρηστο στην πλειοψηφία των περιπτώσεων. Επιπλέον, έστω ότι έχεις μια class και αρχικοποιείς έτσι ένα event. ΟΚ, κάποια στιγμή όμως για να δεις αποτέλεσμα θα πρέπει να το κάνεις raise:

private void RaiseKazabubu()
{
    Kazabubu?.Invoke(this, args); // c# 6 αλλά δεν έχει σημασία
}

Δεδομένου ότι καρφώνοντας το NumberBeyond10 σαν initializer κατά 99% μας λες πως "βασικά αυτό θα συμβαίνει πάντα, έτσι είναι φτιαγμένη η class", γιατί απλά να μην κάνεις αυτό;

private void RaiseKazabubu()
{
    NumberBeyond10(this, args);
    Kazabubu?.Invoke(this, args);
}

Η μόνη περίπτωση που δε θα ήταν τόσο βολικό είναι εμ από τη μία να καρφώνεις delegate σαν initializer, να είναι φυσικά delegate σε static, και να υπάρχει και σενάριο να τον αφαιρέσεις αργότερα. Μιλάμε για 1 στο εκατομμύριο στην πράξη; Δε νομίζω ότι είναι ικανό επιχείρημα για να βάλουν καινούριο feature.

 

That said προσωπικά δε θα το έκανα αυτό και θεωρώ τον constructor μια χαρά σημείο για να καρφώσεις το delegate που θέλεις.

 

 

Αυτό που αναρωτιέμαι είναι πως μπορώ να 'σπάσω' την εκτέλεση από έναν delegate.

 

Έστω ότι έχω έναν delegate Α που τον έχω βάλει να εκτελεί 4 μεθόδους όταν καλείται. Υπάρχει όμως ένα event που χρησιμοποιεί άλλο delegate (Β), και υπάρχει περίπτωση όταν εκτελείται μια απ' τις μεθόδους του delegate A να συμβεί ένα event σε αυτή.

Σε αυτή τη περίπτωση, θέλω ο delegate A να σταματήσει να εκτελεί τις μεθόδους που του χουν μείνει να εκτελέσει, όπως σε μια λούπα θα χρησιμοποιούσα τη break.

 

Το πιο απλό που μπορείς να κάνεις είναι throw new SkipInvocationOfRemainingDelegatesException() και τέλος η εκτέλεση των μεθόδων του delegate.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

   Για πιο λογο θα το εκανε πιο βολικο; Δεν ειναι αυτοσκοπος οταν προγραμματιζεις να εχεις οσο το δυνατον λιγοτερες γραμμες κωδικα, αλλα να ειναι ο κωδικας σου ευαναγνωστος σε αλλους περα απο σενα.

 

Ε για να μην έχαχνες τριγύρω... Στο κάτω κάτω, και οι λιγόετερες γραμμές, δεν κάνουν το κώδικα πιο ευανάγνωστο ?

Απλά μια ιδέα είπα.

 

 

Τι κακο εχει μια μεθοδο να καλει μια αλλη μεθοδο;

 

Δεν έχει απαραίτητα κάτι το κακό.

Απλά άμα μπορούσα να εκπροσωπήσω ένα αριθμό μεθόδων με μια μεταβλητή, και μπορούσα με αυτό το τύπο να κάνω πραγματάκια όπως να κόβεται η εκτέλεση των άλλων μεθόδων υπό προϋποθέσεις,πιστεύω θα ήταν χρήσιμο σε διάφορες περιπτώσεις.

 ο delegate που περνάς θα έπρεπε αναγκαστικά να είναι κάτι static.

Δεν το είχα σκεφτεί αυτό..

 

 

Δεδομένου ότι καρφώνοντας το NumberBeyond10 σαν initializer κατά 99% μας λες πως "βασικά αυτό θα συμβαίνει πάντα, έτσι είναι φτιαγμένη η class", γιατί απλά να μην κάνεις αυτό;

Εμ... για να γλιτώσω γραμμές κώδικα ?

 

 

Το πιο απλό που μπορείς να κάνεις είναι throw new SkipInvocationOfRemainingDelegatesException() και τέλος η εκτέλεση των μεθόδων του delegate.

 

Σωστά. Για κάποιο λόγο αν και ήξερα και το πως να πετάω και να πιάνω exceptions, και πως να φτιάξω delegate, δεν συνέδεσα μαζί τις γνώσεις από αυτά τα δύο. Είχα αλλού το κεφάλι μου φαίνεται.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ξέρει κανείς πως κάνω τα tables μιας SQL έτσι ώστε να μπορώ να τους θέσω ερωτήματα με το LINQ ?

 

Έχω φτιάξει μια SQL Service - Database (.mdf) και την έχω βάλει στο project.

Έχω φτιάξει και τα columns, και έχω προσθέσει και data, και

έκανα διάφορα queries σε αυτή γράφοντας SQL σε ένα .sql αρχείο.

 

Απ' την άλλη έχω μάθει πως να κάνω και queries με το LINQ τύπου

var query = from someName in CollectionName
            where someName.FieldName > 5
            select someName;

Αλλά ως τώρα έχω πειραματιστεί μόνο με συλλογές τύπου lists, arrays, dictionaries.

Και θέλω να χρησιμοποιήσω το LINQ για να χρησιμοποιήσω και δεδομένα από .mdf μέσα σε .cs, στο κώδικα του προγράμματος.

Τι κλάσεις / αντικείμενα όμως πρέπει να χρησιμοποιήσω ώστε να κάνω τα tables του .mdf να μπορεί να τα βλέπει το LINQ ?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επισκέπτης
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μα αφού είναι πιο εύκολο να γράψει εδώ την απορία του (αντί να ψάξει έστω και λίγο) και να του την λύσουν οι άλλοι.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

 

 

Είναι εύκολο για εσάς που τα ξέρετε ήδη να λέτε πως είναι εύκολα.

Μιας και κάνετε το λάθος να νομίζετε πως επειδή εσείς τα ξέρετε ήδη και έχετε εξοικειωθεί μαζί τους και σας φαίνεται εύκολο το πως να κάνετε τέτοιες διαδικασίες, πως το ίδιο εύκολο θα είναι και σε κάποιον που δεν τα έχει μάθει ακόμα, και δεν έχει ασχοληθεί ποτέ πριν ξανά.

 

Άρα λοιπόν το

 

Με ένα απλό search "LINQ to SQL" θα έβρισκες τη λύση

θα ίσχυε, αν ήξερα ήδη ότι πρέπει να προσθέσω new item στο project, τύπου "LINQ TO SQL". 

 

Εγώ εδώ και 3 μέρες δεν ήξερα αν για να μπορεί να βλέπει το data το LINQ, έπρεπε να φτιάξω dataset, SQL DataBase, SQL Service Based DataBase, Entity ή ADO, αν ότι χρειάζομαι για να λινκάρω από database είναι μέσα στο System.Linq, ή στο System.SQL, ή σε κάποιο άλλο namespace, ή αν δεν ήταν καν στα namespaces των ήδη refferenced dlls και έπρεπε να βρω να κάνω reference κάποιο άλλο dll...

 

Και για κάθε μια επιλογή που εμφανίζεται στο "add new item / data" στο dialog του VS, στο MSDN έχει καμιά 80αριά σελίδες... Όχι μια και δύο σαν τα λινκ που βάλατε, αλλά δεκάδες για το κάθε τι ξεχωριστά, που αριθμούν εκατοντάδες σελίδες μαζί, και στη χειρότερη περίπτωση θα έπρεπε να τις διάβαζα όλες μέχρι να έβρισκα ανάμεσα τους τι απ' όλα αυτά θα μου επέτρεπε να κάνω αυτό που θέλω να κάνω.

 

Άσε δε που άμα πας στη σελίδα του MSDN για LINQ TO SQL για VS2015 (πήγα μια βόλτα) το πρώτο πράμα που σου λέει η MS πάνω πάνω είναι πως αυτή είναι παρωχημένη τεχνολογία και πως δε θα πρέπει να χρησιμοποιείται σε νέα projects...

 

Για αυτό, cut me some slack που λένε...

Ευχαριστώ πάντως για τη κατάδειξη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 4 εβδομάδες αργότερα...

Καλησπέρα παίδες.

Πάει περίπου ένας μήνας που έγραψα σε αυτό το thread, και επανέρχομαι για να μοιραστώ κάποια πράγματα.

Ελπίζω κάποια απ' αυτά να τα βρουν χρήσιμα κάποιοι αρχάριοι που ίσως δουν το thread, μιας και τα πρώτα

4 δεν είναι ερωτήσεις αλλά διαπιστώσεις.

 

1) Καταρχάς το εξής: Είχα την υποψία από αρκετά παλαιότερα, αλλά πλέον που ξέρω 5 πραγματάκια και δουλεύω

σε ένα πρότζεκτ, η υποψία μου έγινε σιγουριά. Αναφέρομαι στο ότι ο εγκέφαλος, δουλεύει καλύτερα σε χαμηλότερες

θερμοκρασίες. Η ζέστη σε 'χαζεύει' κατά κάποιο τρόπο. Σε κάνει πιο νωχελικό και δυσκολεύει τη συγκέντρωση.

Η παραγωγικότητα μου κατά τον Ιούνιο, και ιδιαίτερα κατά τη διάρκεια των ημερών του καύσωνα που είχε 39 - 40

βαθμούς είχε πέσει στην Άβυσσο.  :(  Κάποιες μέρες δεν εργάστηκα καν. Και σήμερα που έπεσε κάπως η θερμοκρασία

(29~32 βαθμούς) μπόρεσα και βρήκα τον αλγόριθμο για μια συγκεκριμένη λειτουργία, και τον κωδικοποίησα, και έφτασα

το επόμενο milestone.  Αυτό μου έγινε μάθημα για το πως να οργανώνω πρότζεκτ με διάρκεια μηνών στο μέλλον.

 

2) Είναι tricky τελικά η υπόθεση χρόνου ολοκλήρωσης ενός project. Νόμιζα τότε πίσω τον Μάιο πως κατά το τέλος του

Ιουνίου θα είχα τελειώσει το project αυτό. Έσφαλα. Είναι 26 του μηνός και ίσα που κοντεύω να ολοκληρώσω τη βασική 

του λειτουργία, το "MAKE IT WORK" του " Make it work, Make it right, Make it fast", να φτάσω την 'Άλφα'. Οι λόγοι,

διάφοροι που εμφανίστηκαν εκεί που δεν τους περίμενα. Από τη μια αυτό που αναφέρω στο 1. Από την άλλη, επισκέπτες

που μου έφαγαν χρόνο, πράγματα καθημερινής ζωής που συμβαίνουν, αλλά και πιο σχετικοί, όπως επανεξέταση απαιτήσεων

(που ο ίδιος είχα αποφασίσει πολύ νωρίς) και αλλαγή αρχιτεκτονικής σε κάποια sub-modules. Κοινώς, θέλω πιστεύω τουλάχιστον

άλλο έναν μήνα, για να φτάσω στην ολοκλήρωση.

 

3) Συνάντησα και βρίσκομαι στην εξής περίεργη θέση: Ξέρω αρκετά για να μπορέσω (τουλάχιστον προς το παρόν) να λύσω

διάφορα προγραμματιστικά προβλήματα που μου εμφανίζονται, και να δουλέψω πχ σε κάτι που ήθελα να φτιάξω, και σιγά 

σιγά να το υλοποιήσω και να το ολοκληρώσω. Ωστόσο ξέρω πως υπάρχουν ακόμα αρκετά θέματα για τα οποία δεν ξέρω τίποτα.

Για παράδειγμα για τη C#, για το Async, το Multithreading, τα Reactive Extensions, και το Reflection, δεν έχω ασχοληθεί 

καθόλου ακόμα. Και επίσης θέλω στο μέλλον να μελετήσω και τα design patterns. Το πρόβλημα είναι το εξής: Δεν μπορώ

να πάρω μια και καλή μια απόφαση για το πως είναι το καλύτερο να ξοδέψω το χρόνο μου "τώρα".

Δηλαδή πχ όταν πιάνω ένα βιβλίο για να διαβάζω για αυτά που δε ξέρω, νιώθω πως το χρόνο αυτό θα μπορούσα να τον

χρησιμοποιήσω για να γράφω κώδικα, και η όρεξή μου για διάβασμα πέφτει. Απ' την άλλη νιώθω όταν γράφω κώδικα,

πως ίσως για αυτά που κάνω, μπορεί να υπάρχει καλύτερος τρόπος να τα κάνω και να μη το ξέρω. Έτσι έχω ένα αίσθημα

αβεβαιότητας. Αυτό που λέω προς το παρόν στον εαυτό μου είναι πως αφού ολοκληρώσω αυτό το project, θα κάτσω

μετά να διαβάσω για να μάθω και όλα τα υπόλοιπα. Ώστε μετά πλέον να μην έχω αυτό το αίσθημα. Κάποια συμβουλή

για αυτό θα ήταν ωραία.

 

4) Θα μοιραστώ και ένα φαινόμενο που παρατήρησα να συμβαίνει μερικές φορές ενώ πήγαινα να γράψω μια απάντηση

σε αυτό το thread ή και να ανοίξω νέο θέμα. Είχα στο νου μου κάτι που με απασχολούσε με μορφή ερωτήματος, το 

οποίο και αποφάσιζα να μπω εδώ και να το γράψω. Κατά το γράψιμο λοιπόν, καθώς σκεφτόμουν πως να γράψω το

ερώτημα μου και τι πληροφορίες να μη ξεχάσω να προσθέσω για να είναι κατανοητό το πρόβλημα, αντιλήφθηκα και 

την απάντηση,  :lol: και έτσι τελικά ακύρωσα τις απαντήσεις εκείνες και δεν εμφανίστηκαν.

 

//Ας πάμε τώρα σε μερικές ερωτήσεις...

 

5) Κάτι έκανα και από κει που όταν πατώντας το debug σε ένα VSIX project φόρτωνε σύμβολα για 2-3 δευτερόλεπτα,

τώρα φορτώνει ΟΛΑ τα σύμβολα, ότι έχει και δεν έχει. Ακόμα και για φαινομενικά άσχετα πράγματα όπως Xamarin,

javascript, κτλπ τα οποία δεν τα χρησιμοποιώ σε κανένα project. Και το φόρτωμα όλων αυτών των συμβόλων κρατά

εξαντλητικά πολύ. Απλά μετά από 2-3 δευτερόλεπτα πατάω το Cancel, και συνεχίζω το debugging...

Btw δεν είναι ενοχλητικό που δεν λειτουργούν τα breakpoints σε αρχείο κώδικα ενός toolbox control / VSIX όταν το 

κάνεις debug ?

 

6) Όσων αφορά το localization του προγράμματος σε πάνω από μια γλώσσες... Ο τρόπος που σκέφτηκα είναι να

φτιάξω μια κλάση για κάθε γλώσσα που έχει ως properties public strings, και οι οποίες κλάσεις κληρονομούν τα ονόματα των properties από μια μητρική κλάση 'Γλώσσα', και όταν φορτώνει το πρόγραμμα να διαβάζει σε ένα αρχειάκι που είναι αποθηκευμένα τα options του χρήστη την επιλογή, και να τοποθετεί σε ένα αντικείμενο τύπου Γλώσσα, την αντίστοιχη γλώσσα. Και όπου πρέπει να χρησιμοποιήσω strings, αναφέρομαι στο property του αντικείμενου Γλώσσας, αντί να έχω literals.

Υπάρχουν καλύτεροι τρόποι ; 

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επισκέπτης

Το localization στο .NET λειτουργεί με .resx αρχεία και αντιστοίχιση λέξεων με τη μετάφραση τους. Μετά απλά αλλάζεις το CultureInfo στον κώδικα κι είσαι έτοιμος.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...