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

Αρχάριος στη C#


Giorgos3924

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

Γειά σας και πάλι.

Επαναφέρω το θέμα καθώς άρχισα και ασχολούμε λίγο λίγο με την C# και συγκεκριμένα με φόρμες.

Γενικά απλή μου φαίνεται αν και με μπερδεύουν μερικά πράγματα στο VS όπως κάποια namespace system,windows,forms,drawing, application, και διάφορα άλλα που δεν συνίθιζα να βλέπω σε προγράμματα ή βιβλία της C/C++.

 

Θα ήθελα να ρωτήσω, Μπορώ να ενώσω ένα πρόγραμμα της C# με ένα πρόγραμμα της C?

Δηλαδή να περνάω δεδομένα απ το ένα στ άλλο.

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


Επίσης κάτι άλλο περίεργο που είδα.

Όταν πατάω διπλό κλικ να ανοίξω μια συνάρτηση

πχ τη button_click για να γράψεις τί θα γίνει αν πατηθεί το συγκεκριμένο button.

Αν μετά πας και σβήσεις τη συνάρτηση επειδή δεν θες να τη χρησιμοποιήσεις πλέον

τότε εμφανίζεται αυτό:

 

Αυτό εμφανίζεται στο form design.

 

Αν πατήσω ignore and continue τότε εμφανίζεται η φόρμα στην αρχική της κατάσταση όταν δημιουργήθηκε το project.

post-131369-0-10990200-1404297423_thumb.png

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

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

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

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

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

Δημοσ. (επεξεργασμένο)

Το σημείο που προσφέρεται είναι η class Program ή όπως αλλιώς τη λες στην οποία βρίσκεται και η Main() σου (εκεί που καλεί Application.Run() δηλαδή), μπορείς να βάλεις μια static property και να τη βλέπεις ως Program.MyProperty.

 

Πάντως έχε υπόψη ότι ιδιαίτερα στις πιο high level γλώσσες, global μεταβλητές == κακή συνήθεια. Πάντα υπάρχει κάποιος καλύτερος από άποψη δόμησης τρόπος να κάνεις την ίδια δουλειά.

 

 

Μιας και βρήκα λίγο χρόνο να ασχοληθώ...

 

Πώς μπορώ να αναφερθώ σε κάτι που είναι στη main?

 

Επειδή δεν δούλεψε, το έκανα έτσι:

 

 

namespace myapp
{
    public partial class Form1 : Form
    {
        private int xx=0;
        public Form1()
        {
            InitializeComponent();
            
        }
        public int metabliti()
        {
            xx++;
            return xx;
        }
            

      
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            
            if (e.KeyChar == (char)Keys.Enter)
            {
               // label1.Text = textBox1.Text;
                label1.Text = textBox1.Text + Convert.ToString( metabliti() );  
             
            }
            
            
        }
    }
}

 

 

Στην class program πώς μπορώ να αναφερθώ;.

 

 

namespace myapp
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
            
            
        }

        
        
    }
}

 

 

 

Αυτός ο τρόπος μου φαίνεται καλύτερος

 

 

 

 

namespace myapp
{
    

    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
            
        }


        metablites metabliti_ab = new metablites(0);           

      
        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            
            if (e.KeyChar == (char)Keys.Enter)
            {
               // label1.Text = textBox1.Text;
                label1.Text = textBox1.Text + Convert.ToString(metabliti_ab.auksisi());  
                
            
            
        }
    }

        public class metablites
        {
            private int ab;
            public metablites(int timi_ab)
            {
                ab = timi_ab;
            }
            public int auksisi()
            {
                ab++;
                return ab;
            }
        }
    }

} 

 

 

 

Όταν δηλώνω την "public class metablites" πάνω από την "public partial class Form1 : Form"

μου βγάζει error, έτσι όμως δουλεύει μια χαρά

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

Θες singleton. check δες και αυτο για να ξεκολλησεις απο το "main"

Το τελευταίο πρόγραμμα πώς σου φαίνεται;

Είναι το καλύτερο που μπορούσα να σκεφτώ :/ Ελπίζω να έπιασα το νόημα...

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

Το τελευταίο πρόγραμμα πώς σου φαίνεται;

Είναι το καλύτερο που μπορούσα να σκεφτώ :/ Ελπίζω να έπιασα το νόημα...

 

Υπάρχουν πολλά που θα μπορούσαν να γίνουν καλύτερα, αλλά σημασία έχει πρώτα απ' όλα ότι έκατσες να σκεφτείς. Μερικές προτάσεις για βελτίωση in no particular order:

 

Πρώτα απ' όλα είπα να βάλεις τη μεταβλητή στην class Program και όχι στη Form1 -- γιατί; Δε θα κάνει κάποια πρακτική διαφορά. Απλά αν η μεταβλητή που θέλεις αφορά μάλλον το πρόγραμμα σα σύνολο και όχι την ίδια τη φόρμα ταιριάζει καλύτερα να τη βάλεις εκεί (και θα είναι static). Αν πάλι αφορά τη φόρμα αυτή καθαυτή τότε να τη βάλεις στη Form1. Εδώ τώρα θα μπορούσε κάποιος μη προγραμματιστής να πει ότι η φόρμα είναι το πρόγραμμα με την έννοια πως γι' αυτόν δεν υπάρχει διαχωρισμός, αλλά για μας υπάρχει. Αν ήθελες να το βάλεις στην Program θα ήταν π.χ.

 

