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

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


Alithinos

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

Υπάρχουν και προσωπικές πατέντες. :)

 

Τιποτα δεν υπαρχει εκτος απο εγωισμο. Το 99% των εφαρμογων μοορεις να το αντιγρςψεις χωρις να δεις κωδικα, επειδη η "πατεντα" που λες ειναι αυτο που μπορεξ να κανει και οχι το πως το κανει.

 

Τωρα βαλτο στο git να δουμε κωδικα μπας και κραξουμε...

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

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

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

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

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

Αφού αναφέρεις πως ο κώδικας υπάρχει μέσα στα .zip, για ποιες πατέντες μιλάς;

 

By the way, δεν με πειράζει που μοιράζεις έτσι τις εφαρμογές σου, απλά θέλω να σου δείξω πως περιορίζεις κατά πολύ το κοινό σου με αυτό τον τρόπο.

Εννοούσα "προσωπική μέθοδος αποθήκευσης στιγμιοτύπων αρχείων". :P 

 

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

 

 

Τιποτα δεν υπαρχει εκτος απο εγωισμο. Το 99% των εφαρμογων μοορεις να το αντιγρςψεις χωρις να δεις κωδικα, επειδη η "πατεντα" που λες ειναι αυτο που μπορεξ να κανει και οχι το πως το κανει.

 

Τωρα βαλτο στο git να δουμε κωδικα μπας και κραξουμε...

 

Έβαλα το 1 απ τα 2 στο git. Το 'σημειώσεις' που είναι και μεγαλύτερο, θέλει λίγο 'καθάρισμα' πριν μπει στο git.

 

https://github.com/StavrosDimou/JokerGenerator

 

Κράξτε ελεύθερα!  :-D

 

(το feedback με βοηθά να γίνω καλύτερος ούτως ή άλλως)

 

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

Εννοούσα "προσωπική μέθοδος αποθήκευσης στιγμιοτύπων αρχείων". :P

 

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

 

 

 

Έβαλα το 1 απ τα 2 στο git. Το 'σημειώσεις' που είναι και μεγαλύτερο, θέλει λίγο 'καθάρισμα' πριν μπει στο git.

 

https://github.com/StavrosDimou/JokerGenerator

 

Κράξτε ελεύθερα!  :-D

 

(το feedback με βοηθά να γίνω καλύτερος ούτως ή άλλως)

 

Γιατι bytes και οχι απλα ints αληθεια;

Ειδικοτερα στο for loop. Περα απο το γεγονος οτι οι cpus ειναι optimised για int calculations, δεν στεκει και λογικα μιας και αναπαριστας αριθμους, σε ολο το προγραμμα το περισσοτερο execution time απλα μετατρεπεις ints σε bytes και τουμπαλιν.

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

Γιατι bytes και οχι απλα ints αληθεια;

Ειδικοτερα στο for loop. Περα απο το γεγονος οτι οι cpus ειναι optimised για int calculations, δεν στεκει και λογικα μιας και αναπαριστας αριθμους, σε ολο το προγραμμα το περισσοτερο execution time απλα μετατρεπεις ints σε bytes και τουμπαλιν.

Το έκανα με το σκεπτικό του να ελαχιστοποιήσω τη κατανάλωση μνήμης.

 

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

και δεν θυμάμαι αν το διάβασα / άκουσα κάπου ή ήταν δικής μου εμπνεύσεως, αλλά μου δόθηκε από νωρίς η εντύπωση

πως θα πρέπει να αποφεύγω τους πλεονασμούς και να μη χρησιμοποιώ πχ int για αριθμούς που καλύπτονται και από

τύπο που δεσμεύει λιγότερη μνήμη.

 

Λες είναι καλύτερο να μη χρησιμοποιώ bytes για μικρά νούμερα από εδώ και πέρα, για να αποφεύγω τις μετατροπές ; 

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

Το έκανα με το σκεπτικό του να ελαχιστοποιήσω τη κατανάλωση μνήμης.

 

Αυτό ήταν πρόβλημα πριν αρκετά χρόνια.Πλέον εκτός από ειδικές κατηγορίες δεν κάνει καμία διαφορά για 10-15 mb.

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

Το έκανα με το σκεπτικό του να ελαχιστοποιήσω τη κατανάλωση μνήμης.

 

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

και δεν θυμάμαι αν το διάβασα / άκουσα κάπου ή ήταν δικής μου εμπνεύσεως, αλλά μου δόθηκε από νωρίς η εντύπωση

πως θα πρέπει να αποφεύγω τους πλεονασμούς και να μη χρησιμοποιώ πχ int για αριθμούς που καλύπτονται και από

