C# ジェネリックインターフェース
ジェネリックインターフェースは、型パラメータを持つインターフェースです。IEnumerable<T> や IComparable<T> など、.NET の基盤となる多くのインターフェースがジェネリックとして定義されています。
基本的な定義方法
インターフェース名の後に <T> を付けることで、ジェネリックインターフェースになります。
public interface IRepository<T>
{
T GetById(int id);
void Add(T entity);
void Delete(T entity);
IEnumerable<T> GetAll();
}ジェネリックインターフェースの実装
実装するクラスでは、具体的な型を指定するか、クラス自体もジェネリックにします。
// 具体的な型を指定して実装
public class UserRepository : IRepository<User>
{
private List<User> _users = new();
public User GetById(int id) => _users.FirstOrDefault(u => u.Id == id)!;
public void Add(User entity) => _users.Add(entity);
public void Delete(User entity) => _users.Remove(entity);
public IEnumerable<User> GetAll() => _users;
}
public class User
{
public int Id { get; set; }
public string Name { get; set; } = "";
}クラス自体をジェネリックにする方法もあります。
// ジェネリッククラスとして実装
public class GenericRepository<T> : IRepository<T>
{
private List<T> _items = new();
public T GetById(int id) => _items.ElementAtOrDefault(id)!;
public void Add(T entity) => _items.Add(entity);
public void Delete(T entity) => _items.Remove(entity);
public IEnumerable<T> GetAll() => _items;
}.NET 標準のジェネリックインターフェース
.NET には多くの標準ジェネリックインターフェースがあります。
IEnumerable<T>
コレクションの反復処理を可能にする。foreach で使用される。
IComparable<T>
同じ型のオブジェクト同士の比較を定義する。
IEquatable<T>
同じ型のオブジェクト同士の等価性を定義する。
ICollection<T>
コレクションの基本操作(追加、削除、カウント)を定義する。
IComparable<T> の実装例
オブジェクトの並び替えを可能にするには IComparable<T> を実装します。
public class Product : IComparable<Product>
{
public string Name { get; set; } = "";
public decimal Price { get; set; }
public int CompareTo(Product? other)
{
if (other == null) return 1;
return Price.CompareTo(other.Price);
}
}var products = new List<Product>
{
new() { Name = "Apple", Price = 150 },
new() { Name = "Banana", Price = 100 },
new() { Name = "Cherry", Price = 300 }
};
products.Sort(); // IComparable<Product> を使って並び替え
foreach (var p in products)
Console.WriteLine($"{p.Name}: {p.Price}円");
// Banana: 100円
// Apple: 150円
// Cherry: 300円制約としてのジェネリックインターフェース
ジェネリックインターフェースは制約として使うことで、型の機能を保証できます。
public static T FindMax<T>(IEnumerable<T> items) where T : IComparable<T>
{
T max = items.First();
foreach (var item in items.Skip(1))
{
if (item.CompareTo(max) > 0)
max = item;
}
return max;
}
var numbers = new[] { 3, 1, 4, 1, 5 };
Console.WriteLine(FindMax(numbers)); // 5ジェネリックインターフェースを活用することで、型安全かつ柔軟な抽象化が実現できます。