static class Program
{
    internal static int counter = 0;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
        
        
    }
}

και μετά

var nextValue = ++Program.counter;

 

Δεύτερον το να γράφεις μια method η οποία αυξάνει μια μεταβλητή και επιστρέφει την αυξημένη τιμή της είναι Α-ΟΚ (π.χ. σε ένα PHP πρόγραμμα κάπου είχα γράψει μια getUniqueId() που έκανε ακριβώς αυτό) αλλά το όνομα metabliti() είναι γενικά λάθος όνομα: δε δίνει να καταλάβεις τι γίνεται (σύγκρινε με το getUniqueId). Το ίδιο και το auksisi().

 

Η ξεχωριστή class για να βάλεις μια μεταβλητή μέσα δε φαίνεται να έχει κανένα νόημα. Θα μπορούσε να έχει νόημα αν ήταν ξεκάθαρο το γιατί υπάρχει και αν ο σκοπός της ήταν να κρύψει κάτι το κάπως περίπλοκο, αλλά όχι έτσι που την έχεις. Τραβώντας το λίγο (επειδή είναι πολύ απλό το παράδειγμα σε σημείο που δεν αξίζει μάλλον), αυτό θα ήταν πιο σωστό:

class MonotonicSequence
{
    private int current;
    private readonly int step;

    public MonotonicSequence(int first, int step)
    {
        this.current = first;
        this.step = step;
    }

    public int GetNextTerm()
    {
        return this.current += this.step;
    }
}

και μετά

var seq = new MonotonicSequence(0, 1);
seq.GetNextTerm(); // κλπ
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

Η μεταβλητή όντως έχει εμβέλεια μόνο στη φόρμα και όχι σε όλο το πρόγραμμα απλά δεν κατάφερα να το κάνω αλλιώς γιατί μου έβγαζε error. Είτε κλάση έβαζα είτε μεταβλητή έβγαζε error.

 

Τα ονόματα τα έβαλα εν συντομία, έχεις δίκιο ίσως να μην σου δίνουν να καταλάβεις περι τινος πρόκειται...

 

Και όσον αφορά τη ξεχωριστή κλάση εμένα με βοήθησε περισσότερο να κατανοήσω τη δομή.

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

 

---

 

Το this. σε τί ακριβώς αναφέρετε; 

Βλέπω ότι χρησιμοποιείς μια μεταβλητή τύπου readonly. Γιατί όχι const int?

Το να χρησιμοποιήσεις 

private readonly int step
Και
public MonotonicSequence(int first, int step) 

δηλώνοντας την ίδια μεταβλητή step δεν υπάρχει πρόβλημα;

Εφόσον είναι readonly πώς μπορείς και της δίνεις τιμή 1?

var seq = new MonotonicSequence(0, 1);

και μετά την αυξάνεις

return this.current += this.step;
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το this. σε τί ακριβώς αναφέρετε; 

 

Το να χρησιμοποιήσεις 

private readonly int step
Και
public MonotonicSequence(int first, int step) 
δηλώνοντας την ίδια μεταβλητή step δεν υπάρχει πρόβλημα;

 

 

"Πρόβλημα" δεν υπάρχει, απλά δηλώνοντας μια παράμετρο ή local variable με το όνομα του field (π.χ. εδώ "step") τότε γράφοντας σκέτο step αναφέρεσαι θέλεις δε θέλεις στην παράμετρο ή local. Αν θέλεις να αναφερθείς στο field πρέπει να γράψεις συγκεκριμένα this.step (πράγμα που μπορείς βέβαια να κάνεις έτσι κι αλλιώς, π.χ. με τα coding style standards του StyleCop που ακολουθώ και εγώ "επιβάλλεται" να γράφεις το this από μπροστά αν και αυτά τα θέματα είναι "θρησκευτικού χαρακτήρα").

 

 

Βλέπω ότι χρησιμοποιείς μια μεταβλητή τύπου readonly. Γιατί όχι const int?

Εφόσον είναι readonly πώς μπορείς και της δίνεις τιμή 1?

var seq = new MonotonicSequence(0, 1);
και μετά την αυξάνεις

return this.current += this.step;

 

Θα μπορούσα να σου εξηγήσω λεπτομερώς αλλά γιατί δεν κάνεις απλά google "c# readonly"? Για κάτι τόσο απλό θα ήταν ευκολότερο και για τους δυο μας. Τα δύο πρώτα results θα σου πουν όλα όσα θες να ξέρεις.

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

Ναι τώρα κοιτάω τον internal...

 

Θεώρησα αυτονόητο το τί κάνει, αλλά μάλλον κατάλαβα λάθος. Γιαυτό ρώτησα


Γιατί να μην δηλώσουμε την counter ως

public static int counter = 0;

και την βάζουμε ως internal?

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