τύπο που δεσμεύει λιγότερη μνήμη.

 

Λες είναι καλύτερο να μη χρησιμοποιώ bytes για μικρά νούμερα από εδώ και πέρα, για να αποφεύγω τις μετατροπές ;

 

Σχετικο ειναι. Πχ αν εχεις τιποτα gb array, ε ναι εκει κοιτας και τι τυπο θα παιξεις, τωρα για τα δικασου 5 ολα και ολα byte... Καταλαβαινεις ειναι αστειο.

 

Εεεεενι γουέι, δες το στυλ με το οποιο γραφεις. Ονοματα μεταβλητων, κλασεων, εβεντς κλπ. Αλλου γραφεις με κεφαλαια αλλου με μικρα αλλου με ελληνικα αλλου αφηνεις τον code generator με τα default name του.

 

Τωρα αν θες να παιξεις με περφορμανς, κανε override την OnPaint, παιξε με control.grapgics και βαλε λιγο δικο σου βισουαλ στο προτζεκτ σου.

Ααα ξεχασα. Ο αλγοριθμος ειναι λαθος. Υπαρχει η πιθανοτητα να μην βγει ποτε απο το λουπ.

 

 

Κρα κρα κρα

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

Αυτό ήταν πρόβλημα πριν αρκετά χρόνια.Πλέον εκτός από ειδικές κατηγορίες δεν κάνει καμία διαφορά για 10-15 mb.

Αχά. I see.

 

Σχετικο ειναι. Πχ αν εχεις τιποτα gb array, ε ναι εκει κοιτας και τι τυπο θα παιξεις, τωρα για τα δικασου 5 ολα και ολα byte... Καταλαβαινεις ειναι αστειο.

 

Εεεεενι γουέι, δες το στυλ με το οποιο γραφεις. Ονοματα μεταβλητων, κλασεων, εβεντς κλπ. Αλλου γραφεις με κεφαλαια αλλου με μικρα αλλου με ελληνικα αλλου αφηνεις τον code generator με τα default name του.

 

Τωρα αν θες να παιξεις με περφορμανς, κανε override την OnPaint, παιξε με control.grapgics και βαλε λιγο δικο σου βισουαλ στο προτζεκτ σου.

Ααα ξεχασα. Ο αλγοριθμος ειναι λαθος. Υπαρχει η πιθανοτητα να μην βγει ποτε απο το λουπ.

 

 

Κρα κρα κρα

 

Συνήθως, τα ονόματα των μεθόδων και των αντικειμένων τα γράφω PascalCase, και των τυπικών μεταβλητών (int,double,etc..) camelCase.

Τα Ελληνικά (και όχι τα Greeklish) ξεφύτρωσαν επειδή τα ονόματα αυτών των μεθόδων έγιναν auto generated, διπλοκλικάροντας στα στοιχεία GUI στον Designer, τα οποία στο συγκεκριμένο είναι μόνο στα Ελληνικά και δεν μεταφράζονται. Τώρα οι φωτογραφίες που περνάω στα resources είναι άλλο θέμα...

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

Και νομίζω πως στο συγκεκριμένο παράδειγμα, λόγο μικρού μεγέθους, δεν πειράζει αν αφήσω το Form1 να λέγεται Form1. Σε ένα άλλο μεγαλύτερο που δουλεύω εδώ και κάτι μήνες, εξυπακούεται ότι δίνω σε όλα τα δικά τους ονόματα.

 

...

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

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

Λες είναι καλύτερο να μη χρησιμοποιώ bytes για μικρά νούμερα από εδώ και πέρα, για να αποφεύγω τις μετατροπές ;

 

Απλά να σκέφτεσαι χειροπιαστά ποιό ακριβώς είναι το αποτέλεσμα αυτών που κάνεις. 

 

Αν θες να γίνουμε πολύ technical, έχεις μια List με 5 θέσεις. Αυτό θα καταλήξει ονομαστικά σε ένα heap allocation των 5 bytes αν είναι byte[], 20 bytes αν είναι int[].

 

Είναι (πολύ) πιθανό πως ο heap allocator που χρησιμοποιεί τελικά η εφαρμογή θα έχει κάποια ειδική πρόβλεψη για γρήγορο allocation μικρών πινάκων από primitives, το οποίο γίνεται κάνοντας allocate ένα μεγάλο πίνακα και χωρίζοντάς τον εσωτερικά σε κομμάτια on demand. Αν στο πρόγραμμά σου έχεις ήδη τέτοιο allocation μπορεί η διαφορά στη μνήμη που θα δεσμευτεί να είναι μηδέν. Ή μπορεί και όχι.

 

