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

如何声明函数参数以接受泛型抽象基类的所有派生类型?

解决方法

你的问题出在C#泛型的不变性上:默认情况下,泛型类InputModelBase<T>是不变的——即使SearchParameters继承自InputModelParametersBase,InputModelBase<SearchParameters>也不能隐式转换为InputModelBase<InputModelParametersBase>,所以直接传SearchInput会报错。

下面提供两种可行的解决方案:

方案一:使用泛型方法

给someFunction添加泛型参数,并加上类型约束,让它能接受任意符合条件的InputModelBase<T>派生类型:

public void someFunction<T>(InputModelBase<T> oInputParams) where T : InputModelParametersBase
{
    // 这里编写你的方法逻辑
}

调用时无需显式指定泛型类型,编译器会自动推断:

var oSearchInput = new SearchInput();
someFunction(oSearchInput); // 正常编译通过

这种方案无需修改现有的类结构,简单直接,适合大多数场景。

方案二:使用协变接口

如果需要统一方法参数的类型(比如在集合、依赖注入等场景),可以通过协变接口实现。C#中只有接口和委托支持协变/逆变,具体步骤如下:

  1. 定义一个带out关键字的协变接口(out表示T只能作为返回值,不能作为方法参数):
public interface IInputModelBase<out T> where T : InputModelParametersBase
{
    string Token { get; }
    bool Trace { get; }
    T Parameters { get; }
}
  1. 修改基类InputModelBase<T>,让它实现这个接口:
[DataContract]
public abstract class InputModelBase<T> : IInputModelBase<T> where T : InputModelParametersBase
{
    [DataMember]
    public string Token { get; set; }
    [DataMember]
    public bool Trace { get; set; }
    [DataMember(Name = "parameters")]
    public T Parameters { get; set; }
}
  1. 重新声明someFunction,参数类型改为协变接口:
public void someFunction(IInputModelBase<InputModelParametersBase> oInputParams)
{
    // 方法逻辑
}

此时调用someFunction(oSearchInput)就能正常编译,因为协变允许将IInputModelBase<SearchParameters>隐式转换为IInputModelBase<InputModelParametersBase>。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:13:22