You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中为何枚举转int的强制转换在Pending场景下是冗余的?

问题

我定义了OrderStatus枚举、Order模型,在OrderController的PaginateAsync方法中通过switch语句过滤订单数据。发现在pending分支中,(int)o.Status == 0的强制转换是冗余的,但accepted、rejected、delivered分支却需要该转换,想询问这一现象的原因。

相关代码

OrderStatus枚举

public enum OrderStatus
{
    [Display(Name = "Gözləmədə")]
    Pending,
    [Display(Name = "Qəbul olundu")]
    Accepted,
    [Display(Name = "Ləğv edildi")]
    Rejected,
    [Display(Name = "Çatdırıldı")]
    Delivered
}

Order模型

public class Order : BaseEntity
{
    public string AppUserId { get; set; }
    public AppUser AppUser { get; set; }
    [StringLength(255), Required]
    public string StoreName { get; set; }
    [StringLength(255), Required]
    public string StoreAddress { get; set; }
    public double TotalPrice { get; set; }
    public double RemainingBalance { get; set; }
    public ShippingMethod ShippingMethod { get; set; }
    public OrderStatus Status { get; set; }
    public PaymentStatus PaymentStatus { get; set; }
    public IEnumerable<OrderItem> OrderItems { get; set; }
    public IEnumerable<Payment> Payments { get; set; }
}

PaginateAsync方法

private async Task<IEnumerable<Order>> PaginateAsync(string status, int page)
{
    ViewBag.Status = status;
    ViewBag.CurrentPage = page;
    int perPage = 10;
    ViewBag.PerPage = perPage;

    IEnumerable<Order> orders = await _context.Orders
        .Include(o => o.AppUser)
        .Include(o => o.OrderItems)
        .Where(o => !o.IsDeleted)
        .OrderByDescending(o => o.Id)
        .ToListAsync();

    orders = status switch
    {
        "pending" => orders.Where(o => (int)o.Status == 0),
        "accepted" => orders.Where(o => (int)o.Status == 1),
        "rejected" => orders.Where(o => (int)o.Status == 2),
        "delivered" => orders.Where(o => (int)o.Status == 3),
        _ => orders
    };

    ViewBag.PageCount = Math.Ceiling((double)orders.Count() / perPage);

    return orders.Skip((page - 1) * perPage).Take(perPage);
}
解答

强制转换冗余的原因

C#中枚举的默认基础类型是int,且未显式指定数值的第一个枚举成员默认值为0(也就是OrderStatus.Pending的数值就是0)。当你写o.Status == 0时,编译器会自动将int类型的0隐式转换为OrderStatus.Pending(因为0是该枚举的有效值),所以(int)o.Status == 0和o.Status == 0(甚至更规范的o.Status == OrderStatus.Pending)的效果完全一致,因此这里的强制转换完全是多余的。

关于其他分支的误解

你觉得accepted等分支需要强制转换其实是个误区——根本不需要!C#允许将int类型的有效值隐式转换为对应的枚举成员,所以o.Status == 1本身是可以编译通过的,等价于o.Status == OrderStatus.Accepted。但更推荐的写法是直接使用枚举成员而非硬编码数值,这样代码可读性更高,还能避免后续枚举成员顺序调整、新增成员时导致的数值匹配错误。

优化后的代码示例

把switch分支的过滤条件改成直接比较枚举成员,代码会更健壮:

orders = status switch
{
    "pending" => orders.Where(o => o.Status == OrderStatus.Pending),
    "accepted" => orders.Where(o => o.Status == OrderStatus.Accepted),
    "rejected" => orders.Where(o => o.Status == OrderStatus.Rejected),
    "delivered" => orders.Where(o => o.Status == OrderStatus.Delivered),
    _ => orders
};

另外还有个效率优化点:当前代码是先把所有订单加载到内存再过滤,建议把过滤条件整合到EF Core查询中,让数据库直接返回符合条件的数据,减少内存占用:

IQueryable<Order> ordersQuery = _context.Orders
    .Include(o => o.AppUser)
    .Include(o => o.OrderItems)
    .Where(o => !o.IsDeleted);

ordersQuery = status switch
{
    "pending" => ordersQuery.Where(o => o.Status == OrderStatus.Pending),
    "accepted" => ordersQuery.Where(o => o.Status == OrderStatus.Accepted),
    "rejected" => ordersQuery.Where(o => o.Status == OrderStatus.Rejected),
    "delivered" => ordersQuery.Where(o => o.Status == OrderStatus.Delivered),
    _ => ordersQuery
};

int totalCount = await ordersQuery.CountAsync();
ViewBag.PageCount = Math.Ceiling((double)totalCount / perPage);

IEnumerable<Order> orders = await ordersQuery
    .OrderByDescending(o => o.Id)
    .Skip((page - 1) * perPage)
    .Take(perPage)
    .ToListAsync();

内容的提问来源于stack exchange,提问作者Kamil Guliyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:37:12