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

如何在C#派生类中永久向下转换泛型设置类?

问题:派生服务类无法直接访问设置类的专属属性,需避免强制转换

我拥有多个具备相似行为的服务,这些服务均包含共享设置,同时每个服务还有自身的扩展专属设置,但在派生服务类中无法直接访问这些扩展设置,只能通过强制转换获取。以下是实现示例及问题:

public abstract class BaseSettings<T> where T : ISettings
{
  public string BaseSetting { get; } = "Hello from BaseSettings";
  // other settings, etc.

  public BaseSettings<T>() {}
}

public abstract class BaseService<T> where T : ISettings
{
  public BaseSettings<T> Settings { get; }

  public BaseService(BaseSettings<T> settings)
  {
    Settings = settings;
    Console.WriteLine(Settings.BaseSetting);
  }
}

public class ServiceASettings : BaseSettings<ServiceASettings>, ISettings
{
  public string SettingA { get; } = "Hello from SettingsA";

  public ServiceASettings() {}
}

public class ServiceA : BaseService<ServiceASettings>, IService
{
  public ServiceA(ServiceASettings settings) : base(settings) 
  {
   Console.WriteLine(Settings.SettingA); // 无法访问该属性
   Console.WriteLine((Settings as ServiceASettings).SettingA); // 强制转换后可正常输出
  }
}

// ServiceB, ServiceBSettings; ServiceC, ServiceCSettings; etc...

public class Program
{
  public static void Main(string[] args)
  {
    ServiceASettings settings = new ServiceASettings();
    ServiceA service = new ServiceA(settings);
    // 编译失败,提示ServiceA中没有Settings.SettingA的定义
  }
}

我希望能永久将Settings指定为对应的派生类类型,避免每次都进行强制转换,请问该如何实现?


解决方案

修改后的可运行代码如下:

public abstract class BaseSettings
{
  public string BaseSetting { get; } = "Hello from BaseSettings";
  // other settings, etc.

  public BaseSettings() {}
}

public abstract class BaseService<T> where T : ISettings
{
  public T Settings { get; }

  public BaseService(T settings)
  {
    Settings = settings;
    Console.WriteLine(Settings.BaseSetting);
  }
}

public class ServiceASettings : BaseSettings, ISettings
{
  public string SettingA { get; } = "Hello from SettingsA";

  public ServiceASettings() {}
}

public class ServiceA : BaseService<ServiceASettings>, IService
{
  public ServiceA(ServiceASettings settings) : base(settings) 
  {
   Console.WriteLine(Settings.SettingA); // 现在可直接访问专属属性
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    ServiceASettings settings = new ServiceASettings();
    ServiceA service = new ServiceA(settings);
  }
}

修改说明

  1. 移除BaseSettings的泛型定义,将其改为普通抽象类,作为所有设置类的基类,保留共享设置属性
  2. 将BaseService<T>中的Settings属性类型从BaseSettings<T>改为泛型参数T,同时构造函数参数也改为T
  3. 派生设置类直接继承BaseSettings并实现ISettings接口

这样修改后,派生服务类中的Settings属性会直接对应到具体的派生设置类类型,无需强制转换即可访问专属属性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:15:35