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

C#中如何优雅实现支持多过滤器的泛型RegisterPipeLine方法

提问

我有一个Mediator类,其中包含用于注册管道的泛型方法RegisterPipeLine,该方法接收消息类型、管道过滤器类型和消息处理器类型。现有实现通过重载不同泛型参数的方法支持多过滤器,但我不想为每个过滤器数量都编写重载,是否有更优雅的实现方式?

现有代码示例

单过滤器实现

internal static void RegisterPipeLine<T1, T2, T3>()
      where T1 : IMessage
      where T2 : BaseFilter
      where T3 : IMessageHandler
  {
      var pipeLine = new PipeLine()
      {
          Filters = [typeof(T2)],
          MessageHandler = typeof(T3)
      };
      pipeLines[typeof(T1)] = pipeLine;
  }

调用方式:

Mediator.RegisterPipeLine<Message1, LogFilter, MessageHandler1>();

多过滤器重载实现

internal static void RegisterPipeLine<T1, T2, T3, T4>()
        where T1 : IMessage
        where T2 : BaseFilter
        where T3 : BaseFilter
        where T4 : IMessageHandler
     {
         var pipeLine = new PipeLine()
         {
             Filters = [typeof(T2), typeof(T3)],
             MessageHandler = typeof(T4)
         };
         pipeLines[typeof(T1)] = pipeLine;
     }

调用方式:

Mediator.RegisterPipeLine<Message2, LogFilter, ValidFilter, MessageHandler2>();

回答

当然有更优雅的实现方式,以下是几种实用方案:

方案1:构建器模式(推荐,编译时安全)

这种方式支持任意数量的过滤器,链式调用直观,且能在编译时保证类型安全,完全不需要写重载:

// 定义管道构建器类
public class PipeLineBuilder<TMessage> where TMessage : IMessage
{
    private readonly List<Type> _filters = new();
    private Type _handlerType;

    // 添加过滤器的方法,支持链式调用
    public PipeLineBuilder<TMessage> AddFilter<TFilter>() 
        where TFilter : BaseFilter
    {
        _filters.Add(typeof(TFilter));
        return this;
    }

    // 注册最终的消息处理器,完成管道注册
    public void RegisterHandler<THandler>() 
        where THandler : IMessageHandler
    {
        _handlerType = typeof(THandler);
        var pipeline = new PipeLine
        {
            Filters = _filters,
            MessageHandler = _handlerType
        };
        Mediator.pipeLines[typeof(TMessage)] = pipeline;
    }
}

// 在Mediator类中添加创建构建器的入口方法
internal static PipeLineBuilder<TMessage> CreatePipeline<TMessage>() 
    where TMessage : IMessage
{
    return new PipeLineBuilder<TMessage>();
}

调用示例:

// 单过滤器场景
Mediator.CreatePipeline<Message1>()
        .AddFilter<LogFilter>()
        .RegisterHandler<MessageHandler1>();

// 多过滤器场景
Mediator.CreatePipeline<Message2>()
        .AddFilter<LogFilter>()
        .AddFilter<ValidFilter>()
        .RegisterHandler<MessageHandler2>();

方案2:可变泛型参数结合约束

通过调整泛型参数的顺序,把消息类型和处理器类型放在固定位置,中间用可变泛型参数接收过滤器类型:

internal static void RegisterPipeLine<TMessage, THandler, params TFilters[]>()
    where TMessage : IMessage
    where THandler : IMessageHandler
    where TFilters : BaseFilter
{
    // 提取所有过滤器的类型
    var filterTypes = typeof(TFilters).GetGenericArguments()
                                     .ToList();
    var pipeline = new PipeLine
    {
        Filters = filterTypes,
        MessageHandler = typeof(THandler)
    };
    pipeLines[typeof(TMessage)] = pipeline;
}

调用示例:

// 单过滤器
Mediator.RegisterPipeLine<Message1, MessageHandler1, LogFilter>();
// 多过滤器
Mediator.RegisterPipeLine<Message2, MessageHandler2, LogFilter, ValidFilter>();

注意:这种方式依赖泛型参数的顺序,可读性略低于构建器模式,但代码量更少。

方案3:参数化传入过滤器类型

如果可以接受运行时类型校验,直接传入过滤器的Type对象是最简单的方式:

internal static void RegisterPipeLine<TMessage, THandler>(params Type[] filterTypes)
    where TMessage : IMessage
    where THandler : IMessageHandler
{
    // 可选:运行时校验所有过滤器都继承自BaseFilter
    foreach (var type in filterTypes)
    {
        if (!typeof(BaseFilter).IsAssignableFrom(type))
        {
            throw new ArgumentException($"类型 {type.Name} 不是有效的BaseFilter实现");
        }
    }

    var pipeline = new PipeLine
    {
        Filters = filterTypes.ToList(),
        MessageHandler = typeof(THandler)
    };
    pipeLines[typeof(TMessage)] = pipeline;
}

调用示例:

// 单过滤器
Mediator.RegisterPipeLine<Message1, MessageHandler1>(typeof(LogFilter));
// 多过滤器
Mediator.RegisterPipeLine<Message2, MessageHandler2>(typeof(LogFilter), typeof(ValidFilter));

这种方式最简洁,但失去了编译时类型安全,需要额外的运行时校验逻辑。


内容的提问来源于stack exchange,提问作者David Kethel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:34:53