Αντίστοιχα το οποιοδήποτε allocation θα πρέπει πρώτα να έχει εξυπηρετηθεί από το λειτουργικό ζητώντας μνήμη. Το κβάντο του allocation από το OS είναι το μέγεθος της σελίδας, που στην πράξη είναι 4Κ (μπορείς να το βρεις έτσι). Το πιο πιθανό είναι πως τα 15 bytes της διαφοράς δε θα είναι αρκετά για να ζητήσει η εφαρμογή σου περισσότερη μνήμη από το λειτουργικό γιατί θα έχει ήδη περίσσευμα από κάποια page που είναι σε χρήση. Επομένως από την πλευρά του λειτουργικού η εφαρμογή θα καταναλώσει ακριβώς το ίδιο ποσό μνήμης και στις δύο περιπτώσεις.

 

Φυσικά όλα αυτά είναι τζάμπα κουβέντα επειδή έτσι κι αλλιώς και 4Κ παραπάνω να καταναλώσει το πρόγραμμά σου τελικά, noone fucking cares. Άνοιξε task manager να δεις πόση μνήμη καταναλώνεις ήδη στην εφαρμογή. 4Κ παραπάνω είναι το τίποτα.

 

Γιατί τα λέω όλα αυτά. Όχι γιατί θα έπρεπε να τα ξέρεις ήδη, αλλά επειδή σε κάποιο βαθμό θα πρέπει να ξέρεις γιατί κάνεις αυτό που κάνεις, ποιά είναι η ουσία του στην πράξη. 15 bytes μνήμης σε απασχολούν όταν το σύστημα στο οποίο δουλεύεις έχει όλα κι όλα 8Κ. :-)

 

 

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

Αυτά είναι coding standards και ο καθένας έχει από ένα. Αλγόριθμος επιλογής:

 

1. Πάντα να χρησιμοποιείς κάποιο coding standard ακόμα κι αν είναι δικής σου κατασκευής.

2. Αν είσαι σε ομάδα, αυτό που ήδη χρησιμοποιεί η ομάδα είναι το καλύτερο.

3. Αν όχι, χρησιμοποίησε της Microsoft. Το οποίο λέει να μη βάζεις prefixes.

 

Το να μη τα μπερδεύεις με τοπικές σηκώνει πολλή συζήτηση, αλλά ένας άλλος τρόπος να το κάνεις (που μου φαίνεται very reasonable) είναι στα fields να γράφεις πάντα "this." από μπροστά.

 

Και νομίζω πως στο συγκεκριμένο παράδειγμα, λόγο μικρού μεγέθους, δεν πειράζει αν αφήσω το Form1 να λέγεται Form1. Σε ένα άλλο μεγαλύτερο που δουλεύω εδώ και κάτι μήνες, εξυπακούεται ότι δίνω σε όλα τα δικά τους ονόματα.

Με την ευκαιρία, μη πετάς όλο τον κώδικά σου στη Form1. Όχι γιατί κάνει διαφορά, απλά για εξάσκηση. Wax on, wax off. Δε μπορείς να φτάσεις στο σημείο να κάνεις σωστά από την αρχή τα δύσκολα αν δε σου έχει γίνει συνήθεια να κάνεις σωστά τα εύκολα.

 

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

Ναι.

 

Γενικά η παραγωγή "unique random numbers" είναι πολύ πιο δύσκολο να γίνει ολόσωστα απ' όσο φαίνεται εκ πρώτης. Στην πράξη αυτό που πρέπει να κάνεις για να επιλέξεις Ν μοναδικούς τυχαίους από ένα σετ Μ επιλογών είναι:

  • αν το Μ και το Ν είναι συγκρίσιμα τότε κάνεις Knuth-Fisher-Yates shuffle και παίρνεις τα πρώτα Ν νούμερα
  • αν Ν << Μ τότε κάνεις Floyd's random sampling το οποίο δεν απαιτεί μνήμη ανάλογη του Μ

Στη δική σου περίπτωση οτιδήποτε από τα δύο θα ήταν λογικό. Προσωπικά θα έγραφα K-F-Y σε μια extension method Shuffle με βλέψη στο τέλος ο κώδικάς μου να γράφει

 

var result = Enumerable.Range(1, 45).Shuffle().Take(5).OrderBy(n => n).ToList();

