
11. Standard Interfaces
Standard Interfaces in C#
IComparable<T>
The IComparable<T> interface allows objects of a custom class to be compared with one another. It defines a single method:
int CompareTo(T other);
This method returns an integer that indicates the relative ordering between the current object and another:
- A negative integer indicates the current object precedes the other in the sort order.
- Zero indicates they are equal in the sort order.
- A positive integer indicates the current object follows the other.
Example
public class Student : IComparable<Student>
{
public int Age { get; set; }
public double Score { get; set; }
public int CompareTo(Student other)
{
// Reverse sorting by Age
if (this.Age > other.Age)
return -1;
else if (this.Age < other.Age)
return 1;
else
return 0;
}
public override string ToString()
{
return $"Age {Age}, Score {Score}";
}
}
When placing Student
objects in a List<Student>
, the .Sort()
method will automatically use CompareTo()
to order the items.
IEnumerable
IEnumerable is another common interface in C#, allowing an object to be enumerated (used in a foreach
loop). It defines one method: GetEnumerator()
, which returns an IEnumerator.
public class Auditory : IEnumerable
{
public List<Student> Students { get; set; }
public IEnumerator GetEnumerator()
{
return Students.GetEnumerator();
}
}
Since List<T>
implements IEnumerable<T>
, returning its GetEnumerator()
effectively makes Auditory
class iterable.
Usage Example
List<Student> students = new List<Student>
{
new Student{Age = 18, Score = 77.4 },
new Student{Age = 56, Score = 55.34 },
new Student{Age = 34, Score = 35.3 }
};
Auditory auditory = new Auditory { Students = students };
// Now you can iterate over 'auditory' like a collection
foreach (var item in auditory)
{
Console.WriteLine(item);
}
Custom Delegates
A delegate in C# is essentially a reference type that holds a list of method references. Declaring a delegate specifies a signature (parameter list and return type) that any methods added to the delegate must match.
public delegate void MyDelegate(); // no parameters, void return
Basic Usage
- Declaration
public delegate void MyDelegate(int number);
This declares a new delegate type that points to methods accepting an
int
parameter and returningvoid
.
- Instantiation
MyDelegate d = new MyDelegate(Function1); d += Function2; d -= Function1;
d
can refer to multiple methods.
+=
adds a method,=
removes it.
- Invocation
d.Invoke(42); // calls all methods in the delegate with parameter 42
- You can also use
d(42)
as shorthand ford.Invoke(42)
.
- You can also use
Delegate Characteristics
- Immutable: Each time you add or remove a method (
+=
or=
), you effectively get a new delegate instance under the hood.
- Multiple Methods: A delegate can call multiple methods, but if it has a non-void return type, only the result of the last method is accessible.
- Event Handling: Delegates form the basis of C# events (e.g., in the publisher/subscriber pattern).
Example
public class Program
{
public delegate void LogHandler(string message);
static void Main(string[] args)
{
LogHandler logDel = LogToConsole;
logDel += LogToFile;
logDel("Application started");
}
static void LogToConsole(string message)
{
Console.WriteLine($"Console log: {message}");
}
static void LogToFile(string message)
{
// Write to a file (pseudocode)
// File.AppendAllText("log.txt", message + Environment.NewLine);
Console.WriteLine($"File log: {message}");
}
}
- Calling
logDel("Application started")
will invoke bothLogToConsole
andLogToFile
.
Reference
The content in this document is based on the original notes provided in Azerbaijani. For further details, you can refer to the original document using the following link:
Original Note - Azerbaijani Version