dotnet --version
Create generic result types, repositories, and extension methods that work across different type parameters.
1 /// <summary> 2 /// A generic discriminated union representing success or failure. 3 /// </summary> 4 public class Result<T> 5 { 6 public T? Value { get; } 7 public string? Error { get; } 8 public bool IsSuccess { get; } 9 public bool IsFailure => !IsSuccess; 10 11 private Result(T value) { Value = value; IsSuccess = true; } 12 private Result(string error) { Error = error; IsSuccess = false; } 13 14 public static Result<T> Ok(T value) => new(value); 15 public static Result<T> Fail(string error) => new(error); 16 17 // Implicit conversion from T 18 public static implicit operator Result<T>(T value) => Ok(value); 19 20 public TOut Match<TOut>(Func<T, TOut> onSuccess, Func<string, TOut> onFailure) 21 => IsSuccess ? onSuccess(Value!) : onFailure(Error!); 22 23 public Result<TOut> Map<TOut>(Func<T, TOut> mapper) 24 => IsSuccess ? Result<TOut>.Ok(mapper(Value!)) : Result<TOut>.Fail(Error!); 25 26 public override string ToString() 27 => IsSuccess ? $"Ok({Value})" : $"Fail({Error})"; 28 } 29 30 public class PagedList<T> 31 { 32 public IReadOnlyList<T> Items { get; } 33 public int Page { get; } 34 public int PageSize { get; } 35 public int TotalCount { get; } 36 public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize); 37 public bool HasPreviousPage => Page > 1; 38 public bool HasNextPage => Page < TotalPages; 39 40 public PagedList(IEnumerable<T> items, int page, int pageSize, int totalCount) 41 { 42 Items = items.ToList().AsReadOnly(); 43 Page = page; 44 PageSize = pageSize; 45 TotalCount = totalCount; 46 } 47 } 48 49 public static class QueryableExtensions 50 { 51 public static async Task<PagedList<T>> ToPagedListAsync<T>( 52 this IQueryable<T> query, 53 int page, 54 int pageSize, 55 CancellationToken ct = default) 56 { 57 int totalCount = await System.Linq.AsyncEnumerable.CountAsync(query, ct); 58 var items = await System.Linq.AsyncEnumerable 59 .ToListAsync(query.Skip((page - 1) * pageSize).Take(pageSize), ct); 60 return new PagedList<T>(items, page, pageSize, totalCount); 61 } 62 } 63
Sign in to share your feedback and join the discussion.