Μου αρέσει άπειρα αυτή η μορφή (και κατ' επέκταση αγαπώ LINQ) γιατί αποδίδει σε σχεδόν κανονικά αγγλικά το τι ακριβώς σκοπεύω να κάνω: Πάρε τα νούμερα 1 ως 45, ανακάτεψέ τα, διάλεξε 5 στην τύχη, βάλτα σε αύξουσα σειρά και πες μου ποιά είναι.

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

 

Απλά να σκέφτεσαι χειροπιαστά ποιό ακριβώς είναι το αποτέλεσμα αυτών που κάνεις. 

 

Αν θες να γίνουμε πολύ technical, έχεις μια List με 5 θέσεις. Αυτό θα καταλήξει ονομαστικά σε ένα heap allocation των 5 bytes αν είναι byte[], 20 bytes αν είναι int[].

 

Είναι (πολύ) πιθανό πως ο heap allocator που χρησιμοποιεί τελικά η εφαρμογή θα έχει κάποια ειδική πρόβλεψη για γρήγορο allocation μικρών πινάκων από primitives, το οποίο γίνεται κάνοντας allocate ένα μεγάλο πίνακα και χωρίζοντάς τον εσωτερικά σε κομμάτια on demand. Αν στο πρόγραμμά σου έχεις ήδη τέτοιο allocation μπορεί η διαφορά στη μνήμη που θα δεσμευτεί να είναι μηδέν. Ή μπορεί και όχι.

 

Αντίστοιχα το οποιοδήποτε allocation θα πρέπει πρώτα να έχει εξυπηρετηθεί από το λειτουργικό ζητώντας μνήμη. Το κβάντο του allocation από το OS είναι το μέγεθος της σελίδας, που στην πράξη είναι 4Κ (μπορείς να το βρεις έτσι). Το πιο πιθανό είναι πως τα 15 bytes της διαφοράς δε θα είναι αρκετά για να ζητήσει η εφαρμογή σου περισσότερη μνήμη από το λειτουργικό γιατί θα έχει ήδη περίσσευμα από κάποια page που είναι σε χρήση. Επομένως από την πλευρά του λειτουργικού η εφαρμογή θα καταναλώσει ακριβώς το ίδιο ποσό μνήμης και στις δύο περιπτώσεις.

 

Φυσικά όλα αυτά είναι τζάμπα κουβέντα επειδή έτσι κι αλλιώς και 4Κ παραπάνω να καταναλώσει το πρόγραμμά σου τελικά, noone fucking cares. Άνοιξε task manager να δεις πόση μνήμη καταναλώνεις ήδη στην εφαρμογή. 4Κ παραπάνω είναι το τίποτα.

 

Γιατί τα λέω όλα αυτά. Όχι γιατί θα έπρεπε να τα ξέρεις ήδη, αλλά επειδή σε κάποιο βαθμό θα πρέπει να ξέρεις γιατί κάνεις αυτό που κάνεις, ποιά είναι η ουσία του στην πράξη. 15 bytes μνήμης σε απασχολούν όταν το σύστημα στο οποίο δουλεύεις έχει όλα κι όλα 8Κ. :-)

 

 

Πολύ ενδιαφέρον αυτό με τις σελίδες της μνήμης. Βέβαια στο παρόν πρόγραμμα η διαφορά είναι αμελητέα, αλλά σε κάτι μεγαλύτερο ή όταν πρόκειται για συσκευή με λίγη μνήμη, θα είναι χρήσιμη γνώση. Άλλαξα τα byte σε int, αλλά δεν αναφέρει καμία διαφορά ούτε σε cpu usage, ούτε memory usage. 

 

 

 

Αυτά είναι coding standards και ο καθένας έχει από ένα. Αλγόριθμος επιλογής:

 

1. Πάντα να χρησιμοποιείς κάποιο coding standard ακόμα κι αν είναι δικής σου κατασκευής.

2. Αν είσαι σε ομάδα, αυτό που ήδη χρησιμοποιεί η ομάδα είναι το καλύτερο.

3. Αν όχι, χρησιμοποίησε της Microsoft. Το οποίο λέει να μη βάζεις prefixes.

 

Το να μη τα μπερδεύεις με τοπικές σηκώνει πολλή συζήτηση, αλλά ένας άλλος τρόπος να το κάνεις (που μου φαίνεται very reasonable) είναι στα fields να γράφεις πάντα "this." από μπροστά.

 

Κλίνω προς αυτό της Microsoft τελικά να πω την αλήθεια. Απλά μερικές φορές ξεφεύγει κάτι από βιασύνη, αλλά συνήθως αργότερα όταν θα ξανακοιτάξω / ελέγξω με ηρεμία και γαλήνη το κώδικα, αλλάζω κάποια. (Συνήθως άλλα πράγματα, αλλά και ονομασίες μερικές φορές)

 

 

 

