C#中如何让泛型扩展方法自动推断类型参数,无需显式指定?
解决泛型扩展方法的类型自动推断问题
你可以通过简化泛型参数的定义,让编译器自动推断所需类型,无需显式指定所有泛型参数。核心是利用this参数的具体类型推导TRequest和TResponse,避免多余的泛型参数干扰推断逻辑。
修正后的扩展方法
public static void AddValidationError<TRequest, TResponse>(this Endpoint<TRequest, TResponse> endpoint, string property, string message) where TRequest : notnull where Endpoint<TRequest, TResponse> : IValidationError { var container = endpoint.Resolve<IValidationErrorContainer>(); container.Errors.Add(new ValidationInfo(property, message)); }
为什么原来的写法无法自动推断?
你最初的代码定义了三个泛型参数TEndpoint、TRequest、TResponse,虽然TEndpoint的约束关联了后两个,但C#的类型推断机制无法同时从this参数推导出这三个相互关联的泛型参数——多余的TEndpoint参数打破了推断链,导致编译器无法自动提取TRequest和TResponse。
修正后的写法直接将this参数的类型设为Endpoint<TRequest, TResponse>,并附加IValidationError的约束,编译器可以从当前类(比如MyEndpoint : Endpoint<ConcreteReq, ConcreteRes>, IValidationError)的类型自动推断出TRequest和TResponse,调用时无需显式指定任何泛型参数:
this.AddValidationError(nameof(MyClass.Property1), "Message");
替代方案:接口默认方法(C# 8.0+)
如果允许修改IValidationError接口,可以将逻辑写成接口的默认方法,调用更简洁:
public interface IValidationError { // 声明Resolve方法(需确保实现类继承自Endpoint基类并拥有该方法) T Resolve<T>(); void AddValidationError(string property, string message) { var container = Resolve<IValidationErrorContainer>(); container.Errors.Add(new ValidationInfo(property, message)); } }
此时只要你的类实现了IValidationError和Endpoint<TRequest, TResponse>,就能直接调用this.AddValidationError(...),完全不需要泛型参数。
内容的提问来源于stack exchange,提问作者Matyas Szekely
相关产品推荐
相关产品推荐

