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

Άποψη: 19672|Απάντηση: 1

[Πηγή] . .NET Η ιστορία της διεπαφής συλλογής μόνο για ανάγνωση

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 5/2/2018 2:28:10 μ.μ. | | |
.ΝΕΤ 4.5Προστέθηκαν δύο νέες διεπαφές συλλογής, IReadOnlyList και IReadOnlyDictionary. Αν και αυτές οι διεπαφές μπορεί να φαίνονται τόσο τετριμμένες στην επιφάνεια, αποκαλύπτουν αρκετά περίπλοκες ιστορίες σχετικά με τη συμβατότητα προς τα πίσω, τη διαλειτουργικότητα και τον ρόλο της συν-μεταβλητότητας.

Το IReadOnlyList και το IReadOnlyDictionary είναι δύο διεπαφές που πάντα ήθελαν να έχουν οι προγραμματιστές .NET. Εκτός από την παροχή κάποιας αίσθησης συμμετρίας (σε αντίθεση με τις εγγράψιμες διεπαφές), μια διεπαφή μόνο για ανάγνωση θα πρέπει να εξαλείψει την εφαρμογή μεθόδων που δημιουργούν μόνο μια εξαίρεση NotSupportedException και δεν κάνουν τίποτα. Όλα αυτά δεν ολοκληρώθηκαν λόγω χρονικών περιορισμών.

Η επόμενη ευκαιρία είναι μέσα. ΝΕΤ 2.0. Αυτό επιτρέπει στη Microsoft να αποσύρει συλλογές με αδύναμους τύπους και να τις αντικαταστήσει με συλλογές ομότιμων με ισχυρούς τύπους. Ωστόσο, η ομάδα της βιβλιοθήκης βάσης[1] έχασε για άλλη μια φορά την ευκαιρία να παράσχει μια λίστα μόνο για ανάγνωση, όπως έγραψε ο Kit George,

Δεδομένου ότι σκοπεύουμε να παρέχουμε μια προεπιλεγμένη υλοποίηση για το πρόβλημα για το οποίο μιλάτε με τον Joe, αντί να δώσουμε μια διεπαφή, παρέχουμε τη βασική κλάση ReadOnlyCollectionBase. Ωστόσο, μπορώ να καταλάβω γιατί οι άνθρωποι διστάζουν να το χρησιμοποιήσουν επειδή δεν είναι ισχυρός τύπος. Αλλά με την εισαγωγή των γενόσημων, έχουμε πλέον και το ReadOnlyCollection<T>, έτσι ώστε όχι μόνο να έχετε την ίδια λειτουργικότητα, αλλά και έναν ισχυρό τύπο: υπέροχο!

Δεδομένου ότι το ReadOnlyCollection <T>δεν είναι μια σφραγισμένη τάξη, μπορείτε να γράψετε τη δική σας συλλογή με πλήρη ταχύτητα εάν είναι απαραίτητο. Επειδή αυτές οι συλλογές που έχουμε δημιουργήσει για αυτό είναι προσαρμόσιμες σε γενικές ανάγκες, δεν σκοπεύουμε να εισαγάγουμε διεπαφές για την ίδια ιδέα.

Ο Krzysztof Cwalina εξέφρασε επίσης τη γνώμη του για αυτό το θέμα,

Είτε αυτό ακούγεται περίεργο είτε όχι, το IList και το IList <T>είναι οι δύο διεπαφές που σκοπεύουμε να χρησιμοποιήσουμε για συλλογές μόνο για ανάγνωση. Και οι δύο έχουν την δυαδική ιδιότητα IsReadOnly, η οποία θα πρέπει να επιστρέφει true όταν μια συλλογή μόνο για ανάγνωση υλοποιεί αυτήν την ιδιότητα. Ο λόγος που δεν θέλουμε να προσθέσουμε μια καθαρή διεπαφή μόνο για ανάγνωση είναι ότι πιστεύουμε ότι προσθέτει υπερβολική περιττή πολυπλοκότητα στη βασική βιβλιοθήκη. Σημειώστε ότι όσον αφορά την πολυπλοκότητα, αναφερόμαστε τόσο σε αυτή τη νέα διεπαφή όσο και στους καταναλωτές της.

Πιστεύουμε ότι εάν ο σχεδιαστής API δεν ενδιαφέρεται για τον έλεγχο της ιδιότητας IsReadOnly κατά το χρόνο εκτέλεσης και τις εξαιρέσεις που μπορεί να προκαλέσει, τότε είναι εντάξει να χρησιμοποιήσετε τη διεπαφή IList σε αυτήν την περίπτωση. Εάν είναι πρόθυμοι να παρέχουν ένα πραγματικά καθαρό προσαρμοσμένο API με μία κίνηση, τότε σε αυτήν την περίπτωση θα πρέπει να δείξουν την υλοποίηση της διεπαφής IList και να δημοσιεύσουν ένα προσαρμοσμένο API μόνο για ανάγνωση. Το τελευταίο είναι τυπικό για συλλογές που εκτίθενται από το μοντέλο αντικειμένου.

