[C#] Generics and Extension Methods
Categories: CS
📋 This is my note-taking from what I learned in the course!
Generics and Extension Methods
Objectives
- Create generic methods.
- Overload generic methods with non-generic methods or other generic methods.
- Understand the kinds of constraints that can be applied to a type parameter.
- Apply multiple constraints to a type parameter.
Generics Overview
Generics introduce the concept of type parameters, allowing the creation of classes and methods that are independent of specific types. The specification of types can be deferred until the class or method is instantiated by client code. Generics provide type safety, performance, and productivity without compromising any of these aspects.
Generic Parameterization
Generics can be used with:
- Types (Struct, Interface, Class, Delegate)
- Methods
Struct Example
Structs are value types stored on the stack and do not support inheritance. Each simple type in C# has a corresponding struct in the System
namespace, such as Boolean
, Byte
, Char
, Decimal
, Double
, Int32
, etc.
Simple-Type Structs
Simple types are aliases for their corresponding structs, and methods related to a simple type are located in the corresponding struct.
Boxing and Unboxing
Boxing converts a value type to an object type, allowing simple types to be manipulated as objects. Unboxing extracts the value type from the object.
Boxing Example
int i = 5; // create an int value
object object1 = (object)i; // explicitly box the int value
object object2 = i; // implicitly box the int value
Unboxing Example
int int1 = (int)object1; // explicitly unbox the int value
Generic Classes
Generic classes allow defining type parameters, enabling different types to be used during compile time. This allows for type safety and code reuse.
Example: Generic Class
public class GenericClass<T> {
private T value;
public GenericClass(T value) {
this.value = value;
}
public T GetValue() {
return value;
}
}
Generic Methods
Generic methods specify a set of related methods with a single method declaration. They use type parameters as placeholders for actual types.
Example: Generic Method
public static T GenericMethod<T>(T input) {
return input;
}
IComparable Interface
The IComparable<T>
interface allows comparison of two objects of the same type using the CompareTo()
method.
CompareTo Method
public int CompareTo(T other) {
// Implementation
}
Type Constraints
Type constraints restrict the types that can be used with a generic method or class.
Types of Constraints
where T : struct
- T must be a value type.where T : class
- T must be a reference type.where T : IFoo
- T must implement interfaceIFoo
.where T : new()
- T must have a default constructor.where T1 : T2
- T1 must derive from T2.
Example: Multiple Constraints
public class Example<T> where T : class, IFoo, new() {
// Implementation
}
Default Values for Generic Types
Default values are used for generic types that can be instantiated as value types or reference types.
T defaultValue = default(T);
Extension Methods
Extension methods extend the functionality of existing classes without modifying their source code. They are static methods defined in static classes and use the this
modifier on the first parameter to specify the type being extended.
Example: Extension Method
public static class StringExtensions {
public static string ToUpperFirstLetter(this string str) {
if (string.IsNullOrEmpty(str)) return str;
return char.ToUpper(str[0]) + str.Substring(1);
}
}
// Usage
string example = "hello";
string result = example.ToUpperFirstLetter(); // "Hello"
Reference: Extension Methods
Leave a comment