Καμία διαφορά στην πράξη, απλά είναι θεωρητικά πιο σωστό το internal επειδή αν ποτέ είχες άλλα assemblies που έχουν reference στο assembly του project σου, αυτά δε θα έπρεπε να έχουν πρόσβαση στο counter.

 

Το ίδιο πράγμα με πιο απλά λόγια: ακόμα και σε ένα πρόγραμμα με μία μόνο class (οπότε τι public τι protected τι private το ίδιο πράγμα στην ουσία), κάποια πράγματα "πρέπει" να είναι public και κάποια "πρέπει" να είναι private. Εσύ γράφεις κώδικα όπως πρέπει ανεξάρτητα από το ότι δεν παίζει ρόλο στην πράξη.

 

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

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

Καμία διαφορά στην πράξη, απλά είναι θεωρητικά πιο σωστό το internal επειδή αν ποτέ είχες άλλα assemblies που έχουν reference στο assembly του project σου, αυτά δε θα έπρεπε να έχουν πρόσβαση στο counter.

 

Το ίδιο πράγμα με πιο απλά λόγια: ακόμα και σε ένα πρόγραμμα με μία μόνο class (οπότε τι public τι protected τι private το ίδιο πράγμα στην ουσία), κάποια πράγματα "πρέπει" να είναι public και κάποια "πρέπει" να είναι private. Εσύ γράφεις κώδικα όπως πρέπει ανεξάρτητα από το ότι δεν παίζει ρόλο στην πράξη.

 

Απ όσο διάβασα, στις public τα πάντα είναι ορατά παντού, ακόμα και σε εξωτερικά αρχεία όπως dll.

Ενώ τα internal, είναι ορατά μόνο σε ότι περιέχει το παρόν exe. (Project?)

Σωστά;

 

Λίγο δεν κατάλαβα σωστά την static και τη readonly.

static: Ποιός ο λόγος να "προστατέψουμε" μια κλάση απ' το να μην δημιουργηθούν αντικείμενα;

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

Για το internal, ναι. Τα dll και το exe δεν έχουν ουσιαστικές διαφορές -- το exe μπορείς να το κάνεις διπλο κλικ και να τρέξει, αλλά that's all. Όλα μαζί λέγονται assemblies.

 

static class: Το να δημιουργήσεις αντικείμενα από αυτή την class (π.χ. Program) δεν έχει νόημα -- δεν είναι αυτός ο σκοπός της. Οπότε την κάνεις static για να βάλεις τον compiler να λέει για λογαριασμό σου "αν πας να δημιουργήσεις αντικείμενο αυτής της class κάτι κάνεις λάθος".

 

Ειδικά για τις extension methods (google it), είσαι αναγκασμένος να τις βάλεις μέσα σε μια static class. Δεν υπάρχει κάποιος τεχνικός λόγος γι' αυτό (οι ίδιες οι extension methods πρέπει να είναι static έτσι κι αλλιώς), αλλά ο κανόνας μπήκε στον compiler για τον ίδιο γενικό λόγο: αν πας να βάλεις extension methods σε μια "κανονική" class, κάνεις χάλια δομή κώδικα. Οπότε οι σχεδιαστές της γλώσσας έβαλαν τον κανόνα πως πρέπει να κάνεις και την class static "για να αναγκαστείς να το κάνεις καλύτερα".

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

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

Όταν θέλω να κάνω refresh() την φόρμα μου είναι σαν να δημιουργείται ξανά;

Δηλαδή:

Μέσα σε μια method form_load έχω βάλει έναν κώδικα ο οποίος τυπώνει κάτι σε μια label (κάτι σαν console) και τώρα θέλω να τρέχω συνεχώς την form_load κάθε X ms ώστε να ανανεώνονται τα δεδομένα.

 

Η refresh() έχω την εντύπωση ότι μου δημιουργεί ολόκληρη τη φόρμα ξανά οπότε δεν μου κάνει γιατί έχω δεδομένα έξω από τη form_load που θέλω να κρατήσω.

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

Βαλε των κωδικα της form_load σε μια συναρτηση, που θα την καλεις περιοδικά απο το tick event ενος System.Windows.Forms.Timer.

Παντως δεν χρειαζεται refresh οταν αλλαζεις τα properties καποιου control. 

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

Βαλε των κωδικα της form_load σε μια συναρτηση, που θα την καλεις περιοδικά απο το tick event ενος System.Windows.Forms.Timer.

Παντως δεν χρειαζεται refresh οταν αλλαζεις τα properties καποιου control. 

Ευχαριστώ για την απάντηση! 

 

Δοκίμασα να βάλω τον κώδικα σε timer_tick αλλά πάλι τίποτα.

αρχικοποίησα και τον timer, τον έκανα και start από τη φορμα (form_load) αλλά τα ίδια.

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

Δεν καταλαβαινω τι εννοεις "παλι τιποτα".

 

Αν βαλεις τη συνάρτηση σε timer θα καλειται περιοδικα.

Στη συναρτηση μπορεις εχεις κωδικα που αλλαζει π.χ. το κειμενο ενος label.

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

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

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

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

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

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

Σύνδεση

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

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

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