Με την ευκαιρία, μη πετάς όλο τον κώδικά σου στη Form1. Όχι γιατί κάνει διαφορά, απλά για εξάσκηση. Wax on, wax off. Δε μπορείς να φτάσεις στο σημείο να κάνεις σωστά από την αρχή τα δύσκολα αν δε σου έχει γίνει συνήθεια να κάνεις σωστά τα εύκολα.

 

Αυτό με το κώδικα στη 'κεντρική' φόρμα μου ήρθε σαν χτύπημα. Σε ένα άλλο, αρκετά μεγαλύτερο (3.500+ lines) που δουλεύω εδώ και κάποιο καιρό, είχα τη φαεινή ιδέα στην αρχή, να διαχωρίσω τα διάφορα στοιχεία που υπήρχαν στο GUI σε θεματικές ενότητες, και να αναπτύξω τη κάθε ξεχωριστή ενότητα ως αυτόνομο control (VSIX). Είχα στο μυαλό μου το plan for reuse, και σκεφτόμουνα κάθε τι που κάνω να το κάνω ως ξεχωριστή μονάδα, μη πάει και μου χρησιμεύσει στο μέλλον. Τελικά "έμπλεξα τα μπούτια μου" με τα refferences που έπρεπε να κάνουν τα διαφορετικά assemblies μεταξύ τους (μιας και όντως συστατικά του ίδιου προγράμματος, πρέπει να αλληλεπιδρούν) και έφτασα σε τέλμα επειδή το ένα assembly δε μπορούσε να κάνει refference κάποιο άλλο, χρειαζόταν η static μέθοδος να χρησιμοποιήσει μη-static μέθοδο και δεν μπορούσε...  Και κένταγε η κόρη το μαντίλι, ντίλι ντίλι ντίλι! 

Σε εκείνη τη φάση χρειάστηκε να κάνω ένα 'τολμηρό' refactor και φοβήθηκα ότι θα χάσω ότι είχα ήδη φτιάξει!  :fear:

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

 

 

Ναι.

Γενικά η παραγωγή "unique random numbers" είναι πολύ πιο δύσκολο να γίνει ολόσωστα απ' όσο φαίνεται εκ πρώτης. Στην πράξη αυτό που πρέπει να κάνεις για να επιλέξεις Ν μοναδικούς τυχαίους από ένα σετ Μ επιλογών είναι:

  • αν το Μ και το Ν είναι συγκρίσιμα τότε κάνεις Knuth-Fisher-Yates shuffle και παίρνεις τα πρώτα Ν νούμερα
  • αν Ν << Μ τότε κάνεις Floyd's random sampling το οποίο δεν απαιτεί μνήμη ανάλογη του Μ

Στη δική σου περίπτωση οτιδήποτε από τα δύο θα ήταν λογικό. Προσωπικά θα έγραφα K-F-Y σε μια extension method Shuffle με βλέψη στο τέλος ο κώδικάς μου να γράφει

 

var result = Enumerable.Range(1, 45).Shuffle().Take(5).OrderBy(n => n).ToList();

Μου αρέσει άπειρα αυτή η μορφή (και κατ' επέκταση αγαπώ LINQ) γιατί αποδίδει σε σχεδόν κανονικά αγγλικά το τι ακριβώς σκοπεύω να κάνω: Πάρε τα νούμερα 1 ως 45, ανακάτεψέ τα, διάλεξε 5 στην τύχη, βάλτα σε αύξουσα σειρά και πες μου ποιά είναι.

 

Χμ.

Δηλαδή πχ:

            var at = Enumerable.Range(1, 45).ToList(); 
            at = Shuffle(at);
            var g = at.Take(5);
            var query = from n in g
                 orderby n ascending
                 select n; 
            at = query.ToList();

            ProtosArithmos.Text = at[0].ToString();
            DefterosArithmos.Text = at[1].ToString();
            TritosArithmos.Text = at[2].ToString();
            TetartosArithmos.Text = at[3].ToString();
            PemptosArithmos.Text = at[4].ToString();
public List<T> Shuffle<T>(List<T> list)
        {
            int n = list.Count;
            while (n > 1)
            {
                n--;
                int k = rng.Next(n + 1);
                T value = list[k];
                list[k] = list[n];
                list[n] = value;
            }
            return list;
        } 

?

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

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

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

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

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

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

Σύνδεση

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

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

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