C#编译时未知泛型类型的实现方案咨询
解决方案
你需要实现泛型类DE<TS>,限制TS为IS或DS,同时访问Foo<TD>的属性,C#可通过以下几种方式实现:
方案1:非泛型基接口 + 类型匹配
先抽离与泛型参数无关的属性到非泛型接口,再通过类型匹配访问泛型属性:
// 新增非泛型基接口 public interface IFoo { List<double> Yey { get; set; } } // 泛型接口继承非泛型接口 public interface Foo<TD> : IFoo { List<TD> Bravo { get; set; } } // 原实现类补全属性 public class IS : Foo<int> { public List<int> Bravo { get; set; } public List<double> Yey { get; set; } } public class DS : Foo<double> { public List<double> Bravo { get; set; } public List<double> Yey { get; set; } } // 目标泛型类 public class DE<TS> where TS : IFoo, class { // 静态构造函数强制TS只能是IS或DS static DE() { var tsType = typeof(TS); if (tsType != typeof(IS) && tsType != typeof(DS)) { throw new InvalidOperationException("TS必须为IS或DS类型"); } } public void DoSomething(TS instance) { // 直接访问非泛型属性Yey var yeyData = instance.Yey; // 通过类型匹配访问泛型属性Bravo if (instance is IS isInstance) { List<int> bravoInt = isInstance.Bravo; // 处理int类型逻辑 } else if (instance is DS dsInstance) { List<double> bravoDouble = dsInstance.Bravo; // 处理double类型逻辑 } } }
方案2:双泛型参数 + 编译期约束
通过新增TD泛型参数,明确绑定TS与Foo<TD>的关系,编译期即可保证类型安全:
// 原接口与实现类不变 public interface Foo<TD> { List<TD> Bravo { get; set; } List<double> Yey { get; set; } } public class IS : Foo<int> { public List<int> Bravo { get; set; } public List<double> Yey { get; set; } } public class DS : Foo<double> { public List<double> Bravo { get; set; } public List<double> Yey { get; set; } } // 双泛型参数的DE类 public class DE<TS, TD> where TS : Foo<TD>, class { public void DoSomething(TS instance) { // 直接访问强类型属性 List<TD> bravoData = instance.Bravo; List<double> yeyData = instance.Yey; } } // 使用示例 var deForIS = new DE<IS, int>(); var deForDS = new DE<DS, double>();
可添加静态工厂方法简化调用,避免手动指定TD:
public static class DEFactory { public static DE<IS, int> CreateForIS() => new DE<IS, int>(); public static DE<DS, double> CreateForDS() => new DE<DS, double>(); } // 调用方式 var deIS = DEFactory.CreateForIS();
方案3:直接类型检查 + 模式匹配
无需修改原有接口,通过模式匹配访问属性,同时用静态构造函数限制TS范围:
// 原接口与实现类不变 public interface Foo<TD> { List<TD> Bravo { get; set; } List<double> Yey { get; set; } } public class IS : Foo<int> { public List<int> Bravo { get; set; } public List<double> Yey { get; set; } } public class DS : Foo<double> { public List<double> Bravo { get; set; } public List<double> Yey { get; set; } } public class DE<TS> where TS : class { static DE() { var tsType = typeof(TS); if (tsType != typeof(IS) && tsType != typeof(DS)) { throw new InvalidOperationException("TS必须为IS或DS类型"); } } public void DoSomething(TS instance) { if (instance is Foo<int> fooInt) { var bravo = fooInt.Bravo; var yey = fooInt.Yey; // 处理int类型逻辑 } else if (instance is Foo<double> fooDouble) { var bravo = fooDouble.Bravo; var yey = fooDouble.Yey; // 处理double类型逻辑 } } }
内容的提问来源于stack exchange,提问作者José Joaquim
相关产品推荐
相关产品推荐

