Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pattern Matching, Records & Reflection

Pattern Matching

C# 9+ Pattern Matching

// Type pattern
if (obj is Product product)
{
    Console.WriteLine(product.Name);
}

// Switch expression
var message = obj switch
{
    null => "Empty",
    int i when i > 0 => "Positive",
    int i => "Negative",
    string s => $"String: {s}",
    _ => "Unknown"
};

// Relational patterns (C# 9)
var category = score switch
{
    >= 90 => "A",
    >= 80 => "B",
    >= 70 => "C",
    _ => "F"
};

Records (C# 9+)

Value Equality

public record Product(string Name, decimal Price);

// So sánh bằng giá trị, không phải reference
var p1 = new Product("Apple", 1.99m);
var p2 = new Product("Apple", 1.99m);

Console.WriteLine(p1 == p2); // True!

With Expression

var p1 = new Product("Apple", 1.99m);
var p2 = p1 with { Price = 2.99m }; // Tạo bản sao với Price mới

// Non-destructive mutation

Positional Records

public record Product(string Name, decimal Price);

// Constructor và Deconstruct tự động
var product = new Product("Apple", 1.99m);
var (name, price) = product;

Attributes & Reflection

Attributes (Thuộc tính)

Attributes cung cấp metadata cho code elements (classes, methods, properties, etc.).

// Built-in attributes
[Serializable]
public class Product { }

[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

[Conditional("DEBUG")]
public void DebugLog(string message) { }

// Custom attribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorAttribute : Attribute
{
    public string Name { get; }
    public string Version { get; set; }
    
    public AuthorAttribute(string name)
    {
        Name = name;
    }
}

// Sử dụng custom attribute
[Author("John Doe", Version = "1.0")]
public class Calculator
{
    [Author("Jane Smith")]
    public int Add(int a, int b) => a + b;
}

Common Built-in Attributes

AttributeMục đíchVí dụ
[Serializable]Cho phép object serialization[Serializable] class Data
[Obsolete]Đánh dấu method/class deprecated[Obsolete("Use v2")]
[Conditional]Chỉ compile khi symbol defined[Conditional("DEBUG")]
[DllImport]Import native DLL function[DllImport("user32.dll")]
[Required]Data validation (ASP.NET Core)[Required] string Name
[Range]Value range validation[Range(1, 100)] int Age

Reflection

Reflection cho phép inspect và thao tác với types tại runtime.

using System.Reflection;

// Lấy Type information
Type type = typeof(Product);
Console.WriteLine($"Type: {type.Name}");
Console.WriteLine($"Namespace: {type.Namespace}");
Console.WriteLine($"Is Class: {type.IsClass}");

// Lấy properties
PropertyInfo[] properties = type.GetProperties();
foreach (var prop in properties)
{
    Console.WriteLine($"Property: {prop.Name} ({prop.PropertyType.Name})");
}

// Lấy methods
MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
{
    Console.WriteLine($"Method: {method.Name}");
}

// Kiểm tra attributes
var attributes = type.GetCustomAttributes(typeof(AuthorAttribute), false);
foreach (AuthorAttribute attr in attributes)
{
    Console.WriteLine($"Author: {attr.Name}, Version: {attr.Version}");
}

Dynamic Type Creation & Invocation

// Tạo instance dynamically
Type calculatorType = typeof(Calculator);
object calculator = Activator.CreateInstance(calculatorType);

// Gọi method dynamically
MethodInfo addMethod = calculatorType.GetMethod("Add");
object result = addMethod.Invoke(calculator, new object[] { 5, 3 });
Console.WriteLine($"Result: {result}"); // 8

// Get/Set property values
PropertyInfo nameProperty = calculatorType.GetProperty("Name");
nameProperty.SetValue(calculator, "MyCalculator");
string name = (string)nameProperty.GetValue(calculator);

Performance Considerations

// ❌ Chậm - Reflection mỗi lần
for (int i = 0; i < 1000; i++)
{
    MethodInfo method = obj.GetType().GetMethod("Process");
    method.Invoke(obj, null);
}

// ✅ Tốt hơn - Cache MethodInfo
MethodInfo cachedMethod = obj.GetType().GetMethod("Process");
for (int i = 0; i < 1000; i++)
{
    cachedMethod.Invoke(obj, null);
}

// ✅ Tốt nhất - Delegate (Expression Trees)
var method = obj.GetType().GetMethod("Process");
var delegate = (Action)Delegate.CreateDelegate(typeof(Action), obj, method);
for (int i = 0; i < 1000; i++)
{
    delegate();
}

Use Cases cho Reflection

  1. Dependency Injection Frameworks - Tìm và register services
  2. ORM Frameworks - Map database columns to properties
  3. Serialization/Deserialization - Inspect object structure
  4. Testing Frameworks - Tìm và chạy test methods
  5. Plugin Systems - Load và instantiate plugins dynamically

C# 12 Features

Primary Constructors (C# 12)

public class Point(int X, int Y)
{
    public int Sum() => X + Y;
}

var point = new Point(3, 4);
Console.WriteLine(point.Sum()); // 7

Collection Expressions

// Array
int[] numbers = [1, 2, 3, 4, 5];

// Span
Span<int> span = [1, 2, 3];

// List
List<string> names = ["Alice", "Bob"];

Default Lambda Parameters

Func<int, int, int> add = (int a, int b = 10) => a + b;
Console.WriteLine(add(5)); // 15

Alias Any Type

using IntList = List<int>;
using Point3D = (int x, int y, int z);