34. enum
An enum (enumeration) is a named set of constants, making code more readable and maintainable by replacing magic numbers with meaningful names.
Example:
enum DayOfWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }
DayOfWeek today = DayOfWeek.Monday;
Enums improve code clarity and reduce errors by restricting values to predefined options.
35. delegate
A delegate is a type-safe function pointer that stores references to methods and allows methods to be passed as parameters.
Example:
delegate void PrintMessage(string message);
void Print(string msg) => Console.WriteLine(msg);
PrintMessage printer = Print;
printer("Hello, Delegates!");
Delegates enable callbacks, event handling, and flexible method invocation.
36. event
An event is a specialized delegate used in the observer pattern, allowing subscribers to listen for changes and react dynamically.
Example:
class Button
{
public event Action Clicked; // Declaring an event
public void Press() => Clicked?.Invoke(); // Trigger event
}
var button = new Button();
button.Clicked += () => Console.WriteLine("Button clicked!"); // Subscribing
button.Press();
Events enable publish-subscribe communication, improving modularity.
37. partial class
A partial class allows splitting a class definition across multiple files, useful for large projects, auto-generated code, or maintaining cleaner code.
Example:
File 1:
partial class Car
{
public void Drive() { Console.WriteLine("Driving..."); }
}
File 2:
partial class Car
{
public void Brake() { Console.WriteLine("Braking..."); }
}
Partial classes improve code organization and collaborative development.
38. partial method
A partial method is a method declared in a partial class that only compiles if implemented in another file.
Example:
partial class Logger
{
partial void Log(string message);
}
partial class Logger
{
partial void Log(string message)
{
Console.WriteLine("Log: " + message);
}
}
Partial methods are useful for auto-generated code, allowing optional developer overrides.
39. sealed
A sealed class cannot be inherited, and a sealed method cannot be overridden in derived classes. This is useful for security, performance, and enforcing final implementations.
Example:
sealed class FinalClass { }
// Sealed method example
class Base
{
public virtual void Show() { Console.WriteLine("Base"); }
}
class Derived : Base
{
public sealed override void Show() { Console.WriteLine("Derived"); }
}
Sealed classes prevent unintended inheritance and optimize runtime performance.
40. abstract
An abstract class serves as a base class that cannot be instantiated, while abstract methods are required to be implemented in derived classes.
Example:
abstract class Animal
{
public abstract void MakeSound(); // No implementation
}
class Dog : Animal
{
public override void MakeSound() { Console.WriteLine("Bark!"); }
}
Abstract classes provide a template for subclasses, enforcing structure while allowing flexibility.
41. abstract method
An abstract method is a method that is declared in a base class but has no implementation. It acts as a blueprint, enforcing that any derived class must provide a concrete implementation. Abstract methods can only be declared within abstract classes, meaning the class itself is incomplete and cannot be instantiated directly.
For example, in C#:
abstract class Animal {
public abstract void MakeSound(); // No implementation
}
class Dog : Animal {
public override void MakeSound() {
Console.WriteLine("Bark!");
}
}
Here, MakeSound() is abstract in Animal, and Dog must override it. This ensures all animals define their own sound. Abstract methods enforce consistency across subclasses while allowing flexibility in implementation.
They are useful in scenarios where a common interface is required, but the behavior must be determined by individual subclasses. This follows the Liskov Substitution Principle (LSP) in Object-Oriented Programming (OOP), ensuring that derived classes can be used interchangeably with their base types.
42. virtual method
A virtual method is a method in a base class that provides a default implementation but allows derived classes to override it if needed. Unlike abstract methods, virtual methods do not force derived classes to provide an implementation—they have the option to do so.
Example in C#:
class Animal {
public virtual void MakeSound() {
Console.WriteLine("Some generic animal sound");
}
}
class Dog : Animal {
public override void MakeSound() {
Console.WriteLine("Bark!");
}
}
Here, MakeSound() is virtual, meaning it has a default behavior, but Dog can (and does) override it. If Dog did not override it, it would inherit the base class behavior.
Virtual methods allow for polymorphism, enabling dynamic method invocation at runtime. This is particularly useful in scenarios like designing extensible frameworks where subclasses can modify only necessary behaviors without reimplementing everything.
43. override
The override keyword in C# is used in a derived class to provide a new implementation for a virtual or abstract method from its base class. The overriding method must have the same signature as the base method.
Example:
class Animal {
public virtual void Speak() {
Console.WriteLine("Animal speaks");
}
}
class Dog : Animal {
public override void Speak() {
Console.WriteLine("Bark!");
}
}
Here, Speak() in Dog overrides the base class implementation, ensuring that when called on a Dog object, the specific method runs instead of the base version.
Overriding is a key feature of runtime polymorphism, allowing objects to be treated as their base type while executing derived-type behavior. Overridden methods replace base implementations but still allow calling the base version using base.MethodName() if needed.
44. new keyword (hiding/shadowing)
The new keyword in C# is used to hide or shadow a member (method, property, or field) from the base class rather than overriding it. It is different from override, as it does not participate in polymorphism.
Example:
class BaseClass {
public void Display() {
Console.WriteLine("Base class method");
}
}
class DerivedClass : BaseClass {
public new void Display() {
Console.WriteLine("Derived class method");
}
}
If you declare a DerivedClass object but reference it as a BaseClass, the base method will be called. Unlike overriding, new keyword hides the base method instead of replacing it.
Hiding can be useful when dealing with legacy code but is generally discouraged because it can lead to confusion and maintenance issues.
45. access modifiers
Access modifiers in C# define visibility and accessibility of classes, methods, and variables. They enforce encapsulation and determine how members are accessed across different classes and assemblies.
- public → Accessible from anywhere.
- private → Accessible only within the same class.
- protected → Accessible within the same class and derived classes.
- internal → Accessible within the same assembly (project).
- protected internal → Accessible within the same assembly OR by derived classes.
- private protected → Accessible only within the same assembly AND by derived classes.
Choosing the right access modifier is crucial for designing secure and maintainable code.
46. public
A public member is accessible from anywhere, inside or outside the class or assembly. This is the least restrictive access level.
Example:
class Example {
public int Value = 10;
}
Example obj = new Example();
Console.WriteLine(obj.Value); // Allowed
While public is convenient, overusing it can lead to poor encapsulation, making code harder to maintain.
47. private
A private member is only accessible within the same class. This is the most restrictive modifier, enforcing data hiding and encapsulation.
Example:
class Example {
private int value = 10;
}
Attempting to access value from outside the class results in a compilation error. Private fields are often accessed via public methods (getters and setters) to control access.