Οι σταθερές (constants) στην C# είναι τιμές που δεν αλλάζουν ποτέ. Σκέψου τις σαν κουτιά που κρατούν κάτι πολύτιμο και αυτό το κάτι δεν μπορεί να αλλάξει ποτέ. Μόλις βάλεις κάτι μέσα στο κουτί, παραμένει εκεί για πάντα.
Τι είναι οι σταθερές;
Οι σταθερές είναι σαν αριθμοί ή λέξεις που δεν αλλάζουν ποτέ. Για παράδειγμα, αν έχεις ένα αγαπημένο νούμερο και δεν θέλεις ποτέ να αλλάξει, μπορείς να το αποθηκεύσεις ως σταθερά.
Πώς τις δηλώνουμε;
Για να δηλώσεις μια σταθερά στην C#, χρησιμοποιείς τη λέξη-κλειδί const
. Ας δούμε πώς γίνεται αυτό:
const int MyFavoriteNumber = 7;
const string MyName = “Alice”;
Στο παραπάνω παράδειγμα, δηλώνουμε δύο σταθερές:
MyFavoriteNumber
που είναι το νούμερο 7.MyName
που είναι το όνομα “Alice”.
Τι κάνουν οι σταθερές;
Οι σταθερές κρατούν τιμές που δεν αλλάζουν. Είναι χρήσιμες όταν έχεις τιμές που ξέρεις ότι θα παραμείνουν οι ίδιες σε όλο το πρόγραμμα. Μερικά παραδείγματα είναι:
- Η τιμή του π (π = 3.14159)
- Ο αριθμός των ημερών σε μια εβδομάδα (7)
- Η ταχύτητα του φωτός σε κενό (299,792,458 μέτρα ανά δευτερόλεπτο)
Πού χρησιμοποιούμε τις σταθερές;
Χρησιμοποιούμε τις σταθερές όταν θέλουμε να διασφαλίσουμε ότι μια τιμή δεν θα αλλάξει κατά λάθος κατά την εκτέλεση του προγράμματος.
ο `const` πεδίο είναι σταθερό και η τιμή του πρέπει να ανατεθεί κατά τη δήλωση. Δεν μπορεί ποτέ να αλλάξει μετά την ανάθεση.
Για παράδειγμα:
using System;
class Program
{
const double Pi = 3.14159;
}
static void Main()
{
double radius = 5.0;
double area = Pi * radius * radius;
Console.WriteLine(“Η επιφάνεια του κύκλου είναι: ” + area);
}
}
Στο παραπάνω πρόγραμμα, χρησιμοποιούμε τη σταθερά Pi
για να υπολογίσουμε την επιφάνεια ενός κύκλου με ακτίνα 5. Η τιμή του Pi
δεν θα αλλάξει ποτέ, έτσι μπορούμε να είμαστε σίγουροι ότι ο υπολογισμός είναι πάντα σωστός.
Χαρακτηριστικά του `const`
1. Ανάθεση τιμής:
– Πρέπει να ανατεθεί κατά τη δήλωση.
– Δεν μπορεί να ανατεθεί ή να αλλάξει μετά από αυτό.
2. Μεταβλητότητα:
– Η τιμή είναι σταθερή και ίδια για όλα τα αντικείμενα της κλάσης.
– Γνωστή κατά τον χρόνο μεταγλώττισης.
3. Χρήση:
– Χρησιμοποιείται για τιμές που είναι απόλυτα σταθερές και γνωστές από την αρχή, όπως μαθηματικές σταθερές, ρυθμίσεις, κλπ.
Παράδειγμα
public class MathConstants
{
// Σταθερές τιμές
public const double Pi = 3.14159;
public const int LightSpeed = 299792458; // σε μέτρα ανά δευτερόλεπτο
}
public class Program
{
public static void Main()
{
Console.WriteLine($”Pi: {MathConstants.Pi}”);
Console.WriteLine($”Speed of Light: {MathConstants.LightSpeed} m/s”);
// Αυτή η γραμμή θα προκαλέσει σφάλμα κατά τη μεταγλώττιση MathConstants.Pi = 3.14;
}
}
Συμπέρασμα
Οι σταθερές είναι τιμές που δεν αλλάζουν ποτέ και χρησιμοποιούνται για να κρατήσουμε τιμές που είναι σημαντικές και δεν πρέπει να αλλάξουν. Είναι σαν κουτιά που κρατούν κάτι πολύτιμο, και μόλις βάλεις κάτι μέσα, παραμένει εκεί για πάντα. Χρησιμοποιούμε τη λέξη-κλειδί const
για να δηλώσουμε μια σταθερά και είναι πολύ χρήσιμες για να διασφαλίσουμε ότι σημαντικές τιμές δεν θα αλλάξουν κατά λάθος.
Πότε χρησιμοποιούμε readonly και πότε const;
– readonly: Χρησιμοποιούμε το `readonly` όταν θέλουμε να καθορίσουμε την τιμή κάτι που μπορεί να είναι διαφορετική κάθε φορά που δημιουργούμε ένα αντικείμενο, αλλά μετά από αυτό, δεν πρέπει να αλλάξει. Σαν το βιβλίο που μπορείς να γράψεις μόνο μία φορά.
– const: Χρησιμοποιούμε το `const` όταν ξέρουμε από την αρχή την τιμή και αυτή δεν θα αλλάξει ποτέ. Σαν τον αριθμό που δεν αλλάζει ποτέ.
Read Only
Τι είναι το readonly;
Φαντάσου ότι έχεις ένα βιβλίο στο οποίο μπορείς να γράψεις μόνο μία φορά. Μόλις γράψεις κάτι σε αυτό το βιβλίο, δεν μπορείς ποτέ ξανά να αλλάξεις ό,τι έγραψες. Μπορείς να γράψεις το περιεχόμενο είτε την πρώτη στιγμή που παίρνεις το βιβλίο (δηλαδή όταν το δημιουργείς) είτε την πρώτη φορά που το ανοίγεις (δηλαδή όταν αρχίσεις να το χρησιμοποιείς), αλλά μετά από αυτό, δεν μπορείς να το αλλάξεις.
Παράδειγμα
Στην C#, αυτό θα ήταν κάτι σαν:
public class MyBook
{
public readonly string Title;
// Εδώ γράφεις τον τίτλο την πρώτη στιγμή που παίρνεις το βιβλίο
public MyBook(string title)
{
Title = title;
}
// Δεν μπορείς να αλλάξεις τον τίτλο μετά
public void ChangeTitle(string newTitle)
{
// Αυτό θα προκαλέσει λάθος
// Title = newTitle;
}
}
Το `readonly` πεδίο μπορεί να ανατεθεί είτε κατά τη δήλωση είτε μέσα στον κατασκευαστή της κλάσης. Μετά την ανάθεση, δεν μπορεί να αλλάξει.
Χαρακτηριστικά του `readonly`
1. Ανάθεση τιμής:
– Μπορεί να ανατεθεί κατά τη δήλωση.
– Μπορεί να ανατεθεί μέσα στον κατασκευαστή της κλάσης.
2. Μεταβλητότητα:
– Μπορεί να έχει διαφορετικές τιμές για διαφορετικά αντικείμενα της κλάσης.
– Δεν μπορεί να αλλάξει μετά την αρχική ανάθεση (ούτε μέσα σε μεθόδους της κλάσης).
3. Χρήση:
– Χρησιμοποιείται όταν μια τιμή πρέπει να είναι σταθερή για το συγκεκριμένο αντικείμενο αλλά μπορεί να είναι διαφορετική για κάθε αντικείμενο της κλάσης.
Παράδειγμα
public class Car
{
public readonly string Make;
public readonly int Year;
// Ανάθεση τιμών στον κατασκευαστή
public Car(string make, int year)
{
Make = make;
Year = year;
}
public void PrintDetails()
{
Console.WriteLine($”Car Make: {Make}, Year: {Year}”);
}
}
public class Program
{
public static void Main()
{
Car car1 = new Car(“Toyota”, 2020);
Car car2 = new Car(“Honda”, 2018);
car1.PrintDetails(); // Εκτυπώνει “Car Make: Toyota, Year: 2020”
car2.PrintDetails(); // Εκτυπώνει “Car Make: Honda, Year: 2018”
}
}
παράδειγμα
Η χρήση του `readonly` σε πεδίο σημαίνει ότι η τιμή του μπορεί να αλλάξει μόνο κατά την αρχικοποίησή του ή μέσα στον κατασκευαστή της κλάσης. Δεν μπορεί να αλλάξει η τιμή του μετά την κατασκευή του αντικειμένου από οπουδήποτε αλλού.
Ωστόσο, μπορείς να το αλλάξεις σε μεταγενέστερο χρόνο μόνο μέσα στον κατασκευαστή. Παρακάτω σου παραθέτω ένα παράδειγμα που δείχνει αυτήν τη δυνατότητα:
using System;
public class Car
{
public readonly string model;
public readonly string manufacturer;
// Κατασκευαστής της κλάσης που επιτρέπει την αλλαγή των readonly πεδίων
public Car(string model, string manufacturer)
{
this.model = model;
this.manufacturer = manufacturer;
}
public void DisplayInfo()
{
Console.WriteLine($”Model: {model}, Manufacturer: {manufacturer}”);
}
}
public class Program
{
public static void Main(string[] args)
{
// Δημιουργία αντικειμένου Car
Car car1 = new Car(“citroen c2”, “citroen”);
car1.DisplayInfo();
// Δεύτερη αλλαγή των readonly πεδίων μέσω νέου κατασκευαστή
Car car2 = new Car(“audi a4”, “audi”);
car2.DisplayInfo();
}
}
Επεξήγηση:
1. Δήλωση και Αρχικοποίηση:
– Τα `readonly` πεδία `model` και `manufacturer` δηλώνονται και αρχικοποιούνται στον κατασκευαστή της κλάσης `Car`.
2. Δημιουργία Αντικειμένων:
– Δημιουργούμε δύο αντικείμενα της κλάσης `Car`, το `car1` και το `car2`, με διαφορετικές τιμές για τα πεδία `model` και `manufacturer`.
3. Εκτύπωση Πληροφοριών:
– Κάθε αντικείμενο εκτυπώνει τις δικές του τιμές μέσω της μεθόδου `DisplayInfo`.
Σημαντική Σημείωση:
Τα πεδία `readonly` μπορούν να αρχικοποιηθούν μόνο κατά τη δήλωσή τους ή στον κατασκευαστή. Μετά τη δημιουργία του αντικειμένου, τα `readonly` πεδία δεν μπορούν να αλλάξουν. Αν προσπαθήσεις να τα αλλάξεις εκτός του κατασκευαστή, θα πάρεις σφάλμα μεταγλώττισης.
παράδειγμα
Για να δείξουμε πώς μπορούμε να χρησιμοποιήσουμε το `readonly` πεδίο και να το αρχικοποιήσουμε με τιμή που αλλάζει, μπορούμε να χρησιμοποιήσουμε έναν κατασκευαστή που υπολογίζει την τιμή του πεδίου κατά τη στιγμή της δημιουργίας του αντικειμένου. Αυτό επιτρέπει την τιμή να είναι διαφορετική ανάλογα με τις συνθήκες κατά τη στιγμή της δημιουργίας του αντικειμένου. Παρακάτω είναι ένα παράδειγμα:
using System;
public class Car
{
public readonly string model;
public readonly string manufacturer;
public readonly int year;
// Κατασκευαστής της κλάσης που αρχικοποιεί τα readonly πεδία
public Car(string model, string manufacturer)
{
this.model = model;
this.manufacturer = manufacturer;
this.year = DateTime.Now.Year; // Αρχικοποίηση του έτους με την τρέχουσα χρονιά
}
public void DisplayInfo()
{
Console.WriteLine($”Model: {model}, Manufacturer: {manufacturer}, Year: {year}”);
}
}
public class Program
{
public static void Main(string[] args)
{
// Δημιουργία αντικειμένου Car στην τρέχουσα χρονιά
Car car1 = new Car(“citroen c2”, “citroen”);
car1.DisplayInfo();
// Αναμονή για ένα δευτερόλεπτο πριν δημιουργηθεί το δεύτερο αντικείμενο (για παράδειγμα)
System.Threading.Thread.Sleep(1000);
// Δημιουργία αντικειμένου Car μετά από λίγο χρόνο
Car car2 = new Car(“audi a4”, “audi”);
car2.DisplayInfo();
}
}
Επεξήγηση:
1. Δήλωση και Αρχικοποίηση:
– Τα `readonly` πεδία `model`, `manufacturer`, και `year` δηλώνονται στην κλάση `Car`.
– Το πεδίο `year` αρχικοποιείται στον κατασκευαστή με την τρέχουσα χρονιά χρησιμοποιώντας `DateTime.Now.Year`.
2. Δημιουργία Αντικειμένων:
– Δημιουργούμε δύο αντικείμενα της κλάσης `Car`, το `car1` και το `car2`.
– Το `car1` δημιουργείται με την τρέχουσα χρονιά.
– Προσθέτουμε μια καθυστέρηση ενός δευτερολέπτου πριν δημιουργήσουμε το `car2`, για να δείξουμε ότι η τιμή του `year` μπορεί να αλλάξει κατά τη διάρκεια δημιουργίας των αντικειμένων.
3. Εκτύπωση Πληροφοριών:
– Κάθε αντικείμενο εκτυπώνει τις δικές του τιμές μέσω της μεθόδου `DisplayInfo`.
Σύγκριση readonly και const
– Ανάθεση:
– readonly: Μπορεί να ανατεθεί κατά τη δήλωση ή στον κατασκευαστή.
– const: Πρέπει να ανατεθεί κατά τη δήλωση.
– Μεταβλητότητα:
– readonly: Μπορεί να έχει διαφορετικές τιμές για διαφορετικά αντικείμενα.
– const: Είναι η ίδια τιμή για όλα τα αντικείμενα και είναι σταθερή κατά τον χρόνο μεταγλώττισης.
– Χρήση:
– readonly: Χρησιμοποιείται για τιμές που είναι σταθερές για το συγκεκριμένο αντικείμενο αλλά μπορεί να είναι διαφορετικές για άλλα αντικείμενα.
– const: Χρησιμοποιείται για τιμές που είναι απόλυτα σταθερές και δεν αλλάζουν ποτέ.
Συνοψίζοντας
– Το `readonly` είναι χρήσιμο για τιμές που θέλουμε να είναι σταθερές μετά την αρχική τους ανάθεση, αλλά μπορεί να διαφέρουν μεταξύ των αντικειμένων.
– Το `const` είναι χρήσιμο για τιμές που δεν αλλάζουν ποτέ και είναι γνωστές κατά τον χρόνο μεταγλώττισης.
Αυτές οι δύο λέξεις-κλειδιά προσφέρουν διαφορετικά επίπεδα αμεταβλητότητας, και η επιλογή μεταξύ τους εξαρτάται από το τι θέλεις να πετύχεις στον κώδικά σου.
Αμεταβλητότητα (Immutability) και readonly
Η αμεταβλητότητα αναφέρεται στην ιδιότητα ενός αντικειμένου να μην μπορεί να αλλάξει μετά τη δημιουργία του. Στην C#, η λέξη-κλειδί `readonly` χρησιμοποιείται για να βοηθήσει στη δημιουργία αμεταβλητών πεδίων μέσα σε μια κλάση ή δομή. Ας εξετάσουμε πιο αναλυτικά πώς το `readonly` σχετίζεται με την αμεταβλητότητα.
readonly και Αμεταβλητότητα
1. Περιορισμός Αλλαγών: Ένα `readonly` πεδίο μπορεί να ανατεθεί μόνο κατά τη δήλωση ή μέσα στον κατασκευαστή της κλάσης. Μετά από αυτό, η τιμή του πεδίου δεν μπορεί να αλλάξει. Αυτό βοηθά στην εξασφάλιση ότι η κατάσταση του αντικειμένου παραμένει σταθερή μετά την αρχική του δημιουργία.
2. Αμεταβλητά Αντικείμενα: Μπορείς να χρησιμοποιήσεις `readonly` για να δημιουργήσεις αντικείμενα που είναι σε μεγάλο βαθμό αμεταβλητά. Αν όλα τα πεδία ενός αντικειμένου είναι `readonly`, τότε μετά την κατασκευή του, η εσωτερική του κατάσταση δεν μπορεί να αλλάξει.
3. Ασφάλεια Νημάτων (Thread Safety): Τα αμεταβλητά αντικείμενα είναι εγγενώς ασφαλή για χρήση σε πολλαπλά νήματα, επειδή η κατάστασή τους δεν μπορεί να αλλάξει μετά την αρχική δημιουργία. Η χρήση του `readonly` μπορεί να βοηθήσει στη δημιουργία τέτοιων αντικειμένων.
Παράδειγμα Αμεταβλητού Αντικειμένου με `readonly`
Ας δούμε ένα παράδειγμα δημιουργίας αμεταβλητού αντικειμένου χρησιμοποιώντας `readonly`:
public class ImmutablePoint
{
public readonly int X;
public readonly int Y;
public ImmutablePoint(int x, int y)
{
X = x;
Y = y;
}
public ImmutablePoint Move(int newX, int newY)
{
// Αντί να αλλάξουμε το υπάρχον αντικείμενο, δημιουργούμε ένα νέο
return new ImmutablePoint(newX, newY);
}
}
public class Program
{
public static void Main()
{
ImmutablePoint point = new ImmutablePoint(1, 2);
Console.WriteLine($”Point: ({point.X}, {point.Y})”); // Εκτυπώνει Point: (1, 2)
ImmutablePoint newPoint = point.Move(3, 4);
Console.WriteLine($”New Point: ({newPoint.X}, {newPoint.Y})”); // Εκτυπώνει New Point: (3, 4)
// Το αρχικό σημείο παραμένει το ίδιο
Console.WriteLine($”Original Point: ({point.X}, {point.Y})”); // Εκτυπώνει Original Point: (1, 2)
}
}
“`
Οφέλη της Αμεταβλητότητας
1.Απλότητα: Τα αμεταβλητά αντικείμενα είναι πιο εύκολα στην κατανόηση και χρήση, καθώς η κατάστασή τους δεν αλλάζει μετά τη δημιουργία.
2. Ασφάλεια: Ελαχιστοποιεί τα λάθη που μπορεί να προκύψουν από αλλαγές στην κατάσταση των αντικειμένων.
3.Ασφάλεια Νημάτων: Καθώς τα αμεταβλητά αντικείμενα δεν αλλάζουν, είναι ασφαλή για χρήση σε πολλαπλά νήματα χωρίς την ανάγκη για συγχρονισμό.
Περιορισμοί και Προβλήματα
– Αρχική Ανάθεση: Πρέπει να διασφαλίσεις ότι όλες οι απαραίτητες τιμές ανατίθενται κατά την κατασκευή του αντικειμένου.
– Μνήμη: Η δημιουργία νέων αντικειμένων αντί για την αλλαγή των υπαρχόντων μπορεί να οδηγήσει σε αυξημένη χρήση μνήμης.
Συμπεράσματα
Το `readonly` είναι ένα σημαντικό εργαλείο για την επίτευξη αμεταβλητότητας στην C#. Χρησιμοποιώντας το `readonly`, μπορείς να δημιουργήσεις αντικείμενα των οποίων η κατάσταση δεν μπορεί να αλλάξει μετά την αρχική τους δημιουργία, εξασφαλίζοντας έτσι μεγαλύτερη ασφάλεια και σταθερότητα στον κώδικα σου.