Step into object-oriented programming: classes, objects, fields, properties, constructors and static members, while writing a Resistor class.
What is a class?
So far we have kept data (variables) and operations (methods) separate. A class brings them together: it defines both what information something carries and what it can do. A class is a template; each concrete example produced from that template is called an object.
An analogy: the concept of a "Resistor" is the class; the particular 1 kΩ resistor on your desk is the object. Every resistor has a value and a tolerance, and each of them can calculate power.
Your first class
var r1 = new Resistor { Value = 1000, Tolerance = 5 };
Console.WriteLine($"{r1.Value} ohm, {r1.Tolerance}%");
Console.WriteLine($"Power at 5 V: {r1.CalculatePower(5):F3} W");
class Resistor
{
public double Value { get; set; } // ohm
public double Tolerance { get; set; } // percent
public double CalculatePower(double voltage)
{
return voltage * voltage / Value; // P = V² / R
}
}
1000 ohm, 5%
Power at 5 V: 0.025 W
new Resistor() creates a new object in memory. Value and Tolerance are properties; they hold the object's data. CalculatePower is a method of the object. You reach an object's members with a dot: r1.Value.
Note: When working with top-level statements, you need to put class definitions at the end of the file or in a separate file; top-level code must be written before the classes.
The constructor
To require initial values when an object is created, you write a constructor. Its name is the same as the class, and it has no return type.
var r = new Resistor(470);
Console.WriteLine(r);
Console.WriteLine($"The real value is between {r.LowerBound:F1} and {r.UpperBound:F1}");
class Resistor
{
public double Value { get; }
public double Tolerance { get; }
public Resistor(double value, double tolerance = 5)
{
if (value <= 0)
throw new ArgumentException("Resistance must be greater than zero.");
Value = value;
Tolerance = tolerance;
}
public double LowerBound => Value * (1 - Tolerance / 100);
public double UpperBound => Value * (1 + Tolerance / 100);
public override string ToString() => $"{Value} Ω (±{Tolerance}%)";
}
470 Ω (±5%)
The real value is between 446.5 and 493.5
There are three new things here: { get; } is a read-only property (its value is assigned only in the constructor); LowerBound is a computed property; and by override-ing the ToString() method we defined the object's text form. That way Console.WriteLine(r) prints something meaningful.
Access modifiers
public: accessible from anywhere.private: only from inside the class itself. If you write nothing, class members are private by default.protected: from the class and the classes that inherit from it (next lesson).
Hiding the data and opening it up only through controlled doors (properties, methods) is called encapsulation. For example, enforcing the rule "a resistance cannot be zero" in the constructor prevents an invalid object from ever being created.
static members
A static member belongs not to an object but to the class itself. It suits information shared by all objects:
var a = new Counter();
var b = new Counter();
Console.WriteLine(Counter.TotalObjects); // 2
class Counter
{
public static int TotalObjects { get; private set; }
public Counter()
{
TotalObjects++;
}
}
The Console and Math classes are static too: you write Math.Sqrt(9) without creating an object from them.
Record: For classes that only carry data, there is a one-line short form such as record Measurement(string Channel, double Value);. It gives you things like equality and printing automatically. We will use it in the LINQ lesson.
Warning: Classes are reference types. When you write var y = x;, the object is not copied; two variables point to the same object. A change made through one is visible through the other.
Try it yourself
Write a class called Sensor: it should have Name and Unit properties, a List<double> that holds the measurement values, an Add(double) method and an Average() method. Create two sensor objects, add a few measurements and print the averages. When there are no measurements, Average should return 0.
// Mini quiz
Click an option; you will see right away, with the reason, whether it is correct or not.
Mark it when you finish: your progress is saved and you earn +20 XP.
Tip: ← → keys let you move between lessons.