Αν και οι προγραμματιστές έχουν παραπονεθεί για αυτήν την κατάσταση, οι νέες ευκαιρίες που παρέχουν τα γενόσημα υπερτερούν κατά πολύ αυτής της ουσίας και το πρόβλημα είναι στο . Το NET 4 αγνοήθηκε σε μεγάλο βαθμό πριν. Ωστόσο, αυτή η απόφαση πυροδότησε και κάποιες αντιδράσεις, τις οποίες θα συζητήσουμε αργότερα.

Με το in. Μια συναρπαστική νέα δυνατότητα στο .NET 4 προστέθηκε στο χρόνο εκτέλεσης. Σε παλαιότερη έκδοση. .NET, όταν οι διασυνδέσεις γίνονται τύποι, αυτές οι διασυνδέσεις είναι υπερβολικά περιορισμένες. Για παράδειγμα, ακόμα και αν ο Πελάτης κληρονομήσει από το Πρόσωπο, δεν είναι δυνατό να μεταβιβάσετε ένα αντικείμενο τύπου IEnumerable <Customer>ως παράμετρο σε μια συνάρτηση τύπου IEnumerable<Person>. Με την προσθήκη συναλλοίωτης υποστήριξης, αυτός ο περιορισμός άρθηκε εν μέρει.

Λέμε "εν μέρει" επειδή σε ορισμένες περιπτώσεις οι άνθρωποι θα πρέπει να χρησιμοποιούν κάποια διεπαφή με ένα πλούσιο API ταυτόχρονα, αντί να χρησιμοποιούν μια διεπαφή IEnumerable. Ακόμα κι αν η διεπαφή IList δεν είναι συνμεταβλητή, θα πρέπει να είναι μια διεπαφή λίστας μόνο για ανάγνωση. Δυστυχώς, . Η ομάδα της βασικής βιβλιοθήκης .NET αποφάσισε και πάλι να μην αντιμετωπίσει αυτήν την παράβλεψη.

Στη συνέχεια, η εισαγωγή του WinRT και η επιστροφή του COM άλλαξαν τα πάντα. Η διαλειτουργικότητα COM ήταν κάποτε μια τεχνολογία που χρησιμοποιούσαν οι προγραμματιστές όταν δεν είχαν άλλη επιλογή, αλλά έχει γίνει μια τεχνολογία . Ο ακρογωνιαίος λίθος του προγραμματισμού .NET. Και δεδομένου ότι το WinRT εκθέτει τις διεπαφές IVectorView <T>και IMapView<K, V>, επομένως. Το .NET πρέπει επίσης να προσαρμοστεί ανάλογα.

Ένα ενδιαφέρον χαρακτηριστικό του προγράμματος WinRT είναι η ανακοίνωση διαφορετικών αλλά παρόμοιων API για κάθε πλατφόρμα ανάπτυξης. Όπως ίσως γνωρίζετε ήδη, όλα τα ονόματα μεθόδων αντιπροσωπεύονται από camelCased [2], ενώ οι προγραμματιστές C++ και .NET βλέπουν τα ονόματα μεθόδων ως PascalCased [3]. Μια άλλη πιο δραστική αλλαγή είναι η αυτόματη αντιστοίχιση μεταξύ των διεπαφών C++ και .NET. Επομένως. Οι προγραμματιστές .NET δεν χρειάζεται να ασχοληθούν με τον χώρο ονομάτων Windows.Foundation.Collections, απλώς συνεχίστε να χρησιμοποιείτε τον χώρο ονομάτων System.Collections.Generic. Οι διεπαφές IVectorView <T>και IMapView<K, V> θα μετατραπούν από το χρόνο εκτέλεσης σε διεπαφές IReadOnlyList <T>και IReadOnlyDictionary<TKey, TValue> διεπαφές, αντίστοιχα.

Αξίζει να σημειωθεί ότι αυτά τα ονόματα διεπαφής στη C++/WinRT είναι πιο ακριβή σε κάποιο βαθμό. Αυτές οι διεπαφές χρησιμοποιούνται για την αναπαράσταση ορισμένων προβολών μιας συλλογής, αλλά η διεπαφή δεν διασφαλίζει ότι η ίδια η συλλογή είναι αμετάβλητη. Ακόμη και μεταξύ εκείνων με έμπειρους. Ένα συνηθισμένο λάθος μεταξύ των προγραμματιστών .NET είναι να υποθέτουν ότι ο τύπος ReadOnlyCollection είναι αντίγραφο μιας αμετάβλητης συλλογής, αλλά στην πραγματικότητα είναι απλώς ένα περιτύλιγμα για μια ενεργή συλλογή (δείτε την ομώνυμη ανάρτηση του Andrew Arnott για περισσότερες πληροφορίες σχετικά με τις συλλογές μόνο για ανάγνωση, τις παγωμένες και τις αμετάβλητες).

Αν και η διεπαφή IList <T>έχει όλα τα ίδια μέλη με τη διεπαφή IReadOnlyList <T>και όλες οι λίστες τύπου IList <T>μπορούν να αναπαρασταθούν ως λίστες μόνο για ανάγνωση, το IList <T>δεν κληρονομεί από το IReadOnlyList<T>, κάτι που μπορεί να είναι ενδιαφέρον να μάθετε. Ο Ίμο Λάντβερθ εξήγησε,

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

Ή με άλλα λόγια, η μόνη ευκαιρία να εισαγάγετε μια διεπαφή μόνο για ανάγνωση ως κάποια βασική κλάση μεταβλητής κλάσης είναι να επιστρέψετε στο . NET 2.0, δηλαδή πότε σχεδιάστηκαν αρχικά. Μόλις κυκλοφορήσει πλήρως, η μόνη αλλαγή που μπορεί να κάνει είναι να προσθέσει δείκτες συνμεταβλητής ή/και μετατροπέα (που αντιπροσωπεύονται ως "in" και "out" σε VB και C#).

Όταν ρωτήθηκε γιατί δεν υπάρχει διεπαφή IReadOnlyCollection<T>, ο Immo απάντησε:

Εξετάσαμε αυτό το σχέδιο, αλλά θεωρήσαμε ότι η προσθήκη ενός τύπου που παρείχε μόνο το χαρακτηριστικό Count δεν θα πρόσθετε μεγάλη αξία στη βασική βιβλιοθήκη. Στην ομάδα της βασικής βιβλιοθήκης, πιστεύουμε ότι εάν ένα API ξεκινά από μείον 1000, τότε ακόμη και η παροχή κάποιας αξίας δεν αρκεί για να δικαιολογήσει την προσθήκη. Το σκεπτικό για την προσθήκη νέων API περιλαμβάνει επίσης ένα κόστος, για παράδειγμα, οι προγραμματιστές θα έχουν περισσότερες ιδέες για να διαλέξουν. Στην αρχή σκεφτήκαμε ότι η προσθήκη αυτού του τύπου θα έκανε τον κώδικα να αποδίδει καλύτερα σε ορισμένα σενάρια όπου θέλετε απλώς να μετρήσετε και στη συνέχεια να κάνετε κάτι ενδιαφέρον με αυτόν. Για παράδειγμα, μαζική προσθήκη σε μια υπάρχουσα συλλογή. Ωστόσο, σε αυτά τα σενάρια, ενθαρρύναμε τους ανθρώπους να χρησιμοποιούν μόνο τη διεπαφή IEnumerable <T>και <T>για την ειδική περίπτωση να έχουν μια παρουσία που υλοποιεί τη διεπαφή ICollection. Δεδομένου ότι όλοι οι ενσωματωμένοι τύποι συλλογής μας εφάρμοσαν αυτήν τη διεπαφή, δεν υπήρξε αύξηση απόδοσης σε αυτά τα πιο συνηθισμένα σενάρια. Παρεμπιπτόντως, <T>η μέθοδος επέκτασης Count() για το IEnumerable μπορεί επίσης να το κάνει αυτό.

Αυτές οι νέες διεπαφές είναι διαθέσιμες για . NET 4.5 και . NET για Windows 8。

Σημειώσεις μετάφρασης

[1] Base Class Library, συντομογραφία BCL. Για περισσότερες πληροφορίες σχετικά με τη βιβλιοθήκη βασικής τάξης, συμμετάσχετε στο MSDN.

[2] camelCased, ονοματολογία καμπούρας, γνωστή και ως κάτω περίπτωση καμήλας. Η μορφή είναι ότι η πρώτη λέξη αρχίζει με πεζό γράμμα. Το πρώτο γράμμα της δεύτερης λέξης γράφεται με κεφαλαία, για παράδειγμα: firstName, lastName.

[3] PascalCased, ονοματολογία Pascal, γνωστή και ως άνω περίπτωση καμήλας. Η μορφή είναι ότι το πρώτο γράμμα κάθε λέξης γράφεται με κεφαλαία, για παράδειγμα: Όνομα, Επώνυμο, CamelCase.




Προηγούμενος:Πλατφόρμα αδειοδότησης λογισμικού .NET/C# [Πηγαίος κώδικας]
Επόμενος:JS Mining - Πώς εξορύσσεται το Monero με εξόρυξη ιστού;
Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com