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

是否支持部分未绑定泛型?C#泛型类型定义疑问

问题解析与解决方案

为什么typeof(IPipelineBehaviour<,List<>>)无法执行?

C#不允许部分开放的泛型构造类型,泛型类型的使用只能是两种合法情况:

  • 完全未绑定:所有类型参数都未指定,比如typeof(IPipelineBehaviour<,>);
  • 完全封闭:所有类型参数都绑定了具体类型或已封闭的泛型类型,比如typeof(IPipelineBehaviour<MyRequest, List<int>>)。

你尝试的IPipelineBehaviour<,List<>>混合了未绑定的List<>和未指定的第一个参数,属于部分开放构造类型,C#编译器不支持这种写法,因此无法解析。

MediatR管道行为注册解决方案

你的核心需求是:注册一个仅处理TResult为OneOf<, Problem>类型请求的IPipelineBehaviour。以下是两种可行方案:

方案1:开放泛型+运行时类型检查(推荐)

实现一个开放泛型的行为,在运行时判断TResult是否符合OneOf<, Problem>的约束,不符合则直接跳过处理:

using MediatR;
using OneOf;

public class ValidationBehaviour<TRequest, TResult> : IPipelineBehaviour<TRequest, TResult>
    where TRequest : IRequest<TResult>
{
    public async Task<TResult> Handle(TRequest request, RequestHandlerDelegate<TResult> next, CancellationToken cancellationToken)
    {
        var resultType = typeof(TResult);
        
        // 检查TResult是否为OneOf<, Problem>类型
        bool isOneOfWithProblem = resultType.IsGenericType 
            && resultType.GetGenericTypeDefinition() == typeof(OneOf<,>)
            && typeof(Problem).IsAssignableFrom(resultType.GetGenericArguments()[1]);

        if (!isOneOfWithProblem)
        {
            // 不满足约束,直接执行后续管道
            return await next();
        }

        // 在这里编写你的验证逻辑
        // 示例:假设验证失败时返回OneOf的Problem分支
        // var validationErrors = ValidateRequest(request);
        // if (validationErrors.Any())
        // {
        //     return (TResult)(object)new Problem(...);
        // }

        return await next();
    }
}

// 服务注册时直接使用开放泛型
services.AddTransient(typeof(IPipelineBehaviour<,>), typeof(ValidationBehaviour<,>));

这种方式的优势:

  • 无侵入性,不需要修改现有请求定义;
  • 注册简单,利用MediatR对开放泛型的支持自动匹配所有请求;
  • 通过运行时检查过滤出需要处理的请求。

方案2:标记接口+编译时约束

如果需要编译时约束,可以定义一个标记接口,让所有符合条件的请求实现该接口,再通过泛型约束限制行为的适用范围:

// 定义泛型标记接口
public interface IRequestWithProblemResult<TResult> : IRequest<TResult> 
    where TResult : OneOf<, Problem> { }

// 实现行为时添加接口约束
public class ValidationBehaviour<TRequest, TResult> : IPipelineBehaviour<TRequest, TResult>
    where TRequest : IRequestWithProblemResult<TResult>
    where TResult : OneOf<, Problem>
{
    public async Task<TResult> Handle(TRequest request, RequestHandlerDelegate<TResult> next, CancellationToken cancellationToken)
    {
        // 编写验证逻辑
        return await next();
    }
}

// 注册开放泛型行为
services.AddTransient(typeof(IPipelineBehaviour<,>), typeof(ValidationBehaviour<,>));

这种方式的优势是编译时就能确保行为只处理符合约束的请求,但需要修改所有相关请求类实现IRequestWithProblemResult<TResult>,有一定侵入性。

为什么typeof(IPipelineBehaviour<,OneOf<,>>)注册失败?

和前面的问题原因一致:OneOf<,>是未绑定泛型,IPipelineBehaviour<,OneOf<,>>属于部分开放构造类型,C#不允许这种写法,因此无法被解析为合法的泛型类型,导致注册失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